Menu

Heap UAF in lib/token.cpp:1934

2023-07-19
2023-10-11
  • Tamagawa Takeshi

    Description

    Heap UAF in lib/token.cpp:1934

    Version

    ➜  bin git:(main) ./cppcheck --version
    Cppcheck 2.12 dev
    commit d2546d525273c45dfc3bab946e8893b69bb5a542
    

    Replay

    git clone https://github.com/danmar/cppcheck.git
    cd cppcheck
    mkdir build
    cd build
    CC="gcc -fsanitize=address" CXX="g++ -fsanitize=address" cmake ..
    cmake --build . -j
    ./cppcheck poc
    

    POC

    poc

    ASAN

    Checking poc ...
    =================================================================
    ==1896786==ERROR: AddressSanitizer: heap-use-after-free on address 0x612000008450 at pc 0x555555f66ffa bp 0x7ffffffe63a0 sp 0x7ffffffe6390
    READ of size 4 at 0x612000008450 thread T0
        #0 0x555555f66ff9 in ValueFlow::Value::equalValue(ValueFlow::Value const&) const  cppcheck/lib/vfvalue.h:74
        #1 0x55555688db00 in ValueFlow::Value::operator==(ValueFlow::Value const&) const  cppcheck/lib/vfvalue.h:163
        #2 0x5555568919b4 in std::__debug::list<ValueFlow::Value, std::allocator<ValueFlow::Value> >::remove(ValueFlow::Value const&) /usr/include/c++/7/debug/list:649
        #3 0x555556867324 in removeContradiction  cppcheck/lib/token.cpp:1934
        #4 0x555556869d41 in removeContradictions  cppcheck/lib/token.cpp:2068
        #5 0x55555686b23c in Token::addValue(ValueFlow::Value const&)  cppcheck/lib/token.cpp:2158
        #6 0x5555569bed52 in setTokenValue  cppcheck/lib/valueflow.cpp:624
        #7 0x5555569c224a in setTokenValue  cppcheck/lib/valueflow.cpp:769
        #8 0x5555569dab6d in valueFlowImpossibleValues  cppcheck/lib/valueflow.cpp:1853
        #9 0x555556a3f76e in operator()  cppcheck/lib/valueflow.cpp:9466
        #10 0x555556a901c5 in run  cppcheck/lib/valueflow.cpp:9405
        #11 0x555556ac313d in ValueFlowPassRunner::run(ValuePtr<ValueFlowPass> const&) const  cppcheck/lib/valueflow.cpp:9333
        #12 0x555556ac2200 in ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}::operator()(ValuePtr<ValueFlowPass> const&) const  cppcheck/lib/valueflow.cpp:9302
        #13 0x555556b7949a in bool __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>::operator()<ValuePtr<ValueFlowPass> const*>(ValuePtr<ValueFlowPass> const*) /usr/include/c++/7/bits/predefined_ops.h:283
        #14 0x555556b6df18 in ValuePtr<ValueFlowPass> const* std::__find_if<ValuePtr<ValueFlowPass> const*, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}> >(__gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, std::random_access_iterator_tag) /usr/include/c++/7/bits/stl_algo.h:120
        #15 0x555556b5985d in ValuePtr<ValueFlowPass> const* std::__find_if<ValuePtr<ValueFlowPass> const*, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}> >(__gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>) /usr/include/c++/7/bits/stl_algo.h:162
        #16 0x555556b3907f in ValuePtr<ValueFlowPass> const* std::find_if<ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>(ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}) /usr/include/c++/7/bits/stl_algo.h:3933
        #17 0x555556b0f2e2 in bool std::none_of<ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>(ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}) /usr/include/c++/7/bits/stl_algo.h:526
        #18 0x555556ae8bb3 in bool std::any_of<ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>(ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}) /usr/include/c++/7/bits/stl_algo.h:544
        #19 0x555556ac2475 in ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const  cppcheck/lib/valueflow.cpp:9300
        #20 0x555556a437fb in ValueFlow::setValues(TokenList*, SymbolDatabase*, ErrorLogger*, Settings const*, TimerResultsIntf*)  cppcheck/lib/valueflow.cpp:9465
        #21 0x5555568cafcd in Tokenizer::simplifyTokens1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)  cppcheck/lib/tokenize.cpp:3365
        #22 0x5555563e6c28 in CppCheck::checkFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)  cppcheck/lib/cppcheck.cpp:908
        #23 0x5555563dddd8 in CppCheck::check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)  cppcheck/lib/cppcheck.cpp:590
        #24 0x555555f071ce in SingleExecutor::check()  cppcheck/cli/singleexecutor.cpp:60
        #25 0x555555e7c1fd in CppCheckExecutor::check_internal(CppCheck&)  cppcheck/cli/cppcheckexecutor.cpp:289
        #26 0x555555e7b04b in CppCheckExecutor::check(int, char const* const*)  cppcheck/cli/cppcheckexecutor.cpp:223
        #27 0x555555e426e1 in main  cppcheck/cli/main.cpp:91
        #28 0x7ffff6cbd082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
        #29 0x555555e4253d in _start ( cppcheck/build/bin/cppcheck+0x8ee53d)
    
    0x612000008450 is located 16 bytes inside of 272-byte region [0x612000008440,0x612000008550)
    freed by thread T0 here:
        #0 0x7ffff72dc0d0 in operator delete(void*) (/lib/x86_64-linux-gnu/libasan.so.4+0xe20d0)
        #1 0x55555650ae2f in __gnu_cxx::new_allocator<std::__cxx1998::_List_node<ValueFlow::Value> >::deallocate(std::__cxx1998::_List_node<ValueFlow::Value>*, unsigned long) /usr/include/c++/7/ext/new_allocator.h:125
        #2 0x555556505705 in std::allocator_traits<std::allocator<std::__cxx1998::_List_node<ValueFlow::Value> > >::deallocate(std::allocator<std::__cxx1998::_List_node<ValueFlow::Value> >&, std::__cxx1998::_List_node<ValueFlow::Value>*, unsigned long) /usr/include/c++/7/bits/alloc_traits.h:462
        #3 0x5555564fe723 in std::__cxx1998::__cxx11::_List_base<ValueFlow::Value, std::allocator<ValueFlow::Value> >::_M_put_node(std::__cxx1998::_List_node<ValueFlow::Value>*) /usr/include/c++/7/bits/stl_list.h:387
        #4 0x555556505578 in std::__cxx1998::__cxx11::list<ValueFlow::Value, std::allocator<ValueFlow::Value> >::_M_erase(std::__cxx1998::_List_iterator<ValueFlow::Value>) /usr/include/c++/7/bits/stl_list.h:1820
        #5 0x5555564fe649 in std::__cxx1998::__cxx11::list<ValueFlow::Value, std::allocator<ValueFlow::Value> >::erase(std::__cxx1998::_List_const_iterator<ValueFlow::Value>) /usr/include/c++/7/bits/list.tcc:157
        #6 0x5555564f4f16 in std::__debug::list<ValueFlow::Value, std::allocator<ValueFlow::Value> >::_M_erase(std::__cxx1998::_List_const_iterator<ValueFlow::Value>) /usr/include/c++/7/debug/list:491
        #7 0x555556891a3e in std::__debug::list<ValueFlow::Value, std::allocator<ValueFlow::Value> >::remove(ValueFlow::Value const&) /usr/include/c++/7/debug/list:650
        #8 0x555556867324 in removeContradiction  cppcheck/lib/token.cpp:1934
        #9 0x555556869d41 in removeContradictions  cppcheck/lib/token.cpp:2068
        #10 0x55555686b23c in Token::addValue(ValueFlow::Value const&)  cppcheck/lib/token.cpp:2158
        #11 0x5555569bed52 in setTokenValue  cppcheck/lib/valueflow.cpp:624
        #12 0x5555569c224a in setTokenValue  cppcheck/lib/valueflow.cpp:769
        #13 0x5555569dab6d in valueFlowImpossibleValues  cppcheck/lib/valueflow.cpp:1853
        #14 0x555556a3f76e in operator()  cppcheck/lib/valueflow.cpp:9466
        #15 0x555556a901c5 in run  cppcheck/lib/valueflow.cpp:9405
        #16 0x555556ac313d in ValueFlowPassRunner::run(ValuePtr<ValueFlowPass> const&) const  cppcheck/lib/valueflow.cpp:9333
        #17 0x555556ac2200 in ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}::operator()(ValuePtr<ValueFlowPass> const&) const  cppcheck/lib/valueflow.cpp:9302
        #18 0x555556b7949a in bool __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>::operator()<ValuePtr<ValueFlowPass> const*>(ValuePtr<ValueFlowPass> const*) /usr/include/c++/7/bits/predefined_ops.h:283
        #19 0x555556b6df18 in ValuePtr<ValueFlowPass> const* std::__find_if<ValuePtr<ValueFlowPass> const*, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}> >(__gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, std::random_access_iterator_tag) /usr/include/c++/7/bits/stl_algo.h:120
        #20 0x555556b5985d in ValuePtr<ValueFlowPass> const* std::__find_if<ValuePtr<ValueFlowPass> const*, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}> >(__gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>) /usr/include/c++/7/bits/stl_algo.h:162
        #21 0x555556b3907f in ValuePtr<ValueFlowPass> const* std::find_if<ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>(ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}) /usr/include/c++/7/bits/stl_algo.h:3933
        #22 0x555556b0f2e2 in bool std::none_of<ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>(ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}) /usr/include/c++/7/bits/stl_algo.h:526
        #23 0x555556ae8bb3 in bool std::any_of<ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>(ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}) /usr/include/c++/7/bits/stl_algo.h:544
        #24 0x555556ac2475 in ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const  cppcheck/lib/valueflow.cpp:9300
        #25 0x555556a437fb in ValueFlow::setValues(TokenList*, SymbolDatabase*, ErrorLogger*, Settings const*, TimerResultsIntf*)  cppcheck/lib/valueflow.cpp:9465
        #26 0x5555568cafcd in Tokenizer::simplifyTokens1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)  cppcheck/lib/tokenize.cpp:3365
        #27 0x5555563e6c28 in CppCheck::checkFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)  cppcheck/lib/cppcheck.cpp:908
        #28 0x5555563dddd8 in CppCheck::check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)  cppcheck/lib/cppcheck.cpp:590
        #29 0x555555f071ce in SingleExecutor::check()  cppcheck/cli/singleexecutor.cpp:60
    
    previously allocated by thread T0 here:
        #0 0x7ffff72db258 in operator new(unsigned long) (/lib/x86_64-linux-gnu/libasan.so.4+0xe1258)
        #1 0x555556514674 in __gnu_cxx::new_allocator<std::__cxx1998::_List_node<ValueFlow::Value> >::allocate(unsigned long, void const*) /usr/include/c++/7/ext/new_allocator.h:111
        #2 0x555556512b12 in std::allocator_traits<std::allocator<std::__cxx1998::_List_node<ValueFlow::Value> > >::allocate(std::allocator<std::__cxx1998::_List_node<ValueFlow::Value> >&, unsigned long) /usr/include/c++/7/bits/alloc_traits.h:436
        #3 0x5555565118c6 in std::__cxx1998::__cxx11::_List_base<ValueFlow::Value, std::allocator<ValueFlow::Value> >::_M_get_node() /usr/include/c++/7/bits/stl_list.h:383
        #4 0x55555689bc73 in std::__cxx1998::_List_node<ValueFlow::Value>* std::__cxx1998::__cxx11::list<ValueFlow::Value, std::allocator<ValueFlow::Value> >::_M_create_node<ValueFlow::Value>(ValueFlow::Value&&) /usr/include/c++/7/bits/stl_list.h:572
        #5 0x555556897a8b in void std::__cxx1998::__cxx11::list<ValueFlow::Value, std::allocator<ValueFlow::Value> >::_M_insert<ValueFlow::Value>(std::__cxx1998::_List_iterator<ValueFlow::Value>, ValueFlow::Value&&) /usr/include/c++/7/bits/stl_list.h:1801
        #6 0x555556893a56 in std::__cxx1998::__cxx11::list<ValueFlow::Value, std::allocator<ValueFlow::Value> >::push_back(ValueFlow::Value&&) /usr/include/c++/7/bits/stl_list.h:1123
        #7 0x55555686af12 in Token::addValue(ValueFlow::Value const&)  cppcheck/lib/token.cpp:2148
        #8 0x5555569bed52 in setTokenValue  cppcheck/lib/valueflow.cpp:624
        #9 0x5555569c224a in setTokenValue  cppcheck/lib/valueflow.cpp:769
        #10 0x5555569d77d5 in valueFlowBitAnd  cppcheck/lib/valueflow.cpp:1649
        #11 0x555556a3f6c6 in operator()  cppcheck/lib/valueflow.cpp:9460
        #12 0x555556a905eb in run  cppcheck/lib/valueflow.cpp:9405
        #13 0x555556ac313d in ValueFlowPassRunner::run(ValuePtr<ValueFlowPass> const&) const  cppcheck/lib/valueflow.cpp:9333
        #14 0x555556ac20e8 in ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}::operator()(ValuePtr<ValueFlowPass> const&) const  cppcheck/lib/valueflow.cpp:9291
        #15 0x555556b79474 in bool __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>::operator()<ValuePtr<ValueFlowPass> const*>(ValuePtr<ValueFlowPass> const*) /usr/include/c++/7/bits/predefined_ops.h:283
        #16 0x555556b6ddf7 in ValuePtr<ValueFlowPass> const* std::__find_if<ValuePtr<ValueFlowPass> const*, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}> >(__gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, std::random_access_iterator_tag) /usr/include/c++/7/bits/stl_algo.h:140
        #17 0x555556b595fe in ValuePtr<ValueFlowPass> const* std::__find_if<ValuePtr<ValueFlowPass> const*, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}> >(__gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>) /usr/include/c++/7/bits/stl_algo.h:162
        #18 0x555556b38fc7 in ValuePtr<ValueFlowPass> const* std::find_if<ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>(ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}) /usr/include/c++/7/bits/stl_algo.h:3933
        #19 0x555556b0f2ae in bool std::none_of<ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>(ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}) /usr/include/c++/7/bits/stl_algo.h:526
        #20 0x555556ae8b83 in bool std::any_of<ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>(ValuePtr<ValueFlowPass> const*, ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}, ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}) /usr/include/c++/7/bits/stl_algo.h:544
        #21 0x555556ac21b0 in ValueFlowPassRunner::run_once(std::initializer_list<ValuePtr<ValueFlowPass> >) const  cppcheck/lib/valueflow.cpp:9291
        #22 0x555556a41ce9 in ValueFlow::setValues(TokenList*, SymbolDatabase*, ErrorLogger*, Settings const*, TimerResultsIntf*)  cppcheck/lib/valueflow.cpp:9447
        #23 0x5555568cafcd in Tokenizer::simplifyTokens1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)  cppcheck/lib/tokenize.cpp:3365
        #24 0x5555563e6c28 in CppCheck::checkFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)  cppcheck/lib/cppcheck.cpp:908
        #25 0x5555563dddd8 in CppCheck::check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)  cppcheck/lib/cppcheck.cpp:590
        #26 0x555555f071ce in SingleExecutor::check()  cppcheck/cli/singleexecutor.cpp:60
        #27 0x555555e7c1fd in CppCheckExecutor::check_internal(CppCheck&)  cppcheck/cli/cppcheckexecutor.cpp:289
        #28 0x555555e7b04b in CppCheckExecutor::check(int, char const* const*)  cppcheck/cli/cppcheckexecutor.cpp:223
        #29 0x555555e426e1 in main  cppcheck/cli/main.cpp:91
    
    SUMMARY: AddressSanitizer: heap-use-after-free  cppcheck/lib/vfvalue.h:74 in ValueFlow::Value::equalValue(ValueFlow::Value const&) const
    

    Environment

    Linux server 5.4.0-153-generic #170-Ubuntu SMP Fri Jun 16 13:43:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
    gcc (Ubuntu 7.5.0-6ubuntu2) 7.5.0
    
     

    Last edit: Tamagawa Takeshi 2023-07-19
  • CHR

    CHR - 2023-07-19
    8&88888tdio:h>
    Jint m
    

    That is clearly invalid code. Cppcheck generally assumes that its input is compileable.

     
    • Tamagawa Takeshi

      Perhaps it can be considered that the poc I provided is unexpected input, which exposes a flaw in cppcheck. Maybe in the next version, cppcheck should reject this type of input.

       
    • Siddhesh Poyarekar

      This has been inexplicably reported as a security issue and has a CVE number assigned. Maybe cppcheck should consider adding a security policy document that describes what could conceivably be considered a security issue so that such useless CVEs don't waste everyone's time. I had contributed a security policy here for yasm, which could be adapted for cppcheck:

      https://github.com/yasm/yasm/blob/master/SECURITY.md

       
      • Daniel Marjamäki

        what could conceivably be considered a security issue

        I don't consider bugs to be security issues. Cppcheck is a developer tool purely for "internal" usage. I expect that it runs in a safe and trusted environment.

         
        👍
        1

        Last edit: Daniel Marjamäki 2023-09-13
      • Daniel Marjamäki

        ok adding a SECURITY.md document similar to that is probably a good idea. If that avoids that people waste time on such reports.

         
  • Daniel Marjamäki

    Sadly.. if you are concerned about cppcheck crashes when the input is garbage, then you should run your compiler first on all the input to ensure that it's not garbage.

    Implementing a full syntax checker in Cppcheck would take a lot of time. Especially since we want to allow compiler extensions. We just don't have the resources to do that.

     
    • Daniel Marjamäki

      Implementing a full syntax checker in Cppcheck would take a lot of time.

      the problem is that all compilers have different syntax checks due to various language extensions.

      writing a syntax checker that matches all the compilers.. I envision that we could spend 100% of our time for years.. and in practice that would have no value at all for users, they could just run their compiler instead.

       
  • CHR

    CHR - 2023-09-13

    Also, having strict syntax checking is in conflict with the aim of handling incomplete code.

     

Log in to post a comment.