Commit a007c724 authored by Julien Tinnes's avatar Julien Tinnes

Linux sandbox: restrict {set,get}priority() in baseline policy.

In the baseline policy, we restrict setpriority() to
|which| == PRIO_PROCESS and (|who| == 0) || (|who| == current_pid).

This doesn't affect most policies which allow setpriority()
unconditionally but allows baseline unittests to pass on Android.

BUG=398611, 399473
R=mdempsky@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#294422}
parent cef0cb9e
......@@ -150,6 +150,9 @@ ResultExpr EvaluateSyscallImpl(int fs_denied_errno,
if (sysno == __NR_futex)
return RestrictFutex();
if (sysno == __NR_getpriority || sysno ==__NR_setpriority)
return RestrictGetSetpriority(current_pid);
if (sysno == __NR_madvise) {
// Only allow MADV_DONTNEED (aka MADV_FREE).
const Arg<int> advice(2);
......@@ -171,7 +174,7 @@ ResultExpr EvaluateSyscallImpl(int fs_denied_errno,
return RestrictMprotectFlags();
if (sysno == __NR_prctl)
return sandbox::RestrictPrctl();
return RestrictPrctl();
#if defined(__x86_64__) || defined(__arm__) || defined(__mips__) || \
defined(__aarch64__)
......
......@@ -10,6 +10,7 @@
#include <signal.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
......@@ -301,6 +302,41 @@ BPF_DEATH_TEST_C(BaselinePolicy,
_exit(1);
}
BPF_TEST_C(BaselinePolicy, GetOrSetPriority, BaselinePolicy) {
errno = 0;
const int original_prio = getpriority(PRIO_PROCESS, 0);
// Check errno instead of the return value since this system call can return
// -1 as a valid value.
BPF_ASSERT_EQ(0, errno);
errno = 0;
int rc = getpriority(PRIO_PROCESS, getpid());
BPF_ASSERT_EQ(0, errno);
rc = getpriority(PRIO_PROCESS, getpid() + 1);
BPF_ASSERT_EQ(-1, rc);
BPF_ASSERT_EQ(EPERM, errno);
rc = setpriority(PRIO_PROCESS, 0, original_prio);
BPF_ASSERT_EQ(0, rc);
rc = setpriority(PRIO_PROCESS, getpid(), original_prio);
BPF_ASSERT_EQ(0, rc);
errno = 0;
rc = setpriority(PRIO_PROCESS, getpid() + 1, original_prio);
BPF_ASSERT_EQ(-1, rc);
BPF_ASSERT_EQ(EPERM, errno);
}
BPF_DEATH_TEST_C(BaselinePolicy,
GetPrioritySigsys,
DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()),
BaselinePolicy) {
getpriority(PRIO_USER, 0);
_exit(1);
}
} // namespace
} // namespace sandbox
......@@ -14,7 +14,9 @@
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
......@@ -237,4 +239,12 @@ ResultExpr RestrictFutex() {
.Default(CrashSIGSYSFutex());
}
ResultExpr RestrictGetSetpriority(pid_t target_pid) {
const Arg<int> which(0);
const Arg<int> who(1);
return If(which == PRIO_PROCESS,
If(who == 0 || who == target_pid, Allow()).Else(Error(EPERM)))
.Else(CrashSIGSYS());
}
} // namespace sandbox.
......@@ -62,6 +62,10 @@ bpf_dsl::ResultExpr RestrictKillTarget(pid_t target_pid, int sysno);
// Crash if FUTEX_CMP_REQUEUE_PI is used in the second argument of futex(2).
bpf_dsl::ResultExpr RestrictFutex();
// Crash if |which| is not PRIO_PROCESS. EPERM if |who| is not 0, neither
// |target_pid| while calling setpriority(2) / getpriority(2).
bpf_dsl::ResultExpr RestrictGetSetpriority(pid_t target_pid);
} // namespace sandbox.
#endif // SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SYSCALL_PARAMETERS_RESTRICTIONS_H_
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