Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Out of bounds heap read in skel_instance_of / put.c #398

Closed
hannob opened this issue Aug 18, 2016 · 2 comments
Closed

Out of bounds heap read in skel_instance_of / put.c #398

hannob opened this issue Aug 18, 2016 · 2 comments

Comments

@hannob
Copy link

hannob commented Aug 18, 2016

There's an out of bounds read access that is triggered by running make check and can be detected using Address Sanitizer.

To reproduce:

./configure CFLAGS="-fsanitize=address -g" LDFLAGS="-fsanitize=address"
make
make check

The error happens in test_vstab. Manually run it:
ASAN_OPTIONS="fast_unwind_on_check=0:fast_unwind_on_fatal=0:fast_unwind_on_malloc=0" src/augparse --nostdinc -I ./lenses ./lenses/tests/test_vfstab.aug
(these asan options make the test much slower, but give more detailed stack traces).

Here's the full error message from Address Sanitizer:

==773==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020001275d8 at pc 0x7f412966347a bp 0x7ffd5129fb80 sp 0x7ffd5129fb78
READ of size 4 at 0x6020001275d8 thread T0
    #0 0x7f4129663479 in skel_instance_of /mnt/ram/augeas/src/put.c:407
    #1 0x7f41296632c9 in skel_instance_of /mnt/ram/augeas/src/put.c:390
    #2 0x7f41296633d4 in skel_instance_of /mnt/ram/augeas/src/put.c:400
    #3 0x7f41296632c9 in skel_instance_of /mnt/ram/augeas/src/put.c:390
    #4 0x7f4129663f0a in put_subtree /mnt/ram/augeas/src/put.c:454
    #5 0x7f4129665d1d in put_lens /mnt/ram/augeas/src/put.c:662
    #6 0x7f4129664723 in put_union /mnt/ram/augeas/src/put.c:487
    #7 0x7f4129665d05 in put_lens /mnt/ram/augeas/src/put.c:659
    #8 0x7f4129664ebb in put_quant_star /mnt/ram/augeas/src/put.c:552
    #9 0x7f4129665d32 in put_lens /mnt/ram/augeas/src/put.c:665
    #10 0x7f4129667099 in lns_put /mnt/ram/augeas/src/put.c:860
    #11 0x7f4129621734 in lens_put /mnt/ram/augeas/src/builtin.c:225
    #12 0x7f41296069ed in native_call /mnt/ram/augeas/src/syntax.c:1046
    #13 0x7f412961131f in compile_exp /mnt/ram/augeas/src/syntax.c:1676
    #14 0x7f412960f692 in apply /mnt/ram/augeas/src/syntax.c:1589
    #15 0x7f4129611269 in compile_exp /mnt/ram/augeas/src/syntax.c:1672
    #16 0x7f4129611805 in compile_test /mnt/ram/augeas/src/syntax.c:1702
    #17 0x7f41296127af in compile_decl /mnt/ram/augeas/src/syntax.c:1783
    #18 0x7f41296129e7 in compile /mnt/ram/augeas/src/syntax.c:1798
    #19 0x7f4129615120 in load_module_file /mnt/ram/augeas/src/syntax.c:1980
    #20 0x7f41295d8ac3 in __aug_load_module_file /mnt/ram/augeas/src/augeas.c:2106
    #21 0x401853 in main /mnt/ram/augeas/src/augparse.c:136
    #22 0x7f4128c8f78f in __libc_start_main (/lib64/libc.so.6+0x2078f)
    #23 0x400e48 in _start (/mnt/ram/augeas/src/.libs/augparse+0x400e48)

