pygame-community / pygame-ce

🐍🎮 pygame - Community Edition is a FOSS Python library for multimedia applications (like games). Built on top of the excellent SDL library.
https://pyga.me
951 stars 157 forks source link

Address sanitizer build (1312) #766

Open GalacticEmperor1 opened 1 year ago

GalacticEmperor1 commented 1 year ago

Issue №1312 opened by illume at 2019-09-17 09:16:06

Doing a test run with an address sanitizer apparently helps to detect various types of bugs.

AddressSanitizer is a fast memory error detector. It consists of a compiler instrumentation module and a run-time library. The tool can detect the following types of bugs:

How to compile a python C extension with clang on MacOS:

LDFLAGS="-g -fsanitize=address" CFLAGS="-g -fsanitize=address -fno-omit-frame-pointer" python3 setup.py install

Comments

*illume commented at 2019-09-28 21:22:17*

Here's one issue it found running the tests...

DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/10.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib \
/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python \
test/mask_test.py -v
AddressSanitizer: heap-buffer-overflow bitmask.c:882 in bitmask_draw mask_test.py:test_draw__bit_boundaries

``` test_draw__bit_boundaries (__main__.MaskTypeTest) Ensures draw handles masks of different sizes correctly. ... ================================================================= ==75420==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000031c50 at pc 0x00010d735a80 bp 0x7ffee6c5e630 sp 0x7ffee6c5e628 READ of size 8 at 0x603000031c50 thread T0 # 0 0x10d735a7f in bitmask_draw bitmask.c:882 # 1 0x10d729d32 in mask_draw mask.c:313 # 2 0x10a031abb in _PyMethodDef_RawFastCallKeywords (Python:x86_64+0x1aabb) # 3 0x10a036555 in _PyMethodDescr_FastCallKeywords (Python:x86_64+0x1f555) # 4 0x10a0c7150 in call_function (Python:x86_64+0xb0150) # 5 0x10a0bfce3 in _PyEval_EvalFrameDefault (Python:x86_64+0xa8ce3) # 6 0x10a031515 in function_code_fastcall (Python:x86_64+0x1a515) # 7 0x10a0c7120 in call_function (Python:x86_64+0xb0120) # 8 0x10a0bfd9a in _PyEval_EvalFrameDefault (Python:x86_64+0xa8d9a) # 9 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 10 0x10a030d68 in _PyFunction_FastCallDict (Python:x86_64+0x19d68) # 11 0x10a031ebc in _PyObject_Call_Prepend (Python:x86_64+0x1aebc) # 12 0x10a031248 in PyObject_Call (Python:x86_64+0x1a248) # 13 0x10a0c0013 in _PyEval_EvalFrameDefault (Python:x86_64+0xa9013) # 14 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 15 0x10a030d68 in _PyFunction_FastCallDict (Python:x86_64+0x19d68) # 16 0x10a031ebc in _PyObject_Call_Prepend (Python:x86_64+0x1aebc) # 17 0x10a06efa3 in slot_tp_call (Python:x86_64+0x57fa3) # 18 0x10a030fa0 in _PyObject_FastCallKeywords (Python:x86_64+0x19fa0) # 19 0x10a0c7119 in call_function (Python:x86_64+0xb0119) # 20 0x10a0bfd9a in _PyEval_EvalFrameDefault (Python:x86_64+0xa8d9a) # 21 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 22 0x10a030d68 in _PyFunction_FastCallDict (Python:x86_64+0x19d68) # 23 0x10a031ebc in _PyObject_Call_Prepend (Python:x86_64+0x1aebc) # 24 0x10a031248 in PyObject_Call (Python:x86_64+0x1a248) # 25 0x10a0c0013 in _PyEval_EvalFrameDefault (Python:x86_64+0xa9013) # 26 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 27 0x10a030d68 in _PyFunction_FastCallDict (Python:x86_64+0x19d68) # 28 0x10a031ebc in _PyObject_Call_Prepend (Python:x86_64+0x1aebc) # 29 0x10a06efa3 in slot_tp_call (Python:x86_64+0x57fa3) # 30 0x10a030fa0 in _PyObject_FastCallKeywords (Python:x86_64+0x19fa0) # 31 0x10a0c7119 in call_function (Python:x86_64+0xb0119) # 32 0x10a0bfd9a in _PyEval_EvalFrameDefault (Python:x86_64+0xa8d9a) # 33 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 34 0x10a030d68 in _PyFunction_FastCallDict (Python:x86_64+0x19d68) # 35 0x10a031ebc in _PyObject_Call_Prepend (Python:x86_64+0x1aebc) # 36 0x10a031248 in PyObject_Call (Python:x86_64+0x1a248) # 37 0x10a0c0013 in _PyEval_EvalFrameDefault (Python:x86_64+0xa9013) # 38 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 39 0x10a030d68 in _PyFunction_FastCallDict (Python:x86_64+0x19d68) # 40 0x10a031ebc in _PyObject_Call_Prepend (Python:x86_64+0x1aebc) # 41 0x10a06efa3 in slot_tp_call (Python:x86_64+0x57fa3) # 42 0x10a030fa0 in _PyObject_FastCallKeywords (Python:x86_64+0x19fa0) # 43 0x10a0c7119 in call_function (Python:x86_64+0xb0119) # 44 0x10a0bfd9a in _PyEval_EvalFrameDefault (Python:x86_64+0xa8d9a) # 45 0x10a031515 in function_code_fastcall (Python:x86_64+0x1a515) # 46 0x10a0c7120 in call_function (Python:x86_64+0xb0120) # 47 0x10a0bfce3 in _PyEval_EvalFrameDefault (Python:x86_64+0xa8ce3) # 48 0x10a031515 in function_code_fastcall (Python:x86_64+0x1a515) # 49 0x10a0c7120 in call_function (Python:x86_64+0xb0120) # 50 0x10a0bfce3 in _PyEval_EvalFrameDefault (Python:x86_64+0xa8ce3) # 51 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 52 0x10a030d68 in _PyFunction_FastCallDict (Python:x86_64+0x19d68) # 53 0x10a031ebc in _PyObject_Call_Prepend (Python:x86_64+0x1aebc) # 54 0x10a06f99e in slot_tp_init (Python:x86_64+0x5899e) # 55 0x10a06c66a in type_call (Python:x86_64+0x5566a) # 56 0x10a030fa0 in _PyObject_FastCallKeywords (Python:x86_64+0x19fa0) # 57 0x10a0c7119 in call_function (Python:x86_64+0xb0119) # 58 0x10a0bfcfc in _PyEval_EvalFrameDefault (Python:x86_64+0xa8cfc) # 59 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 60 0x10a0be10c in PyEval_EvalCode (Python:x86_64+0xa710c) # 61 0x10a0ecfa4 in run_mod (Python:x86_64+0xd5fa4) # 62 0x10a0ebfbf in PyRun_FileExFlags (Python:x86_64+0xd4fbf) # 63 0x10a0eb679 in PyRun_SimpleFileExFlags (Python:x86_64+0xd4679) # 64 0x10a104016 in pymain_main (Python:x86_64+0xed016) # 65 0x10a1048a6 in _Py_UnixMain (Python:x86_64+0xed8a6) # 66 0x7fff64333014 in start (libdyld.dylib:x86_64+0x1014) 0x603000031c50 is located 8 bytes to the right of 24-byte region [0x603000031c30,0x603000031c48) allocated by thread T0 here: # 0 0x108ffef53 in wrap_malloc (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x56f53) # 1 0x10d7321a8 in bitmask_create bitmask.c:119 # 2 0x10d72780f in mask_init mask.c:2359 # 3 0x10a06c66a in type_call (Python:x86_64+0x5566a) # 4 0x10a030fa0 in _PyObject_FastCallKeywords (Python:x86_64+0x19fa0) # 5 0x10a0c7119 in call_function (Python:x86_64+0xb0119) # 6 0x10a0bfcfc in _PyEval_EvalFrameDefault (Python:x86_64+0xa8cfc) # 7 0x10a031515 in function_code_fastcall (Python:x86_64+0x1a515) # 8 0x10a0c7120 in call_function (Python:x86_64+0xb0120) # 9 0x10a0bfd9a in _PyEval_EvalFrameDefault (Python:x86_64+0xa8d9a) # 10 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 11 0x10a030d68 in _PyFunction_FastCallDict (Python:x86_64+0x19d68) # 12 0x10a031ebc in _PyObject_Call_Prepend (Python:x86_64+0x1aebc) # 13 0x10a031248 in PyObject_Call (Python:x86_64+0x1a248) # 14 0x10a0c0013 in _PyEval_EvalFrameDefault (Python:x86_64+0xa9013) # 15 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 16 0x10a030d68 in _PyFunction_FastCallDict (Python:x86_64+0x19d68) # 17 0x10a031ebc in _PyObject_Call_Prepend (Python:x86_64+0x1aebc) # 18 0x10a06efa3 in slot_tp_call (Python:x86_64+0x57fa3) # 19 0x10a030fa0 in _PyObject_FastCallKeywords (Python:x86_64+0x19fa0) # 20 0x10a0c7119 in call_function (Python:x86_64+0xb0119) # 21 0x10a0bfd9a in _PyEval_EvalFrameDefault (Python:x86_64+0xa8d9a) # 22 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 23 0x10a030d68 in _PyFunction_FastCallDict (Python:x86_64+0x19d68) # 24 0x10a031ebc in _PyObject_Call_Prepend (Python:x86_64+0x1aebc) # 25 0x10a031248 in PyObject_Call (Python:x86_64+0x1a248) # 26 0x10a0c0013 in _PyEval_EvalFrameDefault (Python:x86_64+0xa9013) # 27 0x10a0c79b5 in _PyEval_EvalCodeWithName (Python:x86_64+0xb09b5) # 28 0x10a030d68 in _PyFunction_FastCallDict (Python:x86_64+0x19d68) # 29 0x10a031ebc in _PyObject_Call_Prepend (Python:x86_64+0x1aebc) SUMMARY: AddressSanitizer: heap-buffer-overflow bitmask.c:882 in bitmask_draw Shadow bytes around the buggy address: 0x1c0600006330: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd 0x1c0600006340: fd fa fa fa fd fd fd fa fa fa fd fd fd fa fa fa 0x1c0600006350: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd fa 0x1c0600006360: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd 0x1c0600006370: fd fa fa fa fd fd fd fa fa fa fd fd fd fa fa fa =>0x1c0600006380: fd fd fd fa fa fa 00 00 00 fa[fa]fa 00 00 00 fa 0x1c0600006390: fa fa 00 00 00 fa fa fa fa fa fa fa fa fa fa fa 0x1c06000063a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1c06000063b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1c06000063c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1c06000063d0: 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 Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==75420==ABORTING Abort trap: 6 ```


*illume commented at 2019-09-28 21:26:57*

Note, to get best results all the dependencies including SDL and python should also be instrumented with asan.

gresm commented 4 months ago

Example of implementing this in action: falcosecurity/libs#978.