status-im / nim-drchaos

A powerful and easy-to-use fuzzing framework in Nim for C/C++/Obj-C targets
Other
68 stars 3 forks source link

Trying to move input instead of copy crashes. #9

Closed planetis-m closed 2 years ago

planetis-m commented 2 years ago

In the TLV serialization I used to copyMem whole regions of memory based on supportsCopyMem(T). It gives the following AddressSanitizer crash, with this line: x = move getInput(x, data) (tests/tvariants2):

=================================================================
==24735==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000296e98 at pc 0x55f378e7bfbe bp 0x7ffe980d1020 sp 0x7ffe980d07e0
READ of size 1 at 0x603000296e98 thread T0
    #0 0x55f378e7bfbd in __asan_memcpy (nim-drchaos/build/tvariants2+0x147fbd)
    #1 0x55f378edcddb in nimCopyMem Nim/lib/system/memory.nim:10:24
    #2 0x55f378edcddb in copyMem__system_1705 Nim/lib/system.nim:2254:2
    #3 0x55f378edcddb in writeData__OOZdrchaosZcommon_287 nim-drchaos/drchaos/common.nim:162:3
    #4 0x55f378ede911 in toData__OOZdrchaosZcommon_646 nim-drchaos/drchaos/common.nim:270:2
    #5 0x55f378ede359 in toData__tvariants50_384 nim-drchaos/drchaos/common.nim:380:3
    #6 0x55f378eddc2d in toData__tvariants50_412 nim-drchaos/drchaos/common.nim:299:5
    #7 0x55f378ede40d in toData__tvariants50_384 nim-drchaos/drchaos/common.nim:380:3
    #8 0x55f378eea69f in setInput__tvariants50_375 nim-drchaos/drchaos/mutator.nim:559:2
    #9 0x55f378eea69f in customMutatorImpl__tvariants50_484 nim-drchaos/drchaos/mutator.nim:580:3
    #10 0x55f378eeb9f2 in LLVMFuzzerCustomMutator nim-drchaos/drchaos/mutator.nim:600:11
    #11 0x55f378dbd5bc in fuzzer::MutationDispatcher::MutateImpl(unsigned char*, unsigned long, unsigned long, std::vector<fuzzer::MutationDispatcher::Mutator, std::allocator<fuzzer::MutationDispatcher::Mutator> >&) (nim-drchaos/build/tvariants2+0x895bc)
    #12 0x55f378da958b in fuzzer::Fuzzer::MutateAndTestOne() (nim-drchaos/build/tvariants2+0x7558b)
    #13 0x55f378daaf77 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) (nim-drchaos/build/tvariants2+0x76f77)
    #14 0x55f378d8ed44 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (nim-drchaos/build/tvariants2+0x5ad44)
    #15 0x55f378d7e237 in main (nim-drchaos/build/tvariants2+0x4a237)
    #16 0x7f22745542cf  (/usr/lib/libc.so.6+0x232cf) (BuildId: 9c28cfc869012ebbd43cdb0f1eebcd14e1b8bdd8)
    #17 0x7f2274554389 in __libc_start_main (/usr/lib/libc.so.6+0x23389) (BuildId: 9c28cfc869012ebbd43cdb0f1eebcd14e1b8bdd8)
    #18 0x55f378d7e274 in _start /build/glibc/src/glibc/csu/../sysdeps/x86_64/start.S:115

