| Index: sandbox/linux/seccomp-bpf/sandbox_bpf.cc
|
| diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
|
| index c96642ec408685548d96f056731469bc4844a0dc..239043eb270d57b8b60df714323f5a166a380ede 100644
|
| --- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
|
| +++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
|
| @@ -11,7 +11,6 @@
|
| #endif
|
|
|
| #include <errno.h>
|
| -#include <linux/filter.h>
|
| #include <sys/prctl.h>
|
| #include <sys/types.h>
|
| #include <unistd.h>
|
| @@ -34,6 +33,7 @@
|
| #include "sandbox/linux/services/proc_util.h"
|
| #include "sandbox/linux/services/syscall_wrappers.h"
|
| #include "sandbox/linux/services/thread_helpers.h"
|
| +#include "sandbox/linux/system_headers/linux_filter.h"
|
| #include "sandbox/linux/system_headers/linux_seccomp.h"
|
| #include "sandbox/linux/system_headers/linux_syscalls.h"
|
|
|
| @@ -59,9 +59,40 @@ bool KernelSupportsSeccompBPF() {
|
| return false;
|
| }
|
|
|
| +// LG introduced a buggy syscall, sys_set_media_ext, with the same number as
|
| +// seccomp. Return true if the current kernel has this buggy syscall.
|
| +//
|
| +// We want this to work with upcoming versions of seccomp, so we pass bogus
|
| +// flags that are unlikely to ever be used by the kernel. A normal kernel would
|
| +// return -EINVAL, but a buggy LG kernel would return 1.
|
| +bool KernelHasLGBug() {
|
| +#if defined(OS_ANDROID)
|
| + // sys_set_media will see this as NULL, which should be a safe (non-crashing)
|
| + // way to invoke it. A genuine seccomp syscall will see it as
|
| + // SECCOMP_SET_MODE_STRICT.
|
| + const unsigned int operation = 0;
|
| + // Chosen by fair dice roll. Guaranteed to be random.
|
| + const unsigned int flags = 0xf7a46a5c;
|
| + const int rv = sys_seccomp(operation, flags, nullptr);
|
| + // A genuine kernel would return -EINVAL (which would set rv to -1 and errno
|
| + // to EINVAL), or at the very least return some kind of error (which would
|
| + // set rv to -1). Any other behavior indicates that whatever code received
|
| + // our syscall was not the real seccomp.
|
| + if (rv != -1) {
|
| + return true;
|
| + }
|
| +#endif // defined(OS_ANDROID)
|
| +
|
| + return false;
|
| +}
|
| +
|
| // Check if the kernel supports seccomp-filter via the seccomp system call
|
| // and the TSYNC feature to enable seccomp on all threads.
|
| bool KernelSupportsSeccompTsync() {
|
| + if (KernelHasLGBug()) {
|
| + return false;
|
| + }
|
| +
|
| errno = 0;
|
| const int rv =
|
| sys_seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, nullptr);
|
|
|