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

* [Bug c++/105387] libstdc++: with -fno-rtti, pointer type info class incorrectly matches non-pointer type info classes
  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 ` rguenth at gcc dot gnu.org
  2022-04-26  9:07 ` jakub at gcc dot gnu.org
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-04-26  9:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105387

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Thanks for the detailed report and the fix - can you please send the fix to
gcc-patches@gcc.gnu.org and look at https://gcc.gnu.org/contribute.html for
prerequesites to accepting the fix?

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

* [Bug c++/105387] libstdc++: with -fno-rtti, pointer type info class incorrectly matches non-pointer type info classes
  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
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-04-26  9:07 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105387

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Note, libstdc++ patches should be sent to libstdc++@gcc.gnu.org, rest applies.

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

* [Bug libstdc++/105387] libstdc++: with -fno-rtti, pointer type info class incorrectly matches non-pointer type info classes
  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 ` jakob2811 at hotmail dot de
  2022-05-04 22:18 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: jakob2811 at hotmail dot de @ 2022-04-28  1:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105387

--- Comment #3 from Jakob Hasse <jakob2811 at hotmail dot de> ---
Thanks for the kind feedback!

I think I do have a test case now, using placement new to control the memory
adjacent to the type object. My patch seems to fix it. Right now I'm working on
integrating it into the test suite.

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

* [Bug libstdc++/105387] libstdc++: with -fno-rtti, pointer type info class incorrectly matches non-pointer type info classes
  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
                   ` (2 preceding siblings ...)
  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
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2022-05-04 22:18 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105387

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2022-05-04

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

* [Bug libstdc++/105387] libstdc++: with -fno-rtti, pointer type info class incorrectly matches non-pointer type info classes
  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
                   ` (3 preceding siblings ...)
  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
  5 siblings, 0 replies; 7+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-11-05 14:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105387

--- Comment #4 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:b83f01d0057578ebc1785f858fbfd46cdc210560

commit r13-3696-gb83f01d0057578ebc1785f858fbfd46cdc210560
Author: Jakob Hasse <0xjakob@users.noreply.github.com>
Date:   Tue Apr 26 12:03:47 2022 +0800

    libstdc++: fix pointer type exception catch (no RTTI) [PR105387]

    __pbase_type_info::__do_catch(), used to catch pointer type exceptions,
    did not check if the type info object to compare against is a pointer
    type info object before doing a static down-cast to a pointer type info
    object. If RTTI is disabled, this leads to the following situation:
    Since a pointer type info object has additional fields, they would
    end up being undefined if the actual type info object was not a pointer
    type info object.

    A simple check has been added before the down-cast happens.

    Note that a consequence of this check is that exceptions of type
    pointer-to-member cannot be caught anymore.

    In case RTTI is enabled, this does not seem to be a problem because
    RTTI-based checks would run before and prevent running into the bad
    down-cast. Hence, the fix is disabled if RTTI is enabled and exceptions
    of type pointer-to-member can still be caught.

    libstdc++-v3/ChangeLog:

            PR libstdc++/105387
            * libsupc++/pbase_type_info.cc (__do_catch) [!__cpp_rtti]: Add
            check that the thrown type is actually a pointer.
            * testsuite/18_support/105387.cc: New test.
            * testsuite/18_support/105387_memptr.cc: New test.

    Signed-off-by: Jakob Hasse <jakob.hasse@espressif.com>

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

* [Bug libstdc++/105387] libstdc++: with -fno-rtti, pointer type info class incorrectly matches non-pointer type info classes
  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
                   ` (4 preceding siblings ...)
  2022-11-05 14:03 ` cvs-commit at gcc dot gnu.org
@ 2022-11-05 14:05 ` redi at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2022-11-05 14:05 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105387

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|NEW                         |RESOLVED
   Target Milestone|---                         |13.0

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Fixed on trunk now, thanks for the report and the patch.

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