0x603000296e98 is located 8 bytes inside of 32-byte region [0x603000296e90,0x603000296eb0)
freed by thread T0 here:
    #0 0x55f378e7cef2 in __interceptor_free.part.0 asan_malloc_linux.cpp.o
    #1 0x55f378ee83f9 in eqsink___tvariants50_158 Nim/lib/system.nim:1018:3
    #2 0x55f378ed1ea0 in delete__tvariants50_768 Nim/lib/system.nim:1018:5
    #3 0x55f378ee11c8 in mutateSeq__tvariants50_696 nim-drchaos/drchaos/mutator.nim:71:4
    #4 0x55f378ee3063 in mutate__tvariants50_680 nim-drchaos/drchaos/mutator.nim:217:29
    #5 0x55f378ee3f78 in pick__tvariants50_669 nim-drchaos/drchaos/mutator.nim:326:4
    #6 0x55f378ee5958 in pick__tvariants50_609 nim-drchaos/drchaos/common.nim:29:3
    #7 0x55f378ee0aff in runMutator__tvariants50_501 nim-drchaos/drchaos/mutator.nim:402:3
    #8 0x55f378ee6e28 in myMutator__tvariants50_496 nim-drchaos/drchaos/mutator.nim:526:2
    #9 0x55f378eea351 in customMutatorImpl__tvariants50_484 nim-drchaos/drchaos/mutator.nim:577:2
    #10 0x55f378eeb9f2 in LLVMFuzzerCustomMutator nim-drchaos/drchaos/mutator.nim:600:11
    #11 0x55f378dbd5bc in fuzzer::MutationDispatcher::MutateImpl(unsigned char*, unsigned long, unsigned long, std::vector<fuzzer::MutationDispatcher::Mutator, std::allocator<fuzzer::MutationDispatcher::Mutator> >&) (nim-drchaos/build/tvariants2+0x895bc)
    #12 0x55f378da958b in fuzzer::Fuzzer::MutateAndTestOne() (nim-drchaos/build/tvariants2+0x7558b)
    #13 0x55f378daaf77 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) (nim-drchaos/build/tvariants2+0x76f77)
    #14 0x55f378d8ed44 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (nim-drchaos/build/tvariants2+0x5ad44)
    #15 0x55f378d7e237 in main (nim-drchaos/build/tvariants2+0x4a237)
    #16 0x7f22745542cf  (/usr/lib/libc.so.6+0x232cf) (BuildId: 9c28cfc869012ebbd43cdb0f1eebcd14e1b8bdd8)

previously allocated by thread T0 here:
    #0 0x55f378e7e261 in __interceptor_calloc (nim-drchaos/build/tvariants2+0x14a261)
    #1 0x55f378ec69ea in newSeqPayload Nim/lib/system/seqs_v2.nim:38:26
    #2 0x55f378ed39ad in add__tvariants50_915 Nim/lib/system/seqs_v2.nim:109:26
    #3 0x55f378ee1ee6 in mutateSeq__tvariants50_696 nim-drchaos/drchaos/mutator.nim:81:3
    #4 0x55f378ee3122 in mutate__tvariants50_680 nim-drchaos/drchaos/mutator.nim:217:29
    #5 0x55f378ee3f78 in pick__tvariants50_669 nim-drchaos/drchaos/mutator.nim:326:4
    #6 0x55f378ee5958 in pick__tvariants50_609 nim-drchaos/drchaos/common.nim:29:3
    #7 0x55f378ee0aff in runMutator__tvariants50_501 nim-drchaos/drchaos/mutator.nim:402:3
    #8 0x55f378ee15fd in newInput__tvariants50_846 nim-drchaos/drchaos/mutator.nim:65:2
    #9 0x55f378ee15fd in mutateSeq__tvariants50_696 nim-drchaos/drchaos/mutator.nim:76:11
    #10 0x55f378ee3063 in mutate__tvariants50_680 nim-drchaos/drchaos/mutator.nim:217:29
    #11 0x55f378ee3f78 in pick__tvariants50_669 nim-drchaos/drchaos/mutator.nim:326:4
    #12 0x55f378ee5958 in pick__tvariants50_609 nim-drchaos/drchaos/common.nim:29:3
    #13 0x55f378ee0aff in runMutator__tvariants50_501 nim-drchaos/drchaos/mutator.nim:402:3
    #14 0x55f378ee6e28 in myMutator__tvariants50_496 nim-drchaos/drchaos/mutator.nim:526:2
    #15 0x55f378eea351 in customMutatorImpl__tvariants50_484 nim-drchaos/drchaos/mutator.nim:577:2
    #16 0x55f378eeb9f2 in LLVMFuzzerCustomMutator nim-drchaos/drchaos/mutator.nim:600:11
    #17 0x55f378dbd5bc in fuzzer::MutationDispatcher::MutateImpl(unsigned char*, unsigned long, unsigned long, std::vector<fuzzer::MutationDispatcher::Mutator, std::allocator<fuzzer::MutationDispatcher::Mutator> >&) (nim-drchaos/build/tvariants2+0x895bc)
    #18 0x55f378da958b in fuzzer::Fuzzer::MutateAndTestOne() (nim-drchaos/build/tvariants2+0x7558b)
    #19 0x55f378daaf77 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) (nim-drchaos/build/tvariants2+0x76f77)
    #20 0x55f378d8ed44 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (nim-drchaos/build/tvariants2+0x5ad44)
    #21 0x55f378d7e237 in main (nim-drchaos/build/tvariants2+0x4a237)
    #22 0x7f22745542cf  (/usr/lib/libc.so.6+0x232cf) (BuildId: 9c28cfc869012ebbd43cdb0f1eebcd14e1b8bdd8)

