Issue27291
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2016-06-11 03:40 by Park Alex, last changed 2022-04-11 14:58 by admin. This issue is now closed.
Files | ||||
---|---|---|---|---|
File name | Uploaded | Description | Edit | |
poc.zip | Park Alex, 2016-06-11 03:40 |
Messages (7) | |||
---|---|---|---|
msg268173 - (view) | Author: Park Alex (Park Alex) | Date: 2016-06-11 03:40 | |
Hello, I would like to report two heap corruption issue. Test environment: python ersion: python 2.7.11+ hg id: d858eadf2602 (2.7) compile: clang with ASAN OS: ubuntu x86_64 One is heap-buffer-overflow, the other is heap-user-after-free. All of samples are attached in this bug report. Thanks, -- Alex In detail, 1) heap-buffer-overflow bug could be triggerd at cpython/Python/ceval.c:1229 ASAN report is following: ================================================================= ==26786==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7ffff7ec56e8 at pc 0x5ec87f bp 0x7fffffffd2d0 sp 0x7fffffffd2c8 READ of size 8 at 0x7ffff7ec56e8 thread T0 #0 0x5ec87e in PyEval_EvalFrameEx /project/cpython/Python/ceval.c:1229 #1 0x5d3c6c in PyEval_EvalCodeEx /project/cpython/Python/ceval.c:3582 #2 0x5d2b11 in PyEval_EvalCode /project/cpython/Python/ceval.c:669 #3 0x6612d9 in run_pyc_file /project/cpython/Python/pythonrun.c:1406 #4 0x6612d9 in PyRun_SimpleFileExFlags /project/cpython/Python/pythonrun.c:946 #5 0x48e3dc in Py_Main /project/cpython/Modules/main.c:640 #6 0x7ffff6ce282f in __libc_start_main /build/glibc-GKVZIf/glibc-2.23/csu/../csu/libc-start.c:291 #7 0x48c518 in _start (/project/cpython/python.asan+0x48c518) 0x7ffff7ec56e8 is located 280 bytes to the left of 196608-byte region [0x7ffff7ec5800,0x7ffff7ef5800) allocated by thread T0 here: #0 0x476429 in __interceptor_malloc /project/clang-3.4/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74 #1 0x50e969 in dictresize /project/cpython/Objects/dictobject.c:643 #2 0x537844 in PyString_InternInPlace /project/cpython/Objects/stringobject.c:4757 SUMMARY: AddressSanitizer: heap-buffer-overflow /project/cpython/Python/ceval.c:1229 PyEval_EvalFrameEx Shadow bytes around the buggy address: 0x10007efd0a80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x10007efd0a90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x10007efd0aa0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x10007efd0ab0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x10007efd0ac0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x10007efd0ad0: fa fa fa fa fa fa fa fa fa fa fa fa fa[fa]fa fa 0x10007efd0ae0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x10007efd0af0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x10007efd0b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007efd0b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007efd0b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 ASan internal: fe ==26786==ABORTING 2) heap-user-after-free bug could be triggerd at cpython/Objects/dictobject.c:732 ASAN report is following: ================================================================= ==26918==ERROR: AddressSanitizer: heap-use-after-free on address 0x60f00000ef98 at pc 0x50f5ac bp 0x7fffffffa1d0 sp 0x7fffffffa1c8 READ of size 8 at 0x60f00000ef98 thread T0 #0 0x50f5ab in PyDict_GetItem /project/cpython/Objects/dictobject.c:732 #1 0x537792 in PyString_InternInPlace /project/cpython/Objects/stringobject.c:4750 #2 0x64fad5 in r_object /project/cpython/Python/marshal.c:822 #3 0x650d00 in r_object /project/cpython/Python/marshal.c:1037 #4 0x64edf6 in r_object /project/cpython/Python/marshal.c:886 #5 0x650c1b in r_object /project/cpython/Python/marshal.c:1019 #6 0x64e1b1 in PyMarshal_ReadObjectFromString /project/cpython/Python/marshal.c:1183 #7 0x64e1b1 in PyMarshal_ReadLastObjectFromFile /project/cpython/Python/marshal.c:1144 #8 0x6429c1 in read_compiled_module /project/cpython/Python/import.c:823 #9 0x6429c1 in load_source_module /project/cpython/Python/import.c:1094 #10 0x644cda in import_submodule /project/cpython/Python/import.c:2722 #11 0x643e81 in load_next /project/cpython/Python/import.c:2537 #12 0x63e061 in import_module_level /project/cpython/Python/import.c:2254 #13 0x63e061 in PyImport_ImportModuleLevel /project/cpython/Python/import.c:2310 #14 0x5c4e1a in builtin___import__ /project/cpython/Python/bltinmodule.c:49 #15 0x5e2535 in do_call /project/cpython/Python/ceval.c:4564 #16 0x5e2535 in call_function /project/cpython/Python/ceval.c:4372 #17 0x5e2535 in PyEval_EvalFrameEx /project/cpython/Python/ceval.c:2987 #18 0x5d3c6c in PyEval_EvalCodeEx /project/cpython/Python/ceval.c:3582 #19 0x7237f3 in function_call /project/cpython/Objects/funcobject.c:523 #20 0x4aca9a in PyObject_Call /project/cpython/Objects/abstract.c:2546 #21 0x5f1313 in PyEval_CallObjectWithKeywords /project/cpython/Python/ceval.c:4219 #22 0x62118c in _PyCodec_Lookup /project/cpython/Python/codecs.c:147 #23 0x6227d5 in _PyCodec_LookupTextEncoding /project/cpython/Python/codecs.c:459 #24 0x622b6a in codec_getitem_checked /project/cpython/Python/codecs.c:511 #25 0x622b6a in _PyCodec_TextEncoder /project/cpython/Python/codecs.c:523 #26 0x622b6a in _PyCodec_EncodeText /project/cpython/Python/codecs.c:537 #27 0x54dbc8 in PyString_AsEncodedObject /project/cpython/Objects/stringobject.c:532 #28 0x54dbc8 in string_encode /project/cpython/Objects/stringobject.c:3016 #29 0x5e232f in call_function /project/cpython/Python/ceval.c:4350 #30 0x5e232f in PyEval_EvalFrameEx /project/cpython/Python/ceval.c:2987 #31 0x5d3c6c in PyEval_EvalCodeEx /project/cpython/Python/ceval.c:3582 #32 0x5f2c7d in fast_function /project/cpython/Python/ceval.c:4445 #33 0x5dd2ba in call_function /project/cpython/Python/ceval.c:4370 #34 0x5dd2ba in PyEval_EvalFrameEx /project/cpython/Python/ceval.c:2987 #35 0x5d3c6c in PyEval_EvalCodeEx /project/cpython/Python/ceval.c:3582 #36 0x5d2b11 in PyEval_EvalCode /project/cpython/Python/ceval.c:669 #37 0x6612d9 in run_pyc_file /project/cpython/Python/pythonrun.c:1406 #38 0x6612d9 in PyRun_SimpleFileExFlags /project/cpython/Python/pythonrun.c:946 #39 0x48e3dc in Py_Main /project/cpython/Modules/main.c:640 #40 0x7ffff6ce282f in __libc_start_main /build/glibc-GKVZIf/glibc-2.23/csu/../csu/libc-start.c:291 #41 0x48c518 in _start (/project/cpython/python.asan+0x48c518) 0x60f00000ef98 is located 72 bytes inside of 168-byte region [0x60f00000ef50,0x60f00000eff8) freed by thread T0 here: #0 0x4762a9 in free /project/clang-3.4/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64 #1 0x64fad5 in r_object /project/cpython/Python/marshal.c:822 #2 0x64edf6 in r_object /project/cpython/Python/marshal.c:886 #3 0x650c7a in r_object /project/cpython/Python/marshal.c:1022 #4 0x64edf6 in r_object /project/cpython/Python/marshal.c:886 #5 0x650c1b in r_object /project/cpython/Python/marshal.c:1019 #6 0x64e1b1 in PyMarshal_ReadObjectFromString /project/cpython/Python/marshal.c:1183 #7 0x64e1b1 in PyMarshal_ReadLastObjectFromFile /project/cpython/Python/marshal.c:1144 #8 0x6429c1 in read_compiled_module /project/cpython/Python/import.c:823 #9 0x6429c1 in load_source_module /project/cpython/Python/import.c:1094 #10 0x644cda in import_submodule /project/cpython/Python/import.c:2722 #11 0x643e81 in load_next /project/cpython/Python/import.c:2537 previously allocated by thread T0 here: #0 0x476429 in __interceptor_malloc /project/clang-3.4/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74 #1 0x65de92 in new_threadstate /project/cpython/Python/pystate.c:159 SUMMARY: AddressSanitizer: heap-use-after-free /project/cpython/Objects/dictobject.c:732 PyDict_GetItem Shadow bytes around the buggy address: 0x0c1e7fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c1e7fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c1e7fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c1e7fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c1e7fff9de0: fa fa fa fa fa fa fa fa fa fa fd fd fd fd fd fd =>0x0c1e7fff9df0: fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd fa 0x0c1e7fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c1e7fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c1e7fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c1e7fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c1e7fff9e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 ASan internal: fe ==26918==ABORTING QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB QUFBQUFBQUFBQUFBQUE= |
|||
msg268270 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2016-06-11 20:45 | |
poc.zip contains only precompiled files. Could you please provide source files? |
|||
msg268276 - (view) | Author: Park Alex (Park Alex) | Date: 2016-06-11 21:21 | |
all of .pyc files had been altered by fuzzer. original py code is following: $ cat helloworld.py def hello(s=0x4142434445464748): print s if type(s) == str: print s.encode('hex') print repr(s) else: s = str(s) print len(s) << 8, len(s) ^ 8, len(s) | 8, len(s) & 8, len(s) == 8, len(s) <= 8, len(s) >= 8 x = __import__("sys") # for k, v in x.__dict__.items(): # if hasattr(v, '__subclasses__') == True: # cmd = "Subclasses:", (v.__class__.__base__.__subclasses__()[11].__init__.__str__()) return 0x5152535455565758 == max(s, abs(len(s)) % 0x1234) H = 'A'*128 hello(H.encode('base64')) hello() plus, python compiled with ASAN generated .pyc code. After that, fuzzer found a few crashes. Here are some diff information between original pyc and fuzzed pyc. file: poc_heap-buffer-overflow.pyc cmp -bl helloworld.pyc poc_heap-buffer-overflow.pyc | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$4)}' 00000010 00 03 00000012 03 00 00000026 01 00 00000027 00 F7 0000006A 06 EE 0000006B 00 FF 0000006C 00 FF 0000006D 00 FF 00000129 01 FE 0000012A 00 FF 0000012B 64 00 0000012C 04 00 000001F0 6C DB 000001FD 6C 49 file: poc_heap-use-after-free.pyc cmp -bl helloworld.pyc poc_heap-use-after-free.pyc | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$4)}' 0000006A 06 D0 0000006B 00 FF 0000006C 00 FF 0000006D 00 FF 00000129 01 EB 0000012A 00 FF 0000012B 64 00 0000012C 04 00 000001F0 6C DB 000001FD 6C 49 0000026F 6C 7D Thanks, -- Alex |
|||
msg268280 - (view) | Author: STINNER Victor (vstinner) * | Date: 2016-06-11 21:31 | |
Hi, corrupted .pyc files are known to be abel to crash Python. What is the point of your bug report? If you are able to execute untrusted .pyc, you can already execute arbitrary code, no? IMHO we should document the limitation of the security of CPython. |
|||
msg268284 - (view) | Author: Park Alex (Park Alex) | Date: 2016-06-11 21:48 | |
I totally agreed with your opinion. So I hesitated before reporting the issue (I thought) It's kinda, we have different point of view. As far as I can tell, python could be corrupted with .pyc like heap-use-after-free, buffer overrun and so on. Again, I agreed with your comment below: "If you are able to execute untrusted .pyc, you can already execute arbitrary code, no?" If don't want to bother you guys, I respect python-dev as always. Thanks, -- Alex |
|||
msg268286 - (view) | Author: Park Alex (Park Alex) | Date: 2016-06-11 21:52 | |
oops, I cannot modify reply even I wrote it, want to fix tiny typo. I don't want to bother you guys, I respect python-dev as always. Thanks, -- Alex |
|||
msg268302 - (view) | Author: Gregory P. Smith (gregory.p.smith) * | Date: 2016-06-12 00:43 | |
Executing code in any form from untrusted sources can do arbitrary things. If someone can corrupt .pyc data before python executes it, they are just as likely to be able to corrupt other things leading to more direct exploits not even requiring the CPython interpreter. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:58:32 | admin | set | github: 71478 |
2016-06-12 00:43:14 | gregory.p.smith | set | status: open -> closed nosy: + gregory.p.smith messages: + msg268302 resolution: not a bug |
2016-06-11 21:52:29 | Park Alex | set | messages: + msg268286 |
2016-06-11 21:48:51 | Park Alex | set | messages: + msg268284 |
2016-06-11 21:38:50 | ppperry | set | title: two heap corruption issue -> two heap corruption issues when running modified pyc code. |
2016-06-11 21:31:38 | vstinner | set | messages: + msg268280 |
2016-06-11 21:21:28 | Park Alex | set | messages: + msg268276 |
2016-06-11 20:45:48 | serhiy.storchaka | set | messages: + msg268270 |
2016-06-11 20:41:53 | rhettinger | set | nosy:
+ rhettinger, vstinner, stutzbach, serhiy.storchaka |
2016-06-11 03:40:05 | Park Alex | create |