Closed Bug 1651701 Opened 5 years ago Closed 5 years ago

Sandbox is incompatible with rseq registration

Categories

(Core :: Security: Process Sandboxing, defect, P1)

78 Branch
x86_64
Linux
defect

Tracking

()

RESOLVED FIXED
mozilla80
Tracking Status
firefox-esr68 - wontfix
firefox-esr78 79+ fixed
firefox78 --- wontfix
firefox79 + fixed
firefox80 + fixed

People

(Reporter: fweimer, Assigned: jld)

References

Details

Attachments

(1 file)

User Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0

Steps to reproduce:

Install firefox 79.0b5 and run it on the upcoming glibc 2.32 version.

Actual results:

Content processes for all tabs crash. The crash happens in rseq registration within glibc:

Core was generated by `/home/test/firefox/firefox-bin -contentproc -childID 6 -isForBrowser -prefsLen'.
Program terminated with signal SIGSYS, Bad system call.
#0 rseq_register_current_thread ()
at ../sysdeps/unix/sysv/linux/rseq-internal.h:38
38 if (INTERNAL_SYSCALL_ERROR_P (ret))
[Current thread is 1 (Thread 0x7f545a45e640 (LWP 5932))]
(gdb) l
33 if (__rseq_abi.cpu_id != RSEQ_CPU_ID_UNINITIALIZED)
34 __libc_fatal ("glibc fatal error: "
35 "rseq already initialized for this thread\n");
36 ret = INTERNAL_SYSCALL_CALL (rseq, &__rseq_abi, sizeof (struct rseq),
37 0, RSEQ_SIG);
38 if (INTERNAL_SYSCALL_ERROR_P (ret))
39 {
40 const char *msg = NULL;
41
42 switch (INTERNAL_SYSCALL_ERRNO (ret))

(gdb) bt
#0 rseq_register_current_thread ()
at ../sysdeps/unix/sysv/linux/rseq-internal.h:38
#1 start_thread (arg=<optimized out>) at pthread_create.c:390
#2 0x00007f546b86d283 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

rseq registration on other threads appears to have succeeded, so this is very strange:

(gdb) thread 2
[Switching to thread 2 (Thread 0x7f5460947640 (LWP 5913))]
#0 syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
38 cmpq $-4095, %rax /* Check %rax for error. */
(gdb) print __rseq_abi
$2 = {cpu_id_start = 2, cpu_id = 2, rseq_cs = {ptr64 = 0, ptr = 0}, flags = 0}

Expected results:

Tabs should show web content.

I believe SIGSYS terminates the process at this point because signals are blocked during thread creation. However, this is required for correctness, so that applications cannot observe a thread state during which rseq is not registered.

Component: Untriaged → Security: Process Sandboxing
Product: Firefox → Core

A consequence of comment #1 is that, unlike most cases of unknown syscalls, this does affect non-Nightly release channels, like Beta as seen in comment #0, but also Release and ESR.

(In addition to SIGSYS not being usable, we also don't want to try denying the syscall directly with SECCOMP_RET_ERRNO: as mentioned on the glibc mailing list, libc will have successfully called rseq to register every thread created before the seccomp policy is applied, so we'd have a mix of threads where the rseq ABI works and ones where it doesn't, possibly even inconsistent within a thread pool. This could cause confusing bugs, and it would leave at least some of the kernel attack surface accessible.)

Assignee: nobody → jld
Severity: -- → S2
Priority: -- → P1

What's the minimum kernel header version you require for building? __NR_rseq is only available starting with kernel 4.18.

What's the minimum kernel header version you require for building? __NR_rseq is only available starting with kernel 4.18.

The tree has its own copy of the syscall definitions:

security/sandbox/chromium/sandbox/linux/system_headers/x86_64_linux_syscalls.h
security/sandbox/chromium/sandbox/linux/system_headers/x86_32_linux_syscalls.h

This is a trivial change that makes Firefox compatible with newer glibc releases. This affects only distros that track new packages aggressively (i.e. Fedora, Arch etc), but it would be good to pre-empty any compatibility problems.

Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: Unspecified → Linux
Hardware: Unspecified → x86_64

Comment on attachment 9162862 [details]
Bug 1651701 - Allow rseq in the Linux sandboxes.

Beta/Release Uplift Approval Request

  • User impact if declined: Crash on Linux distributions using upcoming glibc releases.
  • Is this code covered by automated tests?: No
  • Has the fix been verified in Nightly?: No
  • Needs manual test from QE?: No
  • If yes, steps to reproduce:
  • List of other uplifts needed: None
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): Adding an extra permission to the sandbox.
  • String changes made/needed:
Attachment #9162862 - Flags: approval-mozilla-beta?
Pushed by jedavis@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/042425712eb1 Allow rseq in the Linux sandboxes. r=gcp
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla80

Comment on attachment 9162862 [details]
Bug 1651701 - Allow rseq in the Linux sandboxes.

Simple sandbox allowlist update. Approved for 79.0b8, 78.1esr, and 68.11esr.

Attachment #9162862 - Flags: approval-mozilla-esr78+
Attachment #9162862 - Flags: approval-mozilla-esr68+
Attachment #9162862 - Flags: approval-mozilla-beta?
Attachment #9162862 - Flags: approval-mozilla-beta+

This doesn't work on ESR68 because it depends on bug 1591117. Given where ESR68 is with respect to end-of-life, it's almost certainly not worth the time to make it work. Backed out.
https://hg.mozilla.org/releases/mozilla-esr68/rev/6ee75980862ad59e4ca30e540a4905e9ba4f9d0d

Attachment #9162862 - Flags: approval-mozilla-esr68+
Regressions: 1696359
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: