google / sanitizers

AddressSanitizer, ThreadSanitizer, MemorySanitizer
Other
11.45k stars 1.03k forks source link

mmap regions which are repeatedly munmapped are not correctly unpoisoned. #1705

Open danog opened 11 months ago

danog commented 11 months ago

Ref https://github.com/php/php-src/issues/12670

Reproducers 10, 11, 12 cause stack-buffer-overflow and stack-buffer-underflow issues when running with --repeat 2 and USE_ZEND_ALLOC=1: https://github.com/danog/jit_bugs

According to maintainers @ php-src, these may or may not be false positives; opening this issue in case they are false positives that should be fixed here.

It's also strange that the issue only occurs when running with --repeat 2 (just for reproducer 12). JIT is not necessary to reproduce (and is disabled in the reproducers).

Results (reproducer 12):

Executing for the first time...
PHPUnit 9.6.13 by Sebastian Bergmann and contributors.

...............................................................  63 / 467 ( 13%)
..........................SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS 126 / 467 ( 26%)
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS...... 189 / 467 ( 40%)
............................................................... 252 / 467 ( 53%)
............................................................... 315 / 467 ( 67%)
.......................................................SSSSSSSS 378 / 467 ( 80%)
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS 441 / 467 ( 94%)
SSSSSSSSSSSSSSSSSSSSSSS..S                                      467 / 467 (100%)

Time: 00:36.574, Memory: 16.00 MB

OK, but incomplete, skipped, or risky tests!
Tests: 467, Assertions: 425, Skipped: 189.
JIT is not enabled!
Finished execution, repeating...
PHPUnit 9.6.13 by Sebastian Bergmann and contributors.

...............................................................  63 / 467 ( 13%)
..........................SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS 126 / 467 ( 26%)
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS...=================================================================
==1==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7f1d787ffe80 at pc 0x5607208ab82a bp 0x7f1d524fd220 sp 0x7f1d524fd218
WRITE of size 8 at 0x7f1d787ffe80 thread T0
^C==1==WARNING: Can't read from symbolizer at fd 174
==1==WARNING: Can't write to symbolizer at fd 179
^C==1==WARNING: Can't read from symbolizer at fd 174
==1==WARNING: Can't write to symbolizer at fd 179
^C==1==WARNING: Can't read from symbolizer at fd 174
==1==WARNING: Can't write to symbolizer at fd 179
^C==1==WARNING: Can't read from symbolizer at fd 174
==1==WARNING: Can't write to symbolizer at fd 179
==1==WARNING: Failed to use and restart external symbolizer!
    #0 0x5607208ab829  (/usr/bin/php+0x10ab829) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #1 0x5607208aa75b  (/usr/bin/php+0x10aa75b) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #2 0x5607208a3dff  (/usr/bin/php+0x10a3dff) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #3 0x5607208a6129  (/usr/bin/php+0x10a6129) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #4 0x5607209c64f7  (/usr/bin/php+0x11c64f7) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #5 0x560720a0e14b  (/usr/bin/php+0x120e14b) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #6 0x560720a14987  (/usr/bin/php+0x1214987) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #7 0x560720bc5aff  (/usr/bin/php+0x13c5aff) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #8 0x560720a3452d  (/usr/bin/php+0x123452d) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #9 0x56072092b9e9  (/usr/bin/php+0x112b9e9) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #10 0x560720d76d23  (/usr/bin/php+0x1576d23) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #11 0x560720d7335e  (/usr/bin/php+0x157335e) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
    #12 0x56072077c3be  (/usr/bin/php+0xf7c3be) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)

Address 0x7f1d787ffe80 is a wild pointer inside of access range of size 0x000000000008.
SUMMARY: AddressSanitizer: stack-buffer-underflow (/usr/bin/php+0x10ab829) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)
Shadow bytes around the buggy address:
  0x7f1d787ffc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f1d787ffc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f1d787ffd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f1d787ffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f1d787ffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7f1d787ffe80:[f1]f1 f1 f1 00 00 f2 f2 00 00 00 00 f3 f3 f3 f3
  0x7f1d787fff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f1d787fff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f1d78800000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f1d78800080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f1d78800100: 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
  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
==1==ABORTING
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer: nested bug in the same thread, aborting.

Reproducer 11:

Executing for the first time...
PHPUnit 9.6.13 by Sebastian Bergmann and contributors.

...............................................................  63 / 366 ( 17%)
............................................................... 126 / 366 ( 34%)
................................=================================================================
==1==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7f4e807ffe80 at pc 0x559fd70ab770 bp 0x7fff2ae81ab0 sp 0x7fff2ae81aa8
WRITE of size 8 at 0x7f4e807ffe80 thread T0
    #0 0x559fd70ab76f in zend_mm_alloc_small_slow /php-src/Zend/zend_alloc.c:1276:21
    #1 0x559fd70aa75b in zend_mm_alloc_small /php-src/Zend/zend_alloc.c:1315:10
    #2 0x559fd70a3dff in zend_mm_alloc_heap /php-src/Zend/zend_alloc.c:1383:9
    #3 0x559fd70a6129 in _emalloc /php-src/Zend/zend_alloc.c:2615:9
    #4 0x559fd74de914 in zend_create_closure_ex /php-src/Zend/zend_closures.c:783:11
    #5 0x559fd74d7696 in zend_create_closure /php-src/Zend/zend_closures.c:826:2
    #6 0x559fd73d8649 in ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_HANDLER /php-src/Zend/zend_vm_execute.h:5492:2
    #7 0x559fd723452d in execute_ex /php-src/Zend/zend_vm_execute.h:56987:7
    #8 0x559fd7234e67 in zend_execute /php-src/Zend/zend_vm_execute.h:61584:2
    #9 0x559fd7180938 in zend_execute_scripts /php-src/Zend/zend.c:1881:4
    #10 0x559fd6f86be1 in php_execute_script /php-src/main/main.c:2492:13
    #11 0x559fd7714779 in do_cli /php-src/sapi/cli/php_cli.c:966:5
    #12 0x559fd771230c in main /php-src/sapi/cli/php_cli.c:1340:18
    #13 0x7f4e86409d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: a43bfc8428df6623cd498c9c0caeb91aec9be4f9)
    #14 0x7f4e86409e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: a43bfc8428df6623cd498c9c0caeb91aec9be4f9)
    #15 0x559fd6405ca4 in _start (/usr/bin/php+0x405ca4) (BuildId: ad2382b3df2dce8f30c7a56c393240e1cd1d9312)

