From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 26EA6385700D; Sun, 5 Jun 2022 15:12:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 26EA6385700D From: "andysem at mail dot ru" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/105857] New: codecvt::do_length causes unexpected buffer overflow Date: Sun, 05 Jun 2022 15:12:18 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: 11.2.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: andysem at mail dot ru X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 05 Jun 2022 15:12:19 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D105857 Bug ID: 105857 Summary: codecvt::do_length causes unexpected buffer overflow Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: andysem at mail dot ru Target Milestone: --- Consider the following test case: #include #include const std::size_t max_size =3D 10u; const char text[] =3D " !\"#$%&'()*+,-./0123456789:;<=3D>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefg= hijklmnopqrstuvwxyz{|}~"; int main() { std::locale loc; std::codecvt< wchar_t, char, std::mbstate_t > const& fac =3D std::use_facet< std::codecvt< wchar_t, char, std::mbstate_t > >(loc= ); std::mbstate_t mbs =3D std::mbstate_t(); const char* from =3D text; const char* from_to =3D from + max_size; std::size_t max =3D ~static_cast< std::size_t >(0u); return static_cast< std::size_t >(fac.length(mbs, from, from_to, max)); } $ g++ -g2 -O0 -o codecvt_length_bug codecvt_length_bug.cpp Running this causes a crash with a buffer overflow: Program received signal SIGABRT, Aborted. __pthread_kill_implementation (no_tid=3D0, signo=3D6, threadid=3D1407373480= 11840) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: No such file or directory. (gdb) bt #0 __pthread_kill_implementation (no_tid=3D0, signo=3D6, threadid=3D140737= 348011840) at ./nptl/pthread_kill.c:44 #1 __pthread_kill_internal (signo=3D6, threadid=3D140737348011840) at ./nptl/pthread_kill.c:78 #2 __GI___pthread_kill (threadid=3D140737348011840, signo=3Dsigno@entry=3D= 6) at ./nptl/pthread_kill.c:89 #3 0x00007ffff7b56476 in __GI_raise (sig=3Dsig@entry=3D6) at ../sysdeps/posix/raise.c:26 #4 0x00007ffff7b3c7f3 in __GI_abort () at ./stdlib/abort.c:79 #5 0x00007ffff7b9d6f6 in __libc_message (action=3Daction@entry=3Ddo_abort, fmt=3Dfmt@entry=3D0x7ffff7cef943 "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:155 #6 0x00007ffff7c4a76a in __GI___fortify_fail (msg=3Dmsg@entry=3D0x7ffff7ce= f8e9 "buffer overflow detected") at ./debug/fortify_fail.c:26 #7 0x00007ffff7c490c6 in __GI___chk_fail () at ./debug/chk_fail.c:28 #8 0x00007ffff7c4a199 in __mbsnrtowcs_chk (dst=3D, src=3D, nmc=3D, len=3D, ps=3D, dstlen=3D) at ./debug/mbsnrtowcs_chk.c:27 #9 0x00007ffff7e290d2 in std::codecvt::do_length(__mbstate_t&, char const*, char const*, unsigned lo= ng) const () from /lib/x86_64-linux-gnu/libstdc++.so.6 #10 0x00005555555552d3 in std::__codecvt_abstract_base::length (this=3D0x7ffff7f86090, __state=3D..., __from=3D0x5555= 55556040 " !\"#$%&'()*+,-./0123456789:;<=3D>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefg= hijklmnopqrstuvwxyz{|}~",=20 __end=3D0x55555555604a "*+,-./0123456789:;<=3D>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnop= qrstuvwxyz{|}~", __max=3D18446744073709551615) at /usr/include/c++/11/bits/codecvt.h:219 #11 0x000055555555523d in main () at codecvt_length_bug.cpp:14 The problem appears to be that std::codecvt< wchar_t, char, std::mbstate_t >::do_length() accesses characters outside the [s, s + max_size) range, apparently using the ~static_cast< std::size_t >(0u) as the size limit. Thi= s is against the do_length() definition in the C++ standard, see [locale.codecvt.virtuals]/12-14 (http://eel.is/c++draft/locale.codecvt.virtuals#lib:codecvt,do_length): Effects: The effect on the state argument is as if it called do_=C2=ADin(st= ate, from, from_=C2=ADend, from, to, to+max, to) for to pointing to a buffer of = at least max elements. That is, max is only referred to as the size of the potential output buffer, and the source buffer is specified as [from, from_end). There is no require= ment for max to be within [from, from_end) bounds. If I change max to (sizeof(te= xt) - 1u) then the buffer overflow does not happen. (As to the purpose of this code, it is supposed to calculate the size, in bytes, of the initial sequence of complete characters not larger than max_size.) $ g++ -v Using built-in specs. COLLECT_GCC=3Dg++ COLLECT_LTO_WRAPPER=3D/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper OFFLOAD_TARGET_NAMES=3Dnvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT=3D1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion=3D'Ubuntu 11.2.0-19ubuntu1' --with-bugurl=3Dfile:///usr/share/doc/gcc-11/README.Bugs --enable-languages=3Dc,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix= =3D/usr --with-gcc-major-version-only --program-suffix=3D-11 --program-prefix=3Dx86_64-linux-gnu- --enable-shared --enable-linker-build-= id --libexecdir=3D/usr/lib --without-included-gettext --enable-threads=3Dposix --libdir=3D/usr/lib --enable-nls --enable-bootstrap --enable-clocale=3Dgnu --enable-libstdcxx-debug --enable-libstdcxx-time=3Dyes --with-default-libstdcxx-abi=3Dnew --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-= zlib --enable-libphobos-checking=3Drelease --with-target-system-zlib=3Dauto --enable-objc-gc=3Dauto --enable-multiarch --disable-werror --enable-cet --with-arch-32=3Di686 --with-abi=3Dm64 --with-multilib-list=3Dm32,m64,mx32 --enable-multilib --with-tune=3Dgeneric --enable-offload-targets=3Dnvptx-none=3D/build/gcc-11-gBFGDP/gcc-11-11.2.0/= debian/tmp-nvptx/usr,amdgcn-amdhsa=3D/build/gcc-11-gBFGDP/gcc-11-11.2.0/deb= ian/tmp-gcn/usr --without-cuda-driver --enable-checking=3Drelease --build=3Dx86_64-linux-gnu --host=3Dx86_64-linux-gnu --target=3Dx86_64-linux-gnu --with-build-config=3Dbootstrap-lto-lean --enable-link-serialization=3D2 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 11.2.0 (Ubuntu 11.2.0-19ubuntu1)=