From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 9855F3858C2C; Wed, 3 Jan 2024 05:20:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9855F3858C2C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1704259239; bh=6ZcekDOtOpEviloiXr0fTBAfn1UNAKDCnmasL/IWl9s=; h=From:To:Subject:Date:From; b=TTkgX/AbNgG5R9HCGLPwsX6xHdF1kQmegHa0z6u2lT/2uKXYnUXB3olnZ0vg2AIid +GoM8G7wX1XRwbVjxJAefW4+Yr7eRh7dunwZ9KlShn5VXRi2umQD56Je6FtYDpGtgr Ejv2rm1PaQsidMBbS70u0vTVJ3Hc8fOjORMMVwT8= From: "alexis at m2osw dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/113211] New: Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found Date: Wed, 03 Jan 2024 05:20:39 +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: 11.4.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: alexis at m2osw dot com 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 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D113211 Bug ID: 113211 Summary: Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found Product: gcc Version: 11.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: alexis at m2osw dot com Target Milestone: --- On some systems, when I install tripwire, it crashes. Now I have had the problem many times, so I decided to look into why it happens. In most cases, one can avoid the issue just by skipping checking certain files and then go on with their life. I don't think that tripwire should ever SEGV, though. Thus, this time I compiled from source on Ubuntu 22.04 and got a stacktrace. The SEGV actually happens in a systemd library which uses a thread safe variable. The systemd function looks like this: _public_ bool _nss_systemd_is_blocked(void) { return _blocked > 0; } The _blocked variable is defined like this: static thread_local unsigned _blocked =3D 0; When reading the value, the `eax` register is 0 and we get the SEGV. This s= eems to be a compiler functionality that fails. There are other tools that have a similar issue and also SEGV. Note that it only happens if the `uid` does not exist in the `/etc/passwd` file and that function will have been called many times before, so the variable should already have been initialized. Here is the stack trace: #0 0x00007ffff7bf86a4 in _nss_systemd_is_blocked () from /lib/x86_64-linux-gnu/libnss_systemd.so.2 #1 0x00007ffff7bfa46d in _nss_systemd_getpwuid_r () from /lib/x86_64-linux-gnu/libnss_systemd.so.2 #2 0x00000000005e5bcf in getpwuid_r () #3 0x00000000005e59d3 in getpwuid () #4 0x0000000000481b6f in cUnixFSServices::GetUserName (this=3D, user_id=3D501, tstrUser=3D...) at ../core/unixfsservices.cpp:542 #5 0x0000000000459892 in cFSPropDisplayer::InitForProp (this=3D0x760be0, pFCO=3D, propIdx=3D) at ../fs/./../core/fsservices.h:353 #6 0x0000000000453ab6 in cFSPropDisplayer::InitForFCO (this=3D0x760be0, ifco=3D0x8e2550) at ../fs/fspropdisplayer.cpp:248 #7 0x0000000000427631 in cTripwireUtil::CalcProps (pFCO=3D0x8e2550, pSpec=3D, pCalc=3D, pPD=3D0x760be0) at ./src/tripwire/tripwireutil.cpp:79 #8 0x0000000000423740 in util_ProcessDir (dbIter=3D..., pIter=3D0x9a0110, pSpec=3D0x770330, pPC=3D0x747070, pPD=3D0x760be0) at ./src/tripwire/generatedb.cpp:92 #9 0x000000000042389f in util_ProcessDir (dbIter=3D..., pIter=3D0x99b370, pSpec=3D0x770330, pPC=3D0x747070, pPD=3D0x760be0) at ./src/tripwire/generatedb.cpp:105 #10 0x000000000042389f in util_ProcessDir (dbIter=3D..., pIter=3D0x949370, pSpec=3D0x770330, pPC=3D0x747070, pPD=3D0x760be0) at ./src/tripwire/generatedb.cpp:105 #11 0x000000000042389f in util_ProcessDir (dbIter=3D..., pIter=3D0x9482b0, pSpec=3D0x770330, pPC=3D0x747070, pPD=3D0x760be0) at ./src/tripwire/generatedb.cpp:105 and the assembly code of the very function that SEGV: 0x00007ffff7bf86a4 in _nss_systemd_is_blocked () from /lib/x86_64-linux-gnu/libnss_systemd.so.2 (gdb) disassemble Dump of assembler code for function _nss_systemd_is_blocked: 0x00007ffff7bf8690 <+0>: endbr64 0x00007ffff7bf8694 <+4>: sub $0x8,%rsp 0x00007ffff7bf8698 <+8>: lea 0x44919(%rip),%rdi # 0x7ffff7c3cfb8 0x00007ffff7bf869f <+15>: call 0x7ffff7bf7c80 <__tls_get_addr@plt> =3D> 0x00007ffff7bf86a4 <+20>: mov 0x1c(%rax),%eax 0x00007ffff7bf86aa <+26>: test %eax,%eax 0x00007ffff7bf86ac <+28>: setne %al 0x00007ffff7bf86af <+31>: add $0x8,%rsp 0x00007ffff7bf86b3 <+35>: ret=20=20=20=20 End of assembler dump. If I try a simple `getpwuid()` call with an unknown UID, it returns nullptr just as expected. I'm not too sure what tripwire adds that would cause the issue. It's rather complex and still looks like it happens because the C compiler returns a nullptr in a location where it is never expected to happ= en. To reproduce, you can create a VM, change the ownership of a file to an undefined user on a file that tripwire will read (as under /root or /etc), = then install tripwire. At the time it tries to initializes its database, it will SEGV instead. Note: this has been happening for a long time. I think the first time was u= nder Ubuntu 16.04 so this bug has been around for a while.=