SUMMARY: AddressSanitizer: heap-use-after-free (nim-drchaos/build/tvariants2+0x147fbd) in __asan_memcpy
Shadow bytes around the buggy address:
  0x0c068004ad80: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa
  0x0c068004ad90: fd fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd
  0x0c068004ada0: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd
  0x0c068004adb0: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa
  0x0c068004adc0: fd fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd
=>0x0c068004add0: fa fa fd[fd]fd fd fa fa fd fd fd fd fa fa fd fd
  0x0c068004ade0: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa
  0x0c068004adf0: 00 00 00 00 fa fa fd fd fd fd fa fa fa fa fa fa
  0x0c068004ae00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c068004ae10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c068004ae20: 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
==24735==ABORTING
planetis-m commented 2 years ago

Nope still happens after removing every usage of supportsCopyMem. This is caused by =sink(x, move x). Also crashes in:

==28086==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b000133288 at pc 0x55b0952acbff bp 0x7fffc5cbce60 sp 0x7fffc5cbce58
READ of size 1 at 0x60b000133288 thread T0
    #0 0x55b0952acbfe in runPostProcessor__tvariants50_1008 nim-drchaos/drchaos/common.nim:12:30
    #1 0x55b0952ac4a8 in runPostProcessor__tvariants50_1028 nim-drchaos/drchaos/mutator.nim:461:6
    #2 0x55b0952acb77 in runPostProcessor__tvariants50_1008 nim-drchaos/drchaos/common.nim:29:4
    #3 0x55b0952ac4a8 in runPostProcessor__tvariants50_1028 nim-drchaos/drchaos/mutator.nim:461:6
    #4 0x55b0952acb77 in runPostProcessor__tvariants50_1008 nim-drchaos/drchaos/common.nim:29:4
    #5 0x55b0952ad0b4 in myMutator__tvariants50_538 nim-drchaos/drchaos/mutator.nim:528:2
    #6 0x55b0952afe96 in customMutatorImpl__tvariants50_526 nim-drchaos/drchaos/mutator.nim:575:2
    #7 0x55b0952b0ef8 in LLVMFuzzerCustomMutator nim-drchaos/drchaos/mutator.nim:598:11
    #8 0x55b09517e46c in fuzzer::MutationDispatcher::MutateImpl(unsigned char*, unsigned long, unsigned long, std::vector<fuzzer::MutationDispatcher::Mutator, std::allocator<fuzzer::MutationDispatcher::Mutator> >&) crtstuff.c
    #9 0x55b09516a3fb in fuzzer::Fuzzer::MutateAndTestOne() crtstuff.c
    #10 0x55b09516bde7 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) crtstuff.c
    #11 0x55b09514fb74 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) crtstuff.c
    #12 0x55b09518a107 in main crtstuff.c
    #13 0x7fdab003c2cf  (/usr/lib/libc.so.6+0x232cf) (BuildId: 9c28cfc869012ebbd43cdb0f1eebcd14e1b8bdd8)
    #14 0x7fdab003c389 in __libc_start_main (/usr/lib/libc.so.6+0x23389) (BuildId: 9c28cfc869012ebbd43cdb0f1eebcd14e1b8bdd8)
    #15 0x55b09513f0a4 in _start /build/glibc/src/glibc/csu/../sysdeps/x86_64/start.S:115

