Skip to content

Add assert to local_bitvector_analysis.cpp #838

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

Merged
merged 1 commit into from
May 20, 2017

Conversation

reuk
Copy link
Contributor

@reuk reuk commented Apr 18, 2017

When running the linked program
(thanks @mgudemann for the test case) with cbmc under address-sanitizer, we get the following error:

Reading GOTO program from file
Reading: /home/reuben/Downloads/more crashes/crashes/id:000118,sig:04,src:000006,op:arith8,pos:5884,val:-3
Generating GOTO Program
Adding CPROVER library (x86_64)
Removal of function pointers and virtual functions
Partial Inlining
Generic Property Instrumentation
=================================================================
==6360==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000009b70 at pc 0x000001004d5d bp 0x7ffceb271700 sp 0x7ffceb2716f8
READ of size 8 at 0x603000009b70 thread T0
    #0 0x1004d5c in std::vector<local_bitvector_analysist::flagst, std::allocator<local_bitvector_analysist::flagst> >::size() const /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_vector.h:655:40
    #1 0x100113c in local_bitvector_analysist::loc_infot::merge(local_bitvector_analysist::loc_infot const&) /home/reuben/development/cbmc/src/analyses/local_bitvector_analysis.cpp:70:36
    #2 0x10042e4 in local_bitvector_analysist::build(goto_function_templatet<goto_programt> const&) /home/reuben/development/cbmc/src/analyses/local_bitvector_analysis.cpp:403:10
    #3 0xff7e93 in local_bitvector_analysist::local_bitvector_analysist(goto_function_templatet<goto_programt> const&) /home/reuben/development/cbmc/src/analyses/./local_bitvector_analysis.h:39:5
    #4 0xff40e8 in goto_checkt::goto_check(goto_function_templatet<goto_programt>&, dstringt const&) /home/reuben/development/cbmc/src/analyses/goto_check.cpp:1593:29
    #5 0xff74db in goto_check(namespacet const&, optionst const&, goto_functionst&) /home/reuben/development/cbmc/src/analyses/goto_check.cpp:1883:5
    #6 0x81415b in cbmc_parse_optionst::process_goto_program(optionst const&, goto_functionst&) /home/reuben/development/cbmc/src/cbmc/cbmc_parse_options.cpp:907:5
    #7 0x813455 in cbmc_parse_optionst::get_goto_program(optionst const&, bmct&, goto_functionst&) /home/reuben/development/cbmc/src/cbmc/cbmc_parse_options.cpp:737:8
    #8 0x810928 in cbmc_parse_optionst::doit() /home/reuben/development/cbmc/src/cbmc/cbmc_parse_options.cpp:534:5
    #9 0x127792c in parse_options_baset::main() /home/reuben/development/cbmc/src/util/parse_options.cpp:104:10
    #10 0x808240 in main /home/reuben/development/cbmc/src/cbmc/cbmc_main.cpp:53:11
    #11 0x7f66e2da782f in __libc_start_main /build/glibc-9tT8Do/glibc-2.23/csu/../csu/libc-start.c:291
    #12 0x4248c8 in _start (/home/reuben/development/cbmc/src/cbmc/cbmc+0x4248c8)

0x603000009b70 is located 8 bytes to the right of 24-byte region [0x603000009b50,0x603000009b68)
allocated by thread T0 here:
    #0 0x4f5fc0 in operator new(unsigned long) (/home/reuben/development/cbmc/src/cbmc/cbmc+0x4f5fc0)
    #1 0x100fd79 in __gnu_cxx::new_allocator<local_bitvector_analysist::loc_infot>::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/ext/new_allocator.h:104:27
    #2 0xff7e93 in local_bitvector_analysist::local_bitvector_analysist(goto_function_templatet<goto_programt> const&) /home/reuben/development/cbmc/src/analyses/./local_bitvector_analysis.h:39:5
    #3 0xff74db in goto_check(namespacet const&, optionst const&, goto_functionst&) /home/reuben/development/cbmc/src/analyses/goto_check.cpp:1883:5
    #4 0x81415b in cbmc_parse_optionst::process_goto_program(optionst const&, goto_functionst&) /home/reuben/development/cbmc/src/cbmc/cbmc_parse_options.cpp:907:5
    #5 0x813455 in cbmc_parse_optionst::get_goto_program(optionst const&, bmct&, goto_functionst&) /home/reuben/development/cbmc/src/cbmc/cbmc_parse_options.cpp:737:8
    #6 0x810928 in cbmc_parse_optionst::doit() /home/reuben/development/cbmc/src/cbmc/cbmc_parse_options.cpp:534:5
    #7 0x127792c in parse_options_baset::main() /home/reuben/development/cbmc/src/util/parse_options.cpp:104:10
    #8 0x7f66e2da782f in __libc_start_main /build/glibc-9tT8Do/glibc-2.23/csu/../csu/libc-start.c:291

