public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/105387] New: libstdc++: with -fno-rtti, pointer type info class incorrectly matches non-pointer type info classes
@ 2022-04-26  8:58 jakob2811 at hotmail dot de
  2022-04-26  9:03 ` [Bug c++/105387] " rguenth at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: jakob2811 at hotmail dot de @ 2022-04-26  8:58 UTC (permalink / raw)
  To: gcc-bugs

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)

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-11-05 14:05 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-26  8:58 [Bug c++/105387] New: libstdc++: with -fno-rtti, pointer type info class incorrectly matches non-pointer type info classes jakob2811 at hotmail dot de
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

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).