From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id EB95E3857C43; Tue, 26 Apr 2022 08:58:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EB95E3857C43 From: "jakob2811 at hotmail dot de" 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 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: unknown X-Bugzilla-Keywords: EH X-Bugzilla-Severity: normal X-Bugzilla-Who: jakob2811 at hotmail dot de 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 keywords bug_severity priority component assigned_to reporter target_milestone cf_gcchost cf_gcctarget cf_gccbuild attachments.created 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: Tue, 26 Apr 2022 08:58:58 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D105387 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=3D52879&action=3Dedit 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 "norm= al" 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 samp= le code: #include #include 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 i= nfo=20 object of the exception (const type_info *), will be wrongly casted into a pointer type info object (const __pbase_type_info *). The latter has additi= onal 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 evaluat= ion of undefined members. It looks as if __pbase_type_info::__do_catch() is made to handle both point= er 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_catc= h() 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 configuration= s. 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 samp= le 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 Li= nux, 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=3Dxtensa-esp32-elf-gcc COLLECT_LTO_WRAPPER=3D/home/jakob/.espressif/tools/xtensa-esp32-elf/esp-202= 1r2-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=3Dx86_64-build_pc-linux-gnu --host=3Dx86_64-build_pc-linux-gnu --target=3Dxtensa-esp32-elf --prefix=3D/builds/idf/crosstool-NG/builds/xtensa-esp32-elf --with-local-prefix=3D/builds/idf/crosstool-NG/builds/xtensa-esp32-elf/xten= sa-esp32-elf --with-headers=3D/builds/idf/crosstool-NG/builds/xtensa-esp32-elf/xtensa-es= p32-elf/include --with-newlib --enable-threads=3Dno --disable-shared --with-pkgversion=3D'crosstool-NG esp-2021r2-patch3' --disable-__cxa_atexit --enable-cxx-flags=3D-ffunction-sections --disable-libgomp --disable-libmud= flap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --with-gmp=3D/builds/idf/crosstool-NG/.build/xtensa-esp32-elf/buildtools --with-mpfr=3D/builds/idf/crosstool-NG/.build/xtensa-esp32-elf/buildtools --with-mpc=3D/builds/idf/crosstool-NG/.build/xtensa-esp32-elf/buildtools --with-isl=3D/builds/idf/crosstool-NG/.build/xtensa-esp32-elf/buildtools --enable-lto --enable-target-optspace --without-long-double-128 --disable-n= ls --enable-multiarch --enable-languages=3Dc,c++ --disable-libstdcxx-verbose --enable-threads=3Dposix --enable-gcov-custom-rtio --enable-libstdcxx-time= =3Dyes Thread model: posix gcc version 8.4.0 (crosstool-NG esp-2021r2-patch3)=20 $ gcc -v Using built-in specs. COLLECT_GCC=3Dgcc COLLECT_LTO_WRAPPER=3D/usr/libexec/gcc/x86_64-linux-gnu/11.2.0/lto-wrapper Target: x86_64-linux-gnu Configured with: ../configure -prefix=3D/usr --enable-languages=3Dc,c++ --enable-multiarch --host=3Dx86_64-linux-gnu --build=3Dx86_64-linux-gnu --target=3Dx86_64-linux-gnu --enable-cxx-flags=3D-fno-rtti Thread model: posix Supported LTO compression algorithms: zlib gcc version 11.2.0 (GCC)=