Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integer overflow in _pickle.c #68709

Closed
benjaminp opened this issue Jun 27, 2015 · 2 comments
Closed

Integer overflow in _pickle.c #68709

benjaminp opened this issue Jun 27, 2015 · 2 comments
Labels
extension-modules C modules in the Modules dir type-crash A hard crash of the interpreter, possibly with a core dump

Comments

@benjaminp
Copy link
Contributor

BPO 24521
Nosy @benjaminp

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2015-06-27.19:27:00.073>
created_at = <Date 2015-06-27.19:24:48.083>
labels = ['extension-modules', 'type-crash']
title = 'Integer overflow in _pickle.c'
updated_at = <Date 2015-06-28.12:41:56.291>
user = 'https://github.com/benjaminp'

bugs.python.org fields:

activity = <Date 2015-06-28.12:41:56.291>
actor = 'Arfrever'
assignee = 'none'
closed = True
closed_date = <Date 2015-06-27.19:27:00.073>
closer = 'benjamin.peterson'
components = ['Extension Modules']
creation = <Date 2015-06-27.19:24:48.083>
creator = 'benjamin.peterson'
dependencies = []
files = []
hgrepos = []
issue_num = 24521
keywords = []
message_count = 2.0
messages = ['245888', '245889']
nosy_count = 2.0
nosy_names = ['benjamin.peterson', 'Arfrever']
pr_nums = []
priority = 'normal'
resolution = 'fixed'
stage = None
status = 'closed'
superseder = None
type = 'crash'
url = 'https://bugs.python.org/issue24521'
versions = ['Python 3.3', 'Python 3.4', 'Python 3.5', 'Python 3.6']

@benjaminp
Copy link
Contributor Author

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;
    <<SNIP>>
    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);
    }
    <<SNIP>>
}

static int
_Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size)
{
    <<SNIP>>
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 = 0x20000000
  2. and 3. together multiply idx by 8 on a 32 bit arch, 0x20000000 * 8 wraps to 0.
  3. 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: I INT 1
3: r LONG_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 c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0000d3c4 ebx=1d84d1d0 ecx=778c28ac edx=01e700f0 esi=001f8a48 edi=40000000
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 c7048200000000 mov dword ptr [edx+eax*4],0 ds:002b:01ea5000=????????
0:000> kb
ChildEBP RetAddr Args to Child
0057f658 1d5ce627 00301ff4 0000000 0057f684 python34!_Unpickler_ResizeMemoList+0x33 [c:\users\martin\34\python\modules\_pickle.c @ 1275]
0057f668 1d5d3503 20000000 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 0000000 0057f6dc python34!load+0x2c7 [c:\users\martin\34\python\modules\_pickle.c @ 6134]
0057f6b0 1d5d5461 00301fe0 00000001 1d6ff9d0 python34!_pickle_loads_impl+0x54 [c:\users\martin\34\python\modules\_pickle.c @ 7060]
0057f6dc 1d674f15 00597780 002cf6b0 0000000 python34!_pickle_loads+0x61 [c:\users\martin\34\python\modules\clinic\_pickle.c.h @ 540]
0057f6fc 1d6c591f 0059b440 002cf6b0 0000000 python34!PyCFunction_Call+0x65 [c:\users\martin\34\python\objects\methodobject.c @ 99]
0057f72c 1d6c79d9 0057f760 0000000 002d1d40 python34!call_function+0x28f [c:\users\martin\34\python\python\ceval.c @ 4237]
0057f7a0 1d6c89fd 002ff7b0 0000000 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 01e5e09 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 0000000 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 00000001 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]
0057f990 778b92e2 7efde000 2345c114 0000000 kernel32!BaseThreadInitThunk+0xe
0057f9d0 778b92b5 1cd712ec 7efde000 0000000 ntdll!__RtlUserThreadStart+0x70
0057f9e8 0000000 1cd712ec 7efde000 0000000 ntdll!_RtlUserThreadStart+0x1b

@benjaminp benjaminp added extension-modules C modules in the Modules dir type-crash A hard crash of the interpreter, possibly with a core dump labels Jun 27, 2015
@benjaminp
Copy link
Contributor Author

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extension-modules C modules in the Modules dir type-crash A hard crash of the interpreter, possibly with a core dump
Projects
None yet
Development

No branches or pull requests

1 participant