0x6020001275d8 is located 6 bytes to the right of 2-byte region [0x6020001275d0,0x6020001275d2)
allocated by thread T0 here:
    #0 0x7f41299259af in malloc (/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/libasan.so.1+0x549af)
    #1 0x7f4128ced249 in strndup (/lib64/libc.so.6+0x7e249)
    #2 0x7f41296535c9 in token /mnt/ram/augeas/src/get.c:363
    #3 0x7f4129654c5a in parse_del /mnt/ram/augeas/src/get.c:518
    #4 0x7f412965fd15 in parse_lens /mnt/ram/augeas/src/get.c:1621
    #5 0x7f41296564c9 in parse_union /mnt/ram/augeas/src/get.c:626
    #6 0x7f412965fdfd in parse_lens /mnt/ram/augeas/src/get.c:1645
    #7 0x7f4129656f8d in parse_concat /mnt/ram/augeas/src/get.c:682
    #8 0x7f412965fddd in parse_lens /mnt/ram/augeas/src/get.c:1642
    #9 0x7f41296596bb in parse_subtree /mnt/ram/augeas/src/get.c:911
    #10 0x7f412965fe1d in parse_lens /mnt/ram/augeas/src/get.c:1648
    #11 0x7f41296564c9 in parse_union /mnt/ram/augeas/src/get.c:626
    #12 0x7f412965fdfd in parse_lens /mnt/ram/augeas/src/get.c:1645
    #13 0x7f412965855d in parse_quant_star /mnt/ram/augeas/src/get.c:823
    #14 0x7f412965fe3d in parse_lens /mnt/ram/augeas/src/get.c:1651
    #15 0x7f4129660324 in lns_parse /mnt/ram/augeas/src/get.c:1689
    #16 0x7f4129666fc6 in lns_put /mnt/ram/augeas/src/put.c:848
    #17 0x7f4129621734 in lens_put /mnt/ram/augeas/src/builtin.c:225
    #18 0x7f41296069ed in native_call /mnt/ram/augeas/src/syntax.c:1046
    #19 0x7f412961131f in compile_exp /mnt/ram/augeas/src/syntax.c:1676
    #20 0x7f412960f692 in apply /mnt/ram/augeas/src/syntax.c:1589
    #21 0x7f4129611269 in compile_exp /mnt/ram/augeas/src/syntax.c:1672
    #22 0x7f4129611805 in compile_test /mnt/ram/augeas/src/syntax.c:1702
    #23 0x7f41296127af in compile_decl /mnt/ram/augeas/src/syntax.c:1783
    #24 0x7f41296129e7 in compile /mnt/ram/augeas/src/syntax.c:1798
    #25 0x7f4129615120 in load_module_file /mnt/ram/augeas/src/syntax.c:1980
    #26 0x7f41295d8ac3 in __aug_load_module_file /mnt/ram/augeas/src/augeas.c:2106
    #27 0x401853 in main /mnt/ram/augeas/src/augparse.c:136
    #28 0x7f4128c8f78f in __libc_start_main (/lib64/libc.so.6+0x2078f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /mnt/ram/augeas/src/put.c:407 skel_instance_of
Shadow bytes around the buggy address:
  0x0c048001ce60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c048001ce70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c048001ce80: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c048001ce90: fa fa fd fa fa fa fd fa fa fa 03 fa fa fa fd fa
  0x0c048001cea0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa 04 fa
=>0x0c048001ceb0: fa fa 00 00 fa fa 03 fa fa fa 02[fa]fa fa 02 fa
  0x0c048001cec0: fa fa fd fd fa fa 07 fa fa fa 02 fa fa fa fd fd
  0x0c048001ced0: fa fa 07 fa fa fa 03 fa fa fa fd fd fa fa 00 fa
  0x0c048001cee0: fa fa 03 fa fa fa fd fd fa fa 05 fa fa fa 03 fa
  0x0c048001cef0: fa fa fd fd fa fa 05 fa fa fa 03 fa fa fa fd fd
  0x0c048001cf00: fa fa 05 fa fa fa 02 fa fa fa fd fd fa fa fd 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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Contiguous container OOB:fc
  ASan internal:           fe
==773==ABORTING
@lutter
Copy link
Member

lutter commented Aug 19, 2016

Nice catch .. I can also see this with valgrind now. I'll look into what's going on there.

lutter added a commit to lutter/augeas that referenced this issue Sep 25, 2016
We used to always access skel->skels; but that is only valid if the tag for
skel->skels is L_CONCAT or L_STAR. Because of this, we could, for example
access skel->skels for a skel tagged as L_DEL, which is illegal.

This patch adds a fix to the L_CONCAT case so that we only look at
skel->skels if the skel is tagged that way.

Fixes hercules-team#398
@lutter
Copy link
Member

lutter commented Sep 25, 2016

For posterity, here's a simpler test case that exposes this problem:

module Issue_398 =

  let comma   = del "," ","
  let optlabel = /[a-z]+/
  let optional = del "-" "-"

  let opt_list =
    let opt = [ label "opt" . store optlabel ] in
      opt . (comma . opt)*

  let lns = [ label "1" . (opt_list | optional) ]

  let s_in = "-"
  let s_out = "fg"

test lns get s_in = ?
test lns put s_in after
    set "/1/opt" "fg"  = s_out

Unfortunately, I don't know how to turn that into an actual test without requiring running all tests with address sanitizer, which is not fun, to say the least.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants