Open Bug 1413313 Opened 7 years ago Updated 2 years ago

sched_* syscalls that take thread IDs should be filtered in the content sandbox policy

Categories

(Core :: Security: Process Sandboxing, enhancement, P3)

Unspecified
Linux
enhancement

Tracking

()

Tracking Status
firefox58 --- affected

People

(Reporter: jld, Assigned: jld)

References

Details

(Whiteboard: sb+)

We already do this for media plugins, but not content: the various syscalls whose names start with "sched_" that operate on a thread should be restricted to pid 0 (the calling thread), with the case of using the thread's actual ID mapped to pid 0 with a trap function.
Blocked by, for once, not PulseAudio proper but specifically the WebRTC PulseAudio glue code[1].  There's also an issue with workers[2], but it seems easily fixable by making the thread set its own priority.  And there's something that uses webrtc's import of parts of Chromium[3], but I can't see what's calling that because Breakpad is being flaky. 

[1] https://searchfox.org/mozilla-central/rev/aa1343961fca52e8c7dab16788530da31aab7c8d/media/webrtc/trunk/webrtc/modules/audio_device/linux/audio_device_pulse_linux.cc#199
[2] https://searchfox.org/mozilla-central/rev/aa1343961fca52e8c7dab16788530da31aab7c8d/dom/workers/RuntimeService.cpp#1841
[3] http://searchfox.org/mozilla-central/rev/aa1343961fca52e8c7dab16788530da31aab7c8d/media/webrtc/trunk/webrtc/base/platform_thread.cc#390

All of these are basically the same problem: these syscalls take only a thread ID, so there's no way to use seccomp-bpf to restrict them to threads of the calling process.  (Put another way, they're like tkill() and there's no equivalent to tgkill().)
Depends on: 1394163
Priority: P2 → --
Interestingly, WebRTC doesn't even try to adjust thread priorities on Linux when embedded in Chromium (same function as link #3 in previous comment):

#elif defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX)
  // TODO(tommi): Switch to the same mechanism as Chromium uses for changing
  // thread priorities.
  return true;

There's some context in https://crbug.com/468793 — Chromium's Linux sandbox was blocking other-thread scheduling operations (by failing with EPERM, not crashing), and when this was eventually noticed, they changed their thread abstractions to remove the general SetPriority() call and allow only SetCurrentThreadPriority and CreateWithPriority (the latter covers most cases where a thread wanted to set another thread's priority).

Unfortunately for us, someone had the idea of factoring out “has a priority” into its own XPCOM interface, shared with various non-thread things (see bug 278531), so trying to make the same changes to nsThread may be more trouble than it's worth.  And PR_SetThreadPriority returns void, so I can't even make nsThread warn on failure; I'd have to make it directly check for whether it's the current thread and warn about that.

There's also the usual problem with trying to do anything with scheduling priority on Unix: in general you don't have permission to raise priority, even if you're just trying to regain your old priority level after lowering it.  (Also, the comments in Chromium indicate that in some cases you might be able to gain realtime scheduling but then be unable to switch back to normal scheduling.)

Maybe the least bad way to deal with this is to fail the syscalls, fix the workers, maybe add some warnings to nsThread if it's not too difficult, and file a bug against WebRTC upstream.
Priority: -- → P3
Whiteboard: sb+
See Also: → 1489735
It's also possible to make nsThread not implement nsISupportsPriority, and expose only a static method to set the current thread's priority, and convert the few places that care.  It's simple enough that I wrote patches for it and they pass Try.

As for WebRTC, it's not just the audio backend, so the cleanups to how it uses audio backends didn't fix this.  However, every use of PlatformThread::SetPriority is directly after starting the thread, so that could be fixed without invasive changes.  Upstream started working on this ( https://webrtc.googlesource.com/src/+/0f8b403eb536ebc721201de5a272ffb66eb5ffe1 ) but hasn't converted all the uses of threads, and it's entangled with another piece of cleanup.

It's also possible to treat MOZ_SANDBOX like WEBRTC_CHROMIUM_BUILD and not do thread priorities at all on Linux; I don't know what the practical impact of that is.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.