public inbox for libc-help@sourceware.org
 help / color / mirror / Atom feed
* segmentation fault with glibc-2.34
@ 2021-12-03 13:38 Andreas Fink
  2021-12-03 14:55 ` Adhemerval Zanella
  0 siblings, 1 reply; 5+ messages in thread
From: Andreas Fink @ 2021-12-03 13:38 UTC (permalink / raw)
  To: libc-help

[-- Attachment #1: Type: text/plain, Size: 410 bytes --]

Hello,
I have observed a crash in firefox with glibc-2.34 and have found a
small reproducer.
Is the sigsys signal handler valid? If yes, then there is a bug in
glibc-2.34.
If it is invalid to set the result in the context, I think the firefox
sandbox is doing dodgy things.

gcc test.c -lseccomp
strace ./a.out

This test reproducer does not segfault with 2.33 (it gives a
"Permission denied")

Cheers
Andreas

[-- Attachment #2: test.c --]
[-- Type: text/x-c++src, Size: 1660 bytes --]

#define _GNU_SOURCE
#include <err.h>
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <seccomp.h>
#include <signal.h>
#include <unistd.h>

#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)])
#define SECCOMP_RESULT(_ctx)    SECCOMP_REG(_ctx, REG_RAX)
void sigsys_handler(int signum, siginfo_t *info, void *vctx) {
    static int ctr = 0;
    ucontext_t * ctx = vctx;
    intptr_t ret_val = 0;
    if (++ctr > 1)
        ret_val = -13; // EACCESS
    SECCOMP_RESULT(ctx) = (greg_t)ret_val;
}

static void sandbox(void)
{
    /* allow all syscalls by default */
    scmp_filter_ctx seccomp_ctx = seccomp_init(SCMP_ACT_ALLOW);
    if (!seccomp_ctx)
        err(1, "seccomp_init failed");

    /* kill the process, if it tries to use "newfstatat" syscall */
    if (seccomp_rule_add_exact(seccomp_ctx, SCMP_ACT_TRAP, seccomp_syscall_resolve_name("newfstatat"), 0)) {
        perror("seccomp_rule_add_exact failed");
        exit(1);
    }

    /* apply the composed filter */
    if (seccomp_load(seccomp_ctx)) {
        perror("seccomp_load failed");
        exit(1);
    }

    /* release allocated context */
    seccomp_release(seccomp_ctx);
}


int main(int argc, char** argv) {
    struct sigaction sa, old_sa;
    sa.sa_sigaction = sigsys_handler;
    sa.sa_flags = SA_SIGINFO | SA_NODEFER;
    sigaction(SIGSYS, &sa, &old_sa);
    sandbox();
    struct passwd *pwd = getpwuid(getuid());
    if (pwd) {
        printf("%s\n", pwd->pw_name);
    } else {
        perror("getpwuid failed\n");
    }
    return 0;
}


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

* Re: segmentation fault with glibc-2.34
  2021-12-03 13:38 segmentation fault with glibc-2.34 Andreas Fink
@ 2021-12-03 14:55 ` Adhemerval Zanella
  2021-12-03 15:02   ` Florian Weimer
  2021-12-03 15:03   ` Adhemerval Zanella
  0 siblings, 2 replies; 5+ messages in thread
From: Adhemerval Zanella @ 2021-12-03 14:55 UTC (permalink / raw)
  To: Andreas Fink; +Cc: libc-help

On Fri, Dec 3, 2021 at 10:38 AM Andreas Fink via Libc-help
<libc-help@sourceware.org> wrote:
>
> Hello,
> I have observed a crash in firefox with glibc-2.34 and have found a
> small reproducer.
> Is the sigsys signal handler valid? If yes, then there is a bug in
> glibc-2.34.
> If it is invalid to set the result in the context, I think the firefox
> sandbox is doing dodgy things.
>
> gcc test.c -lseccomp
> strace ./a.out

The seccomp filter *explicitly* blocks newfstatat, which might be used
by getpwuid.

>
> This test reproducer does not segfault with 2.33 (it gives a
> "Permission denied")
>
> Cheers
> Andreas

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

* Re: segmentation fault with glibc-2.34
  2021-12-03 14:55 ` Adhemerval Zanella
@ 2021-12-03 15:02   ` Florian Weimer
  2021-12-03 15:15     ` Adhemerval Zanella
  2021-12-03 15:03   ` Adhemerval Zanella
  1 sibling, 1 reply; 5+ messages in thread
From: Florian Weimer @ 2021-12-03 15:02 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-help

* Adhemerval Zanella via Libc-help:

> On Fri, Dec 3, 2021 at 10:38 AM Andreas Fink via Libc-help
> <libc-help@sourceware.org> wrote:
>>
>> Hello,
>> I have observed a crash in firefox with glibc-2.34 and have found a
>> small reproducer.
>> Is the sigsys signal handler valid? If yes, then there is a bug in
>> glibc-2.34.
>> If it is invalid to set the result in the context, I think the firefox
>> sandbox is doing dodgy things.
>>
>> gcc test.c -lseccomp
>> strace ./a.out
>
> The seccomp filter *explicitly* blocks newfstatat, which might be used
> by getpwuid.

