Commit 54407b42 authored by Matthew Denton's avatar Matthew Denton Committed by Commit Bot

Allow restricted clock_nanosleep in Linux sandbox

To support glibc 2.30, allow clock_nanosleep in the baseline BPF
policy, with the same clock_id restrictions as clock_gettime and
other clock_* syscalls.

Bug: 1025739
Change-Id: Ic53a782fef01049bc61c535b50735a4a7d4c23c0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1935715
Commit-Queue: Matthew Denton <mpdenton@chromium.org>
Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719421}
parent d1bda4df
...@@ -148,7 +148,7 @@ ResultExpr EvaluateSyscallImpl(int fs_denied_errno, ...@@ -148,7 +148,7 @@ ResultExpr EvaluateSyscallImpl(int fs_denied_errno,
return Allow(); return Allow();
#endif #endif
if (sysno == __NR_clock_gettime) { if (sysno == __NR_clock_gettime || sysno == __NR_clock_nanosleep) {
return RestrictClockID(); return RestrictClockID();
} }
......
...@@ -398,6 +398,17 @@ BPF_DEATH_TEST_C(BaselinePolicy, ...@@ -398,6 +398,17 @@ BPF_DEATH_TEST_C(BaselinePolicy,
syscall(SYS_clock_gettime, (~0) | CLOCKFD, &ts); syscall(SYS_clock_gettime, (~0) | CLOCKFD, &ts);
} }
BPF_DEATH_TEST_C(BaselinePolicy,
ClockNanosleepWithDisallowedClockCrashes,
DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()),
BaselinePolicy) {
struct timespec ts;
struct timespec out_ts;
ts.tv_sec = 0;
ts.tv_nsec = 0;
syscall(SYS_clock_nanosleep, (~0) | CLOCKFD, 0, &ts, &out_ts);
}
#if !defined(GRND_RANDOM) #if !defined(GRND_RANDOM)
#define GRND_RANDOM 2 #define GRND_RANDOM 2
#endif #endif
......
...@@ -86,13 +86,13 @@ SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictPrlimit64(pid_t target_pid); ...@@ -86,13 +86,13 @@ SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictPrlimit64(pid_t target_pid);
// process). // process).
SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictGetrusage(); SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictGetrusage();
// Restrict |clk_id| for clock_getres(), clock_gettime() and clock_settime(). We // Restrict |clk_id| for clock_getres(), clock_gettime(), clock_settime(), and
// allow accessing only CLOCK_BOOTTIME, CLOCK_MONOTONIC{,_RAW,_COARSE}, // clock_nanosleep(). We allow accessing only CLOCK_BOOTTIME,
// CLOCK_PROCESS_CPUTIME_ID, CLOCK_REALTIME{,_COARSE}, and // CLOCK_MONOTONIC{,_RAW,_COARSE}, CLOCK_PROCESS_CPUTIME_ID,
// CLOCK_THREAD_CPUTIME_ID. In particular, this disallows access to arbitrary // CLOCK_REALTIME{,_COARSE}, and CLOCK_THREAD_CPUTIME_ID. In particular, on
// per-{process,thread} CPU-time clock IDs (such as those returned by // non-Android platforms this disallows access to arbitrary per-{process,thread}
// {clock,pthread}_getcpuclockid), which can leak information about the state of // CPU-time clock IDs (such as those returned by {clock,pthread}_getcpuclockid),
// the host OS. // which can leak information about the state of the host OS.
SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictClockID(); SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictClockID();
// Restrict the flags argument to getrandom() to allow only no flags, or // Restrict the flags argument to getrandom() to allow only no flags, or
......
...@@ -59,6 +59,7 @@ class RestrictClockIdPolicy : public bpf_dsl::Policy { ...@@ -59,6 +59,7 @@ class RestrictClockIdPolicy : public bpf_dsl::Policy {
switch (sysno) { switch (sysno) {
case __NR_clock_gettime: case __NR_clock_gettime:
case __NR_clock_getres: case __NR_clock_getres:
case __NR_clock_nanosleep:
return RestrictClockID(); return RestrictClockID();
default: default:
return Allow(); return Allow();
...@@ -98,6 +99,25 @@ BPF_TEST_C(ParameterRestrictions, ...@@ -98,6 +99,25 @@ BPF_TEST_C(ParameterRestrictions,
#endif #endif
} }
void CheckClockNanosleep(clockid_t clockid) {
struct timespec ts;
struct timespec out_ts;
ts.tv_sec = 0;
ts.tv_nsec = 0;
clock_nanosleep(clockid, 0, &ts, &out_ts);
}
BPF_TEST_C(ParameterRestrictions,
clock_nanosleep_allowed,
RestrictClockIdPolicy) {
CheckClockNanosleep(CLOCK_MONOTONIC);
CheckClockNanosleep(CLOCK_MONOTONIC_COARSE);
CheckClockNanosleep(CLOCK_MONOTONIC_RAW);
CheckClockNanosleep(CLOCK_BOOTTIME);
CheckClockNanosleep(CLOCK_REALTIME);
CheckClockNanosleep(CLOCK_REALTIME_COARSE);
}
BPF_DEATH_TEST_C(ParameterRestrictions, BPF_DEATH_TEST_C(ParameterRestrictions,
clock_gettime_crash_clock_fd, clock_gettime_crash_clock_fd,
DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
...@@ -106,6 +126,17 @@ BPF_DEATH_TEST_C(ParameterRestrictions, ...@@ -106,6 +126,17 @@ BPF_DEATH_TEST_C(ParameterRestrictions,
syscall(SYS_clock_gettime, (~0) | CLOCKFD, &ts); syscall(SYS_clock_gettime, (~0) | CLOCKFD, &ts);
} }
BPF_DEATH_TEST_C(ParameterRestrictions,
clock_nanosleep_crash_clock_fd,
DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
RestrictClockIdPolicy) {
struct timespec ts;
struct timespec out_ts;
ts.tv_sec = 0;
ts.tv_nsec = 0;
syscall(SYS_clock_nanosleep, (~0) | CLOCKFD, 0, &ts, &out_ts);
}
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
BPF_DEATH_TEST_C(ParameterRestrictions, BPF_DEATH_TEST_C(ParameterRestrictions,
clock_gettime_crash_cpu_clock, clock_gettime_crash_cpu_clock,
......
...@@ -35,9 +35,10 @@ bool SyscallSets::IsAllowedGettime(int sysno) { ...@@ -35,9 +35,10 @@ bool SyscallSets::IsAllowedGettime(int sysno) {
return true; return true;
case __NR_adjtimex: // Privileged. case __NR_adjtimex: // Privileged.
case __NR_clock_adjtime: // Privileged. case __NR_clock_adjtime: // Privileged.
case __NR_clock_getres: // Could be allowed. case __NR_clock_getres: // Allowed only on Android with parameters
case __NR_clock_gettime: // filtered by RestrictClokID().
case __NR_clock_nanosleep: // Could be allowed. case __NR_clock_gettime: // Parameters filtered by RestrictClockID().
case __NR_clock_nanosleep: // Parameters filtered by RestrictClockID().
case __NR_clock_settime: // Privileged. case __NR_clock_settime: // Privileged.
#if defined(__i386__) || \ #if defined(__i386__) || \
(defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS)) (defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS))
......
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