openxc / bitfield-c

Bit array parsing and encoding utility library in C
BSD 3-Clause "New" or "Revised" License
92 stars 51 forks source link

stack-buffer-overflow in copy_bits #17

Open ADKaster opened 2 years ago

ADKaster commented 2 years ago

When running make test with -fsanitize=address in CFLAGS and LDFLAGS, AddressSanitizer quickly finds a bug in copy_bits.

The issue seems to be the increment of source on line 72:

https://github.com/openxc/bitfield-c/blob/e5692e7fda0e55aa271ead33fc23f17a642f2ba5/src/bitfield/bitarray.c#L72-L73

If source was already pointing at &source_origin[source_length - 1], then the read after the increment of source reads the next byte on the stack, out of bounds of the source array.

=== ASAN output below: ===

Running suite(s): bitfield
=================================================================
==166==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd9e915501 at pc 0x55df99f5bde0 bp 0x7ffd9e915420 sp 0x7ffd9e915418
READ of size 1 at 0x7ffd9e915501 thread T0
    #0 0x55df99f5bddf in copy_bits src/bitfield/bitarray.c:73
    #1 0x55df99f5cb8d in set_nibble src/bitfield/bitfield.c:103
    #2 0x55df99f58b24 in test_set_nibble tests/bitfield_tests.c:18
    #3 0x7f0fcda1cdcf  (/lib64/libcheck.so.0+0x5dcf)
    #4 0x7f0fcda1d40d in srunner_run_tagged (/lib64/libcheck.so.0+0x640d)
    #5 0x55df99f5b68e in main tests/bitfield_tests.c:141
    #6 0x7f0fcd24f6a2 in __libc_start_main (/lib64/libc.so.6+0x236a2)
    #7 0x55df99f5866d in _start (/workspace/lib/bitfield-c/build/tests/bitfield_tests.bin+0x666d)

Address 0x7ffd9e915501 is located in stack of thread T0 at offset 33 in frame
    #0 0x55df99f5cac8 in set_nibble src/bitfield/bitfield.c:102

  This frame has 1 object(s):
    [32, 33) 'value' (line 101) <== Memory access at offset 33 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow src/bitfield/bitarray.c:73 in copy_bits
Shadow bytes around the buggy address:
  0x100033d1aa50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100033d1aa60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100033d1aa70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100033d1aa80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100033d1aa90: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
=>0x100033d1aaa0:[01]f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x100033d1aab0: 00 00 f1 f1 f1 f1 04 f3 f3 f3 00 00 00 00 00 00
  0x100033d1aac0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100033d1aad0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100033d1aae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100033d1aaf0: 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
  Shadow gap:              cc
==166==ABORTING
ERROR in test build/tests/bitfield_tests.bin:
$ gcc --version
gcc (GCC) 10.1.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.