0x60b000133288 is located 8 bytes inside of 104-byte region [0x60b000133280,0x60b0001332e8)
freed by thread T0 here:
    #0 0x55b09523def2 in __interceptor_free.part.0 crtstuff.c
    #1 0x55b0952ae149 in eqsink___tvariants50_170 Nim/lib/system.nim:1018:3
    #2 0x55b09529c994 in delete__tvariants50_810 Nim/lib/system.nim:1018:5
    #3 0x55b0952a7cbd in mutateSeq__tvariants50_738 nim-drchaos/drchaos/mutator.nim:71:4
    #4 0x55b0952a998a in mutate__tvariants50_722 nim-drchaos/drchaos/mutator.nim:217:29
    #5 0x55b0952aa868 in pick__tvariants50_711 nim-drchaos/drchaos/mutator.nim:326:4
    #6 0x55b0952abde8 in pick__tvariants50_651 nim-drchaos/drchaos/common.nim:29:3
    #7 0x55b0952a7847 in runMutator__tvariants50_543 nim-drchaos/drchaos/mutator.nim:402:3
    #8 0x55b0952ad048 in myMutator__tvariants50_538 nim-drchaos/drchaos/mutator.nim:526:2
    #9 0x55b0952afe96 in customMutatorImpl__tvariants50_526 nim-drchaos/drchaos/mutator.nim:575:2
    #10 0x55b0952b0ef8 in LLVMFuzzerCustomMutator nim-drchaos/drchaos/mutator.nim:598:11
    #11 0x55b09517e46c in fuzzer::MutationDispatcher::MutateImpl(unsigned char*, unsigned long, unsigned long, std::vector<fuzzer::MutationDispatcher::Mutator, std::allocator<fuzzer::MutationDispatcher::Mutator> >&) crtstuff.c
    #12 0x55b09516a3fb in fuzzer::Fuzzer::MutateAndTestOne() crtstuff.c
    #13 0x55b09516bde7 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) crtstuff.c
    #14 0x55b09514fb74 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) crtstuff.c
    #15 0x55b09518a107 in main crtstuff.c
    #16 0x7fdab003c2cf  (/usr/lib/libc.so.6+0x232cf) (BuildId: 9c28cfc869012ebbd43cdb0f1eebcd14e1b8bdd8)

