pygame-ce icon indicating copy to clipboard operation
pygame-ce copied to clipboard

Address sanitizer build (1312)

Open GalacticEmperor1 opened this issue 2 years ago • 1 comments
trafficstars

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:

  • Out-of-bounds accesses to heap, stack and globals
  • Use-after-free
  • Use-after-return (runtime flag ASAN_OPTIONS=detect_stack_use_after_return=1)
  • Use-after-scope (clang flag -fsanitize-address-use-after-scope)
  • Double-free, invalid free
  • Memory leaks (experimental)

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.

GalacticEmperor1 avatar Feb 12 '23 11:02 GalacticEmperor1

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

gresm avatar Jul 20 '24 07:07 gresm