It's used by the chroot detection.  NSS assumes that a chroot has
happened and disables module loading.  This produces internal null
pointers despite returning success from the lookup, and the callers do
not handle that.  I'm not sure how the previous code handled that.

We should probably return EPERM due to that failing stat call and
propagate the failure to the caller.  Returning ENOENT/a successful
lookup that produces no data seems wrong.

Thanks,
Florian


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

* Re: segmentation fault with glibc-2.34
  2021-12-03 14:55 ` Adhemerval Zanella
  2021-12-03 15:02   ` Florian Weimer
@ 2021-12-03 15:03   ` Adhemerval Zanella
  1 sibling, 0 replies; 5+ messages in thread
From: Adhemerval Zanella @ 2021-12-03 15:03 UTC (permalink / raw)
  To: Andreas Fink; +Cc: libc-help



On 03/12/2021 11:55, Adhemerval Zanella wrote:
> On Fri, Dec 3, 2021 at 10:38 AM Andreas Fink via Libc-help
> <libc-help@sourceware.org> wrote:
>>
>> Hello,
>> I have observed a crash in firefox with glibc-2.34 and have found a
>> small reproducer.
>> Is the sigsys signal handler valid? If yes, then there is a bug in
>> glibc-2.34.
>> If it is invalid to set the result in the context, I think the firefox
>> sandbox is doing dodgy things.
>>
>> gcc test.c -lseccomp
>> strace ./a.out
> 
> The seccomp filter *explicitly* blocks newfstatat, which might be used
> by getpwuid.

Oops, I didn't not get the issue at first.  It seems that the syscall return
code it not being set as expected:

(gdb) disas
Dump of assembler code for function __GI___fstatat64:
   0x00007ffff7e6fe70 <+0>:	endbr64 
   0x00007ffff7e6fe74 <+4>:	mov    %ecx,%r10d
   0x00007ffff7e6fe77 <+7>:	mov    $0x106,%eax
   0x00007ffff7e6fe7c <+12>:	syscall 
   0x00007ffff7e6fe7e <+14>:	cmp    $0xfffff000,%eax
=> 0x00007ffff7e6fe83 <+19>:	ja     0x7ffff7e6fe90 <__GI___fstatat64+32>
   0x00007ffff7e6fe85 <+21>:	xor    %eax,%eax
   0x00007ffff7e6fe87 <+23>:	ret    
   0x00007ffff7e6fe88 <+24>:	nopl   0x0(%rax,%rax,1)
   0x00007ffff7e6fe90 <+32>:	mov    0x100f79(%rip),%rdx        # 0x7ffff7f70e10
   0x00007ffff7e6fe97 <+39>:	neg    %eax
   0x00007ffff7e6fe99 <+41>:	mov    %eax,%fs:(%rdx)
   0x00007ffff7e6fe9c <+44>:	mov    $0xffffffff,%eax
   0x00007ffff7e6fea1 <+49>:	ret    
End of assembler dump.
(gdb) i r eax
eax            0x0                 0

Which makes getpwuid access uninitiated/invalid memory later.

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

* Re: segmentation fault with glibc-2.34
  2021-12-03 15:02   ` Florian Weimer
@ 2021-12-03 15:15     ` Adhemerval Zanella
  0 siblings, 0 replies; 5+ messages in thread
From: Adhemerval Zanella @ 2021-12-03 15:15 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-help



On 03/12/2021 12:02, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-help:
> 
>> On Fri, Dec 3, 2021 at 10:38 AM Andreas Fink via Libc-help
>> <libc-help@sourceware.org> wrote:
>>>
>>> Hello,
>>> I have observed a crash in firefox with glibc-2.34 and have found a
>>> small reproducer.
>>> Is the sigsys signal handler valid? If yes, then there is a bug in
>>> glibc-2.34.
>>> If it is invalid to set the result in the context, I think the firefox
>>> sandbox is doing dodgy things.
>>>
>>> gcc test.c -lseccomp
>>> strace ./a.out
>>
>> The seccomp filter *explicitly* blocks newfstatat, which might be used
>> by getpwuid.
> 
> It's used by the chroot detection.  NSS assumes that a chroot has
> happened and disables module loading.  This produces internal null
> pointers despite returning success from the lookup, and the callers do
> not handle that.  I'm not sure how the previous code handled that.
> 

Indeed this is what is happening on nss_database_check_reload_and_get.

> We should probably return EPERM due to that failing stat call and
> propagate the failure to the caller.  Returning ENOENT/a successful
> lookup that produces no data seems wrong.

Agreed.

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

end of thread, other threads:[~2021-12-03 15:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-03 13:38 segmentation fault with glibc-2.34 Andreas Fink
2021-12-03 14:55 ` Adhemerval Zanella
2021-12-03 15:02   ` Florian Weimer
2021-12-03 15:15     ` Adhemerval Zanella
2021-12-03 15:03   ` Adhemerval Zanella

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