Address 0x7f4e807ffe80 is a wild pointer inside of access range of size 0x000000000008.
SUMMARY: AddressSanitizer: stack-buffer-underflow /php-src/Zend/zend_alloc.c:1276:21 in zend_mm_alloc_small_slow
Shadow bytes around the buggy address:
  0x7f4e807ffc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f4e807ffc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f4e807ffd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f4e807ffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f4e807ffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7f4e807ffe80:[f1]f1 f1 f1 00 00 f2 f2 00 00 00 00 f3 f3 f3 f3
  0x7f4e807fff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f4e807fff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f4e80800000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f4e80800080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f4e80800100: 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
  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
==1==ABORTING
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer: nested bug in the same thread, aborting.

Reproducer 10:

Executing for the first time...
PHPUnit 9.6.13 by Sebastian Bergmann and contributors.

SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS  63 / 462 ( 13%)
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS 126 / 462 ( 27%)
SSSSSSSS..=================================================================
==1==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7f01bbbffe80 at pc 0x55e11faab82a bp 0x7f01bb9feac0 sp 0x7f01bb9feab8
WRITE of size 8 at 0x7f01bbbffe80 thread T0
    #0 0x55e11faab829 in zend_mm_alloc_small_slow /php-src/Zend/zend_alloc.c:1280:14
    #1 0x55e11faaa75b in zend_mm_alloc_small /php-src/Zend/zend_alloc.c:1315:10
    #2 0x55e11faa3dff in zend_mm_alloc_heap /php-src/Zend/zend_alloc.c:1383:9
    #3 0x55e11faa6129 in _emalloc /php-src/Zend/zend_alloc.c:2615:9
    #4 0x55e11fbc64f7 in _zend_new_array /php-src/Zend/zend_hash.c:291:18
    #5 0x55e11fc7cbb7 in ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER /php-src/Zend/zend_vm_execute.h:27388:21
    #6 0x55e11fc3452d in execute_ex /php-src/Zend/zend_vm_execute.h:56987:7
    #7 0x55e11fb2b9e9 in zend_call_function /php-src/Zend/zend_execute_API.c:957:3
    #8 0x55e11ff76d23 in zend_fiber_execute /php-src/Zend/zend_fibers.c:588:3
    #9 0x55e11ff7335e in zend_fiber_trampoline /php-src/Zend/zend_fibers.c:371:2
    #10 0x55e11f97c3be in trampoline /php-src/Zend/asm/make_x86_64_sysv_elf_gas.S:174

Address 0x7f01bbbffe80 is a wild pointer inside of access range of size 0x000000000008.
SUMMARY: AddressSanitizer: stack-buffer-underflow /php-src/Zend/zend_alloc.c:1280:14 in zend_mm_alloc_small_slow
Shadow bytes around the buggy address:
  0x7f01bbbffc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f01bbbffc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f01bbbffd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f01bbbffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f01bbbffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7f01bbbffe80:[f1]f1 f1 f1 00 00 f2 f2 00 00 00 00 f3 f3 f3 f3
  0x7f01bbbfff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f01bbbfff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f01bbc00000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f01bbc00080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f01bbc00100: 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
  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
==1==ABORTING
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer: nested bug in the same thread, aborting.

PHP Version

f8c2d1ec2f2e2d844484b92d9a33f3cc2defbc31

Operating System

Ubuntu

iluuu1994 commented 10 months ago

I have had a closer look at this particular instance in php-src and apparently it is caused by repeated mmap/munmap calls with mmap returning the same base-address. It seems ASAN doesn't correctly unpoison the memory region. Adding an explicit __asan_unpoison_memory_region solves the issue for me.

Patch

```diff diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index caa2a6ad66..5a65ac6d41 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -79,6 +79,9 @@ #include #include #include +#ifdef __SANITIZE_ADDRESS__ +# include +#endif #ifndef _WIN32 # include @@ -724,6 +727,9 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment) if (zend_mm_use_huge_pages) { zend_mm_hugepage(ptr, size); } +#ifdef __SANITIZE_ADDRESS__ + __asan_unpoison_memory_region(ptr, size); +#endif return ptr; } else { size_t offset; @@ -763,6 +769,9 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment) if (zend_mm_use_huge_pages) { zend_mm_hugepage(ptr, size); } +# ifdef __SANITIZE_ADDRESS__ + __asan_unpoison_memory_region(ptr, size); +# endif #endif return ptr; } ```

danog commented 7 months ago

Closing this, fixed upstream!

iluuu1994 commented 7 months ago

It seems to me like we shouldn't need explicit unpoisoning in this case.

danog commented 7 months ago

Let's reopen this then :)