public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
From: "jakob2811 at hotmail dot de" <gcc-bugzilla@gcc.gnu.org> To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/105387] New: libstdc++: with -fno-rtti, pointer type info class incorrectly matches non-pointer type info classes Date: Tue, 26 Apr 2022 08:58:57 +0000 [thread overview] Message-ID: <bug-105387-4@http.gcc.gnu.org/bugzilla/> (raw) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105387 Bug ID: 105387 Summary: libstdc++: with -fno-rtti, pointer type info class incorrectly matches non-pointer type info classes Product: gcc Version: unknown Status: UNCONFIRMED Keywords: EH Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: jakob2811 at hotmail dot de Target Milestone: --- Host: x86_64-linux-gnu (Ubuntu 20, Ubuntu 22) Target: x86_64-linux-gnu, xtensa Build: x86_64-linux-gnu Created attachment 52879 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52879&action=edit Patch which adds a check if the type info object is a pointer type We observed a potential misbehavior in libstdc++'s libsupc++: When compiled with exceptions but without RTTI, we see undefined behavior because a "normal" type info object is incorrectly casted to a pointer type info object. The problem occurs if there's a catch statement for a pointer type and an exception with a non-pointer type is thrown like in the following code sample code: #include <cstdio> #include <stdexcept> int main(int argc, char** argv) { try { throw std::runtime_error("test runtime error"); } catch (const char *e) { printf("~~~~~ cought outer exception char * %s ~~~~\n", e); } catch (const std::exception &e) { printf("~~~~~ cought outer exception %s ~~~~\n", e.what()); } } On Linux, we built it with: /path/to/g++ test_linux.cpp -o test_linux, then ran it. Execution will eventually reach __pbase_type_info::__do_catch() in libstdc++-v3/libsupc++/pbase_type_info.cc. Inside that function, the type info object of the exception (const type_info *), will be wrongly casted into a pointer type info object (const __pbase_type_info *). The latter has additional members of which __pbase_type_info::__flags will also be evaluated in __pbase_type_info::__do_catch(). This may lead to a direct access fault or a plain return false from the function (in which case nothing happens and the program continues without issue) or a call of __pbase_type_info::__pointer_catch() which most likely fails due to evaluation of undefined members. It looks as if __pbase_type_info::__do_catch() is made to handle both pointer and non-pointer type info objects, since the calling function get_adjusted_ptr() in libstdc++-v3/libsupc++/eh_personality.cc also checks if the type info object is a pointer type and later calls type_info::__do_catch() with that very object as parameter. We observed this in gcc 8.4.0 for Xtensa as well as in gcc 11.2.0 for x86_64 Linux, please refer to the last section for detailed compiler configurations. I debugged the sample code above on Xtensa, that's how I gained all the knowledge described above. On Linux, I wasn't able to setup a gdb with the modified libstdc++, so I couldn't debug it properly. But I did run the sample code with the -fno-rtti version of the libstdc++ and the program produced a segfault. When I later applied the attached fix to the compiler, the program ran normally with the locally built libstdc++ with -fno-rtti. If confirmed, I would like to create a proper patch but I don't know how I can create a test case that reliably fails on an undefined variable. On Xtensa with our configuration, __pbase_type_info->__flags of the wrongly casted pointer is in fact a vtable pointer and the issue will not appear in many cases. On Linux, the sample code always produced a segfault, though. I furthermore don't know if the added check in the patch should be switched off if RTTI is active. I haven't analyzed the additional RTTI-related code. GCC configurations of the tested compilers: $ xtensa-esp32-elf-gcc -v Using built-in specs. COLLECT_GCC=xtensa-esp32-elf-gcc COLLECT_LTO_WRAPPER=/home/jakob/.espressif/tools/xtensa-esp32-elf/esp-2021r2-patch3-8.4.0/xtensa-esp32-elf/bin/../libexec/gcc/xtensa-esp32-elf/8.4.0/lto-wrapper Target: xtensa-esp32-elf Configured with: /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-build_pc-linux-gnu --target=xtensa-esp32-elf --prefix=/builds/idf/crosstool-NG/builds/xtensa-esp32-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/xtensa-esp32-elf/xtensa-esp32-elf --with-headers=/builds/idf/crosstool-NG/builds/xtensa-esp32-elf/xtensa-esp32-elf/include --with-newlib --enable-threads=no --disable-shared --with-pkgversion='crosstool-NG esp-2021r2-patch3' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --with-gmp=/builds/idf/crosstool-NG/.build/xtensa-esp32-elf/buildtools --with-mpfr=/builds/idf/crosstool-NG/.build/xtensa-esp32-elf/buildtools --with-mpc=/builds/idf/crosstool-NG/.build/xtensa-esp32-elf/buildtools --with-isl=/builds/idf/crosstool-NG/.build/xtensa-esp32-elf/buildtools --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes Thread model: posix gcc version 8.4.0 (crosstool-NG esp-2021r2-patch3) $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/11.2.0/lto-wrapper Target: x86_64-linux-gnu Configured with: ../configure -prefix=/usr --enable-languages=c,c++ --enable-multiarch --host=x86_64-linux-gnu --build=x86_64-linux-gnu --target=x86_64-linux-gnu --enable-cxx-flags=-fno-rtti Thread model: posix Supported LTO compression algorithms: zlib gcc version 11.2.0 (GCC)
next reply other threads:[~2022-04-26 8:58 UTC|newest] Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-04-26 8:58 jakob2811 at hotmail dot de [this message] 2022-04-26 9:03 ` [Bug c++/105387] " rguenth at gcc dot gnu.org 2022-04-26 9:07 ` jakub at gcc dot gnu.org 2022-04-28 1:57 ` [Bug libstdc++/105387] " jakob2811 at hotmail dot de 2022-05-04 22:18 ` redi at gcc dot gnu.org 2022-11-05 14:03 ` cvs-commit at gcc dot gnu.org 2022-11-05 14:05 ` redi at gcc dot gnu.org
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=bug-105387-4@http.gcc.gnu.org/bugzilla/ \ --to=gcc-bugzilla@gcc.gnu.org \ --cc=gcc-bugs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).