SUMMARY: AddressSanitizer: heap-buffer-overflow /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_vector.h:655:40 in std::vector<local_bitvector_analysist::flagst, std::allocator<local_bitvector_analysist::flagst> >::size() const
Shadow bytes around the buggy address:
  0x0c067fff9310: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9320: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9330: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9340: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9350: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c067fff9360: fa fa fa fa fa fa fa fa fa fa 00 00 00 fa[fa]fa
  0x0c067fff9370: 00 00 00 00 fa fa fd fd fd fa fa fa fd fd fd fa
  0x0c067fff9380: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd
  0x0c067fff9390: fd fa fa fa fd fd fd fa fa fa fd fd fd fa fa fa
  0x0c067fff93a0: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd fa
  0x0c067fff93b0: fa fa fd fd fd fa fa fa fd fd fd fa fa fa 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
  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
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==6360==ABORTING

After applying this patch, we instead trigger the new assertion:

Reading GOTO program from file
Reading: /home/reuben/Downloads/more crashes/crashes/id:000118,sig:04,src:000006,op:arith8,pos:5884,val:-3
Generating GOTO Program
Adding CPROVER library (x86_64)
Removal of function pointers and virtual functions
Partial Inlining
Generic Property Instrumentation
cbmc: local_bitvector_analysis.cpp:403: void local_bitvector_analysist::build(const goto_functiont &): Assertion `succ<loc_infos.size()' failed.

Though I think it's probably a good idea to add this assert to avoid memory corrpution, there may be a better fix that avoids triggering this assertion altogether. Could @tautschnig or @kroening advise?

@tautschnig
Copy link
Collaborator

Happy to debug this - what command line should I be using with CBMC on that program?

@reuk
Copy link
Contributor Author

reuk commented Apr 18, 2017

No arguments whatsoever - just cbmc <the test case>

@tautschnig
Copy link
Collaborator

The change is a good one, but the bug appears to lie in the input program. It has a goto_programt with just a call to __CPROVER_initialize() but no END_FUNCTION. You might review how you've come up with this input.

@reuk
Copy link
Contributor Author

reuk commented Apr 18, 2017

It was generated by a fuzzer. Even ill-formed inputs should not cause the program to attempt to read invalid memory.

@tautschnig
Copy link
Collaborator

Yes, I do agree with that, but really we should have #751 addressed. Ideally we would precisely document which parts of the code base assume consistent goto programs.

@reuk
Copy link
Contributor Author

reuk commented Apr 19, 2017

A good way to do that is to use the type system. Have a type which represents/holds a goto-program in an inconsistent state, and some other classes which represent goto-programs for which specific invariants hold. The constructors for these classes can take the 'inconsistent state' program, and throw an exception if the program cannot be made consistent. This way, modules which use goto programs can specify the invariants that should hold simply by using one of the specialised goto program types in their interfaces. This is safer, more self-documenting, and simpler than having a single goto-program type which has to maintain several different sets of invariants. Of course, this only works if we also make the goto-program data private, and restrict the goto-program interface such that any modifications maintain the current set of invariants.

@tautschnig
Copy link
Collaborator

Yes, types are a possible solution. But I'd argue that rewriting pretty much the entire code base to work with this different approach of encoding is not the most customer-focused way of spending time. There are many areas which would provide a lot better value. Hence I'd argue for doing a rather simple hack of adding invariant checks with goto_programt, goto_functionst, and goto_modelt.

@martin-cs
Copy link
Collaborator

martin-cs commented May 2, 2017 via email

@martin-cs
Copy link
Collaborator

martin-cs commented May 2, 2017 via email

@kroening kroening merged commit 588ed05 into diffblue:master May 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants