Commit a1d175fe authored by Julien Tinnes's avatar Julien Tinnes

Linux sandbox: whitelist allowed Futex operations.

Remove the existing blacklist and whitelist allowed futex operations instead.
The semantics change a little bit as none of the "priority inheritance" operations
are allowed.

BUG=408847
R=mdempsky@chromium.org

Review URL: https://codereview.chromium.org/550473002

Cr-Commit-Position: refs/heads/master@{#293589}
parent b23a1457
...@@ -271,6 +271,14 @@ BPF_DEATH_TEST_C(BaselinePolicy, ...@@ -271,6 +271,14 @@ BPF_DEATH_TEST_C(BaselinePolicy,
syscall(__NR_futex, NULL, FUTEX_CMP_REQUEUE_PI_PRIVATE, 0, NULL, NULL, 0); syscall(__NR_futex, NULL, FUTEX_CMP_REQUEUE_PI_PRIVATE, 0, NULL, NULL, 0);
_exit(1); _exit(1);
} }
BPF_DEATH_TEST_C(BaselinePolicy,
FutexWithUnlockPIPrivate,
DEATH_MESSAGE(GetFutexErrorMessageContentForTests()),
BaselinePolicy) {
syscall(__NR_futex, NULL, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0);
_exit(1);
}
#endif // !defined(OS_ANDROID) #endif // !defined(OS_ANDROID)
BPF_TEST_C(BaselinePolicy, PrctlDumpable, BaselinePolicy) { BPF_TEST_C(BaselinePolicy, PrctlDumpable, BaselinePolicy) {
......
...@@ -25,13 +25,16 @@ ...@@ -25,13 +25,16 @@
#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
#include "sandbox/linux/seccomp-bpf/linux_seccomp.h" #include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
#include "sandbox/linux/services/android_futex.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "sandbox/linux/services/android_futex.h"
#if !defined(F_DUPFD_CLOEXEC) #if !defined(F_DUPFD_CLOEXEC)
#define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6) #define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6)
#endif #endif
#endif
#endif // defined(OS_ANDROID)
#if defined(__arm__) && !defined(MAP_STACK) #if defined(__arm__) && !defined(MAP_STACK)
#define MAP_STACK 0x20000 // Daisy build environment has old headers. #define MAP_STACK 0x20000 // Daisy build environment has old headers.
...@@ -207,19 +210,20 @@ ResultExpr RestrictKillTarget(pid_t target_pid, int sysno) { ...@@ -207,19 +210,20 @@ ResultExpr RestrictKillTarget(pid_t target_pid, int sysno) {
} }
ResultExpr RestrictFutex() { ResultExpr RestrictFutex() {
// In futex.c, the kernel does "int cmd = op & FUTEX_CMD_MASK;". We need to const int kAllowedFutexFlags = FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME;
// make sure that the combination below will cover every way to get const int kOperationMask = ~kAllowedFutexFlags;
// FUTEX_CMP_REQUEUE_PI. const int kAllowedFutexOperations[] = {
const int kBannedFutexBits = FUTEX_WAIT, FUTEX_WAKE, FUTEX_FD, FUTEX_REQUEUE,
~(FUTEX_CMD_MASK | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME); FUTEX_CMP_REQUEUE, FUTEX_WAKE_OP, FUTEX_WAIT_BITSET, FUTEX_WAKE_BITSET};
COMPILE_ASSERT(0 == kBannedFutexBits,
need_to_explicitly_blacklist_more_bits);
const Arg<int> op(1); const Arg<int> op(1);
return If(op == FUTEX_CMP_REQUEUE_PI || op == FUTEX_CMP_REQUEUE_PI_PRIVATE ||
op == (FUTEX_CMP_REQUEUE_PI | FUTEX_CLOCK_REALTIME) || BoolExpr IsAllowedOp = (op & kOperationMask) == kAllowedFutexOperations[0];
op == (FUTEX_CMP_REQUEUE_PI_PRIVATE | FUTEX_CLOCK_REALTIME), for (size_t i = 1; i < arraysize(kAllowedFutexOperations); ++i) {
CrashSIGSYSFutex()).Else(Allow()); IsAllowedOp =
IsAllowedOp || ((op & kOperationMask) == kAllowedFutexOperations[i]);
}
return If(IsAllowedOp, Allow()).Else(CrashSIGSYSFutex());
} }
} // namespace sandbox. } // namespace sandbox.
...@@ -5,20 +5,64 @@ ...@@ -5,20 +5,64 @@
#ifndef SANDBOX_LINUX_SERVICES_ANDROID_FUTEX_H_ #ifndef SANDBOX_LINUX_SERVICES_ANDROID_FUTEX_H_
#define SANDBOX_LINUX_SERVICES_ANDROID_FUTEX_H_ #define SANDBOX_LINUX_SERVICES_ANDROID_FUTEX_H_
#if !defined(FUTEX_PRIVATE_FLAG) #if !defined(FUTEX_WAIT)
#define FUTEX_PRIVATE_FLAG 128 #define FUTEX_WAIT 0
#endif #endif
#if !defined(FUTEX_CLOCK_REALTIME) #if !defined(FUTEX_WAKE)
#define FUTEX_CLOCK_REALTIME 256 #define FUTEX_WAKE 1
#endif
#if !defined(FUTEX_FD)
#define FUTEX_FD 2
#endif
#if !defined(FUTEX_REQUEUE)
#define FUTEX_REQUEUE 3
#endif
#if !defined(FUTEX_CMP_REQUEUE)
#define FUTEX_CMP_REQUEUE 4
#endif
#if !defined(FUTEX_WAKE_OP)
#define FUTEX_WAKE_OP 5
#endif
#if !defined(FUTEX_LOCK_PI)
#define FUTEX_LOCK_PI 6
#endif
#if !defined(FUTEX_UNLOCK_PI)
#define FUTEX_UNLOCK_PI 7
#endif
#if !defined(FUTEX_TRYLOCK_PI)
#define FUTEX_TRYLOCK_PI 8
#endif
#if !defined(FUTEX_WAIT_BITSET)
#define FUTEX_WAIT_BITSET 9
#endif
#if !defined(FUTEX_WAKE_BITSET)
#define FUTEX_WAKE_BITSET 10
#endif
#if !defined(FUTEX_WAIT_REQUEUE_PI)
#define FUTEX_WAIT_REQUEUE_PI 11
#endif #endif
#if !defined(FUTEX_CMP_REQUEUE_PI) #if !defined(FUTEX_CMP_REQUEUE_PI)
#define FUTEX_CMP_REQUEUE_PI 12 #define FUTEX_CMP_REQUEUE_PI 12
#endif #endif
#if !defined(FUTEX_CMP_REQUEUE_PI_PRIVATE) #if !defined(FUTEX_PRIVATE_FLAG)
#define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | FUTEX_PRIVATE_FLAG) #define FUTEX_PRIVATE_FLAG 128
#endif
#if !defined FUTEX_CLOCK_REALTIME
#define FUTEX_CLOCK_REALTIME 256
#endif #endif
#if !defined(FUTEX_CMD_MASK) #if !defined(FUTEX_CMD_MASK)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment