public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/113211] New: Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found
@ 2024-01-03  5:20 alexis at m2osw dot com
  2024-01-03  5:25 ` [Bug c++/113211] " pinskia at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: alexis at m2osw dot com @ 2024-01-03  5:20 UTC (permalink / raw)
  To: gcc-bugs

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

            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 = 0;

When reading the value, the `eax` register is 0 and we get the SEGV. This seems
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=<optimized out>,
user_id=501, tstrUser=...) at ../core/unixfsservices.cpp:542
#5  0x0000000000459892 in cFSPropDisplayer::InitForProp (this=0x760be0,
pFCO=<optimized out>, propIdx=<optimized out>)
    at ../fs/./../core/fsservices.h:353
#6  0x0000000000453ab6 in cFSPropDisplayer::InitForFCO (this=0x760be0,
ifco=0x8e2550) at ../fs/fspropdisplayer.cpp:248
#7  0x0000000000427631 in cTripwireUtil::CalcProps (pFCO=0x8e2550,
pSpec=<optimized out>, pCalc=<optimized out>, pPD=0x760be0)
    at ./src/tripwire/tripwireutil.cpp:79
#8  0x0000000000423740 in util_ProcessDir (dbIter=..., pIter=0x9a0110,
pSpec=0x770330, pPC=0x747070, pPD=0x760be0)
    at ./src/tripwire/generatedb.cpp:92
#9  0x000000000042389f in util_ProcessDir (dbIter=..., pIter=0x99b370,
pSpec=0x770330, pPC=0x747070, pPD=0x760be0)
    at ./src/tripwire/generatedb.cpp:105
#10 0x000000000042389f in util_ProcessDir (dbIter=..., pIter=0x949370,
pSpec=0x770330, pPC=0x747070, pPD=0x760be0)
    at ./src/tripwire/generatedb.cpp:105
#11 0x000000000042389f in util_ProcessDir (dbIter=..., pIter=0x9482b0,
pSpec=0x770330, pPC=0x747070, pPD=0x760be0)
    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>
=> 0x00007ffff7bf86a4 <+20>:    mov    0x1c(%rax),%eax
   0x00007ffff7bf86aa <+26>:    test   %eax,%eax
   0x00007ffff7bf86ac <+28>:    setne  %al
   0x00007ffff7bf86af <+31>:    add    $0x8,%rsp
   0x00007ffff7bf86b3 <+35>:    ret    
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 happen.

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 under
Ubuntu 16.04 so this bug has been around for a while.

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

* [Bug c++/113211] Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found
  2024-01-03  5:20 [Bug c++/113211] New: Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found alexis at m2osw dot com
@ 2024-01-03  5:25 ` pinskia at gcc dot gnu.org
  2024-01-03  5:26 ` pinskia at gcc dot gnu.org
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-01-03  5:25 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2024-01-03
             Status|UNCONFIRMED                 |WAITING
     Ever confirmed|0                           |1

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Why do you think this is a GCC bug rather than a glibc or systemd issue?

Looking at the assembly that you provided:
   0x00007ffff7bf869f <+15>:    call   0x7ffff7bf7c80 <__tls_get_addr@plt>
=> 0x00007ffff7bf86a4 <+20>:    mov    0x1c(%rax),%eax

That looks correct, RAX is the return value of __tls_get_addr here.

Note __tls_get_addr is not implemented by GCC but by glibc.

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

* [Bug c++/113211] Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found
  2024-01-03  5:20 [Bug c++/113211] New: Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found alexis at m2osw dot com
  2024-01-03  5:25 ` [Bug c++/113211] " pinskia at gcc dot gnu.org
@ 2024-01-03  5:26 ` pinskia at gcc dot gnu.org
  2024-01-03  5:29 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-01-03  5:26 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Is tripwire  compiled statically?

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

* [Bug c++/113211] Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found
  2024-01-03  5:20 [Bug c++/113211] New: Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found alexis at m2osw dot com
  2024-01-03  5:25 ` [Bug c++/113211] " pinskia at gcc dot gnu.org
  2024-01-03  5:26 ` pinskia at gcc dot gnu.org
@ 2024-01-03  5:29 ` pinskia at gcc dot gnu.org
  2024-01-03  5:39 ` alexis at m2osw dot com
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-01-03  5:29 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1827372.html

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

* [Bug c++/113211] Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found
  2024-01-03  5:20 [Bug c++/113211] New: Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found alexis at m2osw dot com
                   ` (2 preceding siblings ...)
  2024-01-03  5:29 ` pinskia at gcc dot gnu.org
@ 2024-01-03  5:39 ` alexis at m2osw dot com
  2024-01-03  5:51 ` pinskia at gcc dot gnu.org
  2024-01-03  9:29 ` sjames at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: alexis at m2osw dot com @ 2024-01-03  5:39 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Alexis Wilke <alexis at m2osw dot com> ---
Well, it could be a glibc issue, but the syntax:

static thread_local unsigned _blocked = 0;

is a compiler thing, right?

Looking at ldd output, it is 100% static:

$ ldd tripwire
        not a dynamic executable
$

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

* [Bug c++/113211] Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found
  2024-01-03  5:20 [Bug c++/113211] New: Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found alexis at m2osw dot com
                   ` (3 preceding siblings ...)
  2024-01-03  5:39 ` alexis at m2osw dot com
@ 2024-01-03  5:51 ` pinskia at gcc dot gnu.org
  2024-01-03  9:29 ` sjames at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-01-03  5:51 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|WAITING                     |RESOLVED
         Resolution|---                         |WONTFIX

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Not a GCC bug as GCC is not involved here, thread_local might be a C/C++
concept and the compiler generates code to use per thread local variables but
it is it is glibc which implements __tls_get_addr for use in shared libraries.

Also I doubt this is a glibc issue either. Basically if you use getpwuid, etc.
in a static linked executable, it will use dlopen and TLS in a shared library
is not compatiable with a static linked executable.

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

* [Bug c++/113211] Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found
  2024-01-03  5:20 [Bug c++/113211] New: Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found alexis at m2osw dot com
                   ` (4 preceding siblings ...)
  2024-01-03  5:51 ` pinskia at gcc dot gnu.org
@ 2024-01-03  9:29 ` sjames at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: sjames at gcc dot gnu.org @ 2024-01-03  9:29 UTC (permalink / raw)
  To: gcc-bugs

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

Sam James <sjames at gcc dot gnu.org> changed:

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

--- Comment #6 from Sam James <sjames at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #5)
> Also I doubt this is a glibc issue either. Basically if you use getpwuid,
> etc. in a static linked executable, it will use dlopen and TLS in a shared
> library is not compatiable with a static linked executable.

It even warns about that at link-time.

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

end of thread, other threads:[~2024-01-03  9:29 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-03  5:20 [Bug c++/113211] New: Trying to initialize the tripwire database ends up with a SEGV if a uid cannot be found alexis at m2osw dot com
2024-01-03  5:25 ` [Bug c++/113211] " pinskia at gcc dot gnu.org
2024-01-03  5:26 ` pinskia at gcc dot gnu.org
2024-01-03  5:29 ` pinskia at gcc dot gnu.org
2024-01-03  5:39 ` alexis at m2osw dot com
2024-01-03  5:51 ` pinskia at gcc dot gnu.org
2024-01-03  9:29 ` sjames 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).