previously allocated by thread T0 here:
    #0 0x55b09523e03a in __interceptor_realloc.part.0 crtstuff.c
    #1 0x55b0952931cf in reallocImpl__system_1727 Nim/lib/system/mm/malloc.nim:17:11
    #2 0x55b0952931cf in realloc0Impl__system_1730 Nim/lib/system/mm/malloc.nim:23:11
    #3 0x55b0952931cf in reallocShared0Impl__system_1743 Nim/lib/system/mm/malloc.nim:43:11
    #4 0x55b0952931cf in alignedRealloc0__system_1913 Nim/lib/system/memalloc.nim:398:12
    #5 0x55b0952936aa in prepareSeqAdd Nim/lib/system/seqs_v2.nim:72:30
    #6 0x55b0952986f9 in setLen__tvariants50_129 Nim/lib/system/seqs_v2.nim:126:30
    #7 0x55b09529d1db in insert__tvariants50_902 Nim/lib/system.nim:1360:2
    #8 0x55b0952a80b2 in mutateSeq__tvariants50_738 nim-drchaos/drchaos/mutator.nim:76:4
    #9 0x55b0952a9a52 in mutate__tvariants50_722 nim-drchaos/drchaos/mutator.nim:217:29
    #10 0x55b0952aa868 in pick__tvariants50_711 nim-drchaos/drchaos/mutator.nim:326:4
    #11 0x55b0952abde8 in pick__tvariants50_651 nim-drchaos/drchaos/common.nim:29:3
    #12 0x55b0952a7847 in runMutator__tvariants50_543 nim-drchaos/drchaos/mutator.nim:402:3
    #13 0x55b0952a7f81 in newInput__tvariants50_891 nim-drchaos/drchaos/mutator.nim:65:2
    #14 0x55b0952a7f81 in mutateSeq__tvariants50_738 nim-drchaos/drchaos/mutator.nim:76:11
    #15 0x55b0952a998a in mutate__tvariants50_722 nim-drchaos/drchaos/mutator.nim:217:29
    #16 0x55b0952aa868 in pick__tvariants50_711 nim-drchaos/drchaos/mutator.nim:326:4
    #17 0x55b0952abde8 in pick__tvariants50_651 nim-drchaos/drchaos/common.nim:29:3
    #18 0x55b0952a7847 in runMutator__tvariants50_543 nim-drchaos/drchaos/mutator.nim:402:3
    #19 0x55b0952ad048 in myMutator__tvariants50_538 nim-drchaos/drchaos/mutator.nim:526:2
    #20 0x55b0952afe96 in customMutatorImpl__tvariants50_526 nim-drchaos/drchaos/mutator.nim:575:2
    #21 0x55b0952b0ef8 in LLVMFuzzerCustomMutator nim-drchaos/drchaos/mutator.nim:598:11
    #22 0x55b09517e46c in fuzzer::MutationDispatcher::MutateImpl(unsigned char*, unsigned long, unsigned long, std::vector<fuzzer::MutationDispatcher::Mutator, std::allocator<fuzzer::MutationDispatcher::Mutator> >&) crtstuff.c
    #23 0x55b09516a3fb in fuzzer::Fuzzer::MutateAndTestOne() crtstuff.c
    #24 0x55b09516bde7 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) crtstuff.c
    #25 0x55b09514fb74 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) crtstuff.c
    #26 0x55b09518a107 in main crtstuff.c
    #27 0x7fdab003c2cf  (/usr/lib/libc.so.6+0x232cf) (BuildId: 9c28cfc869012ebbd43cdb0f1eebcd14e1b8bdd8)

SUMMARY: AddressSanitizer: heap-use-after-free nim-drchaos/drchaos/common.nim:12:30 in runPostProcessor__tvariants50_1008
Shadow bytes around the buggy address:
  0x0c168001e600: fd fd fd fd fd fa fa fa fa fa fa fa fa fa fd fd
  0x0c168001e610: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa
  0x0c168001e620: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c168001e630: fd fa fa fa fa fa fa fa fa fa fd fd fd fd fd fd
  0x0c168001e640: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa
=>0x0c168001e650: fd[fd]fd fd fd fd fd fd fd fd fd fd fd fa fa fa
  0x0c168001e660: fa fa fa fa fa fa fd fd fd fd fd fd fd fd fd fd
  0x0c168001e670: fd fd fd fa fa fa fa fa fa fa fa fa fd fd fd fd
  0x0c168001e680: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa
  0x0c168001e690: fa fa 00 00 00 00 00 00 00 00 00 00 00 00 00 fa
  0x0c168001e6a0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
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
==28086==ABORTING
planetis-m commented 2 years ago

Huge speedup is at stake if I managed to find a fix. Somewhere a wasMoved is missing.

planetis-m commented 2 years ago

ContentNode switching branches from Br to either Str or P crashes. After that textStr or pChildren contain grabage! Needs the discriminator destructor to be followed by discriminator assignment and a conditional wasMoved. This is confirmed by emitting C code and running the fuzzer.

planetis-m commented 2 years ago

Bug fixed in https://github.com/nim-lang/Nim/pull/20300