nixcloud/ip2unix

test_globpath unveils an out of range string_view read

etam opened this issue · 1 comments

etam commented

OS: openSUSE Tumbleweed

This started happening quite recently. There were no new releases of ip2unix, so something must have changed "below".

The failure looks like this:

/usr/include/c++/13/string_view:258: constexpr const std::basic_string_view<_CharT, _Traits>::value_type& std::basic_string_view<_CharT, _Traits>::operator[](size_type) const [with _CharT = char; _Traits = std::char_traits<char>; const_reference = const char&; size_type = long unsigned int]: Assertion '__pos < this->_M_len' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff78949ec in __pthread_kill_implementation () from /lib64/libc.so.6
Missing separate debuginfos, use: zypper install libgcc_s1-debuginfo-14.0.1+git9687-1.1.x86_64 libstdc++6-debuginfo-14.0.1+git9687-1.1.x86_64
(gdb) bt
#0  0x00007ffff78949ec in __pthread_kill_implementation () from /lib64/libc.so.6
#1  0x00007ffff7841176 in raise () from /lib64/libc.so.6
#2  0x00007ffff7828917 in abort () from /lib64/libc.so.6
#3  0x00007ffff7ce05e0 in std::__glibcxx_assert_fail(char const*, int, char const*, char const*) () from /lib64/libstdc++.so.6
#4  0x00005555555609a9 in std::basic_string_view<char, std::char_traits<char> >::operator[] (this=<optimized out>, __pos=<optimized out>) at /usr/include/c++/13/string_view:256
#5  std::basic_string_view<char, std::char_traits<char> >::operator[] (__pos=<optimized out>, this=<optimized out>) at /usr/include/c++/13/string_view:256
#6  GlobPath::match_norec (this=this@entry=0x7fffffffd320, pattern_pos=pattern_pos@entry=0x7fffffffd2d0, path_pos=path_pos@entry=0x7fffffffd2d8) at ../src/globpath.cc:157
#7  0x0000555555560bf9 in GlobPath::match (this=this@entry=0x7fffffffd320) at ../src/globpath.cc:268
#8  0x0000555555560d2a in globpath (pattern="*", path="") at ../src/globpath.cc:307
#9  0x000055555555d45f in main () at ../tests/unit/globpath.cc:84
(gdb) f 6
#6  GlobPath::match_norec (this=this@entry=0x7fffffffd320, pattern_pos=pattern_pos@entry=0x7fffffffd2d0, path_pos=path_pos@entry=0x7fffffffd2d8) at ../src/globpath.cc:157
(gdb) p this->pattern->_M_str
$7 = 0x7fffffffd390 "*"
(gdb) p this->pattern->_M_len
$8 = 1
(gdb) p patpos
$9 = 0

To reiterate:

  • this->pattern is a string_view to a string "*" with length 1.
  • patpos == 0
  • this->pattern[patpos] should return char '*', but instead assertion fails: Assertion '__pos < this->_M_len' failed

WAT?

etam commented

Now I get this! I compiled it with -Og, not -O2, so things are not optimized away.

https://github.com/nixcloud/ip2unix/blob/v2.2.1/src/globpath.cc#L156-L170

After patpos++; at line 169 the condition in for loop this->pattern[patpos] == '*' tries to read this->pattern[1], which is invalid.