This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Fallout from dlopen() blocking SIGSYS


On Wed, Dec 04, 2019 at 05:46:54PM -0300, Adhemerval Zanella wrote:
> 
> 
> On 03/12/2019 11:31, Gian-Carlo Pascutto wrote:
> > (reposting here per request from Florian Weimer)
> > 
> > This glibc patch:
> > 
> > Block signals during the initial part of dlopen
> > (a2e8aa0d9ea648068d8be52dd7b15f1b6a008e23)
> > 
> > is going to break every Firefox release of the last few years. We use a
> > seccomp-bpf filter to sandbox various processes. In some of these
> > processes we don't want to do a dlopen() of untrusted code while we're
> > not sandboxed yet, for example in the process we use to isolate Google's
> > Widevine DRM modules from any private data on the system.
> > 
> > seccomp-bpf will intercept various filesystem related syscalls and raise
> > SIGSYS, at which moment our code will contact a broker in the parent
> > process that checks if the file that's being want to read is acceptable
> > to us, and then passes down the file handle.
> > 
> > This obviously only works if the code that we load doesn't block the
> > SIGSYS signal, so we interpose the signal handling functions to stop
> > that from happening:
> > https://searchfox.org/mozilla-central/rev/04d8e7629354bab9e6a285183e763410860c5006/security/sandbox/linux/SandboxHooks.cpp#42
> > 
> > But, ld.so being the linker itself, this technique doesn't work for it.
> > This means that it will succeed in blocking SIGSYS, try open() (or
> > similar), and fail because seccomp-bpf will block it but nobody will
> > handle the raised signal. Now, we hit a Linux seccomp-bpf design issue:
> > SECCOMP_RET_TRAP will, if the signal is either ignored or blocked,
> > unblock it and reset it to SIG_DFL (effectively).
> > At this point, Firefox crashes.
> > 
> > We are tracking the problem here:
> > https://bugzilla.mozilla.org/show_bug.cgi?id=1600574
> > 
> > This is a particularly nasty problem for us - the only
> > solution/workaround so far is to disable sandboxing, and if affects old
> > releases such as ESR.
> > 
> > I'm not clear if it affects other seccomp-bpf users like Chromium - they
> > use almost exactly the same way of dealing with filesystem access, but
> > (all AFAIK) only for the sandboxed GPU Process which might not need to
> > dlopen() things (and I'm not sure that particular sandbox is enabled on
> > regular Linux to begin with).
> > 
> > We might need to intercept the system calls that set up the signal
> > handling and basically undo the above glibc change, while trying to
> > ensure the conditions that caused you to make the above change don't
> > hold. Or something. We're still thinking about how to cope with this.
> > 
> 
> Block and unblocking signals during certain parts of libc implementation
> are required to avoid consistency issues and Florian can give us a better
> idea why it is important on dlopen. Another implementation that glibc also
> does it is posix_spawn and you might face this very issue if you use use
> posix_spawn with some file action.
> 
> IMHO the issue here is seccomp-bpf is crossing some API boundaries and
> adding such constraint that make harder to provide a more robust libc
> implementation. The SIGSYS seemed to become a de-facto API for seccomp,
> where blocking it might break some filter criteria specially if it tries
> to work along with libc. 
> 
> I presume glibc might try to work better with seccomp and don't add SIGSYS
> on __libc_signal_block_all, however it is an incomplete solution since
> SIGSYS handler can potentially make libc internal state inconsistent.
> 
> What I would expect is with current SECCOMP_RET_TRAP semantic that once
> a filter is installed, the kernel would either fail or silent ignore
> trying to block SIGSYS (as for SIGKILL or SIGSTOP).  However it does
> not help with current situation.
> 
> Would be possible to write a filter to intercept rt_sigprocmask and 
> exclude SIGSYS for this specific case?

This is probably possible but even more dangerous. It risks leaving a
signal unblocked in places where it's unsafe for it to be unblocked,
and hiding that fact from libc. That's goind deeper in the rabbit hole
of hacks that poke at implementation internals, not getting out of it.

I think the problem here is that SECCOMP_RET_TRAP is currently a
broken interface, and it's part of a larger problem of
"self-sandboxing" not being a valid sandboxing model. A non-broken
version of it would deliver the signal to a separate process;
SECCOMP_RET_TRACE already does this, but I imagine it's problematic
for other reasons like interfering with use of debugger, etc.

Rich


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]