diff options
author | Matthew Denton <mpdenton@chromium.org> | 2020-01-16 16:07:28 +0100 |
---|---|---|
committer | Kirill Burtsev <kirill.burtsev@qt.io> | 2020-03-02 14:26:28 +0000 |
commit | 3239a38a9b35d29e483b7bd67b786b4f9d109908 (patch) | |
tree | aa364c9c44d403cc63004849c05e1cfbf0b5c11a | |
parent | 07787da493d9a71b994582904a188a53aae9e473 (diff) | |
download | qtwebengine-chromium-3239a38a9b35d29e483b7bd67b786b4f9d109908.tar.gz |
[Backport] 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
Task-number: QTBUG-81313
Change-Id: I2632dfb79182aa781388716c4a47c4ce1853ba30
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 0f7953646c107d5227b8daf2a2464618eee1fddf)
5 files changed, 54 insertions, 10 deletions
diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc index 806d13c1a84..768025ce192 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc @@ -148,7 +148,7 @@ ResultExpr EvaluateSyscallImpl(int fs_denied_errno, return Allow(); #endif - if (sysno == __NR_clock_gettime) { + if (sysno == __NR_clock_gettime || sysno == __NR_clock_nanosleep) { return RestrictClockID(); } diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc index b56b2944f17..34f0a26d07a 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc @@ -397,6 +397,17 @@ BPF_DEATH_TEST_C(BaselinePolicy, syscall(SYS_clock_gettime, CLOCK_MONOTONIC_RAW, &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) #define GRND_RANDOM 2 #endif diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h index cb563dfc550..15442892bcb 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h @@ -86,12 +86,13 @@ SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictPrlimit64(pid_t target_pid); // process). SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictGetrusage(); -// Restrict |clk_id| for clock_getres(), clock_gettime() and clock_settime(). -// We allow accessing only CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID, -// CLOCK_REALTIME, and CLOCK_THREAD_CPUTIME_ID. In particular, this disallows -// access to arbitrary per-{process,thread} CPU-time clock IDs (such as those -// returned by {clock,pthread}_getcpuclockid), which can leak information -// about the state of the host OS. +// Restrict |clk_id| for clock_getres(), clock_gettime(), clock_settime(), and +// clock_nanosleep(). We allow accessing only CLOCK_BOOTTIME, +// CLOCK_MONOTONIC{,_RAW,_COARSE}, CLOCK_PROCESS_CPUTIME_ID, +// CLOCK_REALTIME{,_COARSE}, and CLOCK_THREAD_CPUTIME_ID. In particular, on +// non-Android platforms this disallows access to arbitrary per-{process,thread} +// CPU-time clock IDs (such as those returned by {clock,pthread}_getcpuclockid), +// which can leak information about the state of the host OS. SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictClockID(); // Restrict the flags argument to getrandom() to allow only no flags, or diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc index fdd954cc0fd..f002d45f813 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc @@ -59,6 +59,7 @@ class RestrictClockIdPolicy : public bpf_dsl::Policy { switch (sysno) { case __NR_clock_gettime: case __NR_clock_getres: + case __NR_clock_nanosleep: return RestrictClockID(); default: return Allow(); @@ -99,6 +100,25 @@ BPF_TEST_C(ParameterRestrictions, #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, clock_gettime_crash_monotonic_raw, DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), @@ -107,6 +127,17 @@ BPF_DEATH_TEST_C(ParameterRestrictions, syscall(SYS_clock_gettime, CLOCK_MONOTONIC_RAW, &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) BPF_DEATH_TEST_C(ParameterRestrictions, clock_gettime_crash_cpu_clock, diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc index 4e0ad046299..d9d18822f67 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc @@ -35,9 +35,10 @@ bool SyscallSets::IsAllowedGettime(int sysno) { return true; case __NR_adjtimex: // Privileged. case __NR_clock_adjtime: // Privileged. - case __NR_clock_getres: // Could be allowed. - case __NR_clock_gettime: - case __NR_clock_nanosleep: // Could be allowed. + case __NR_clock_getres: // Allowed only on Android with parameters + // filtered by RestrictClokID(). + case __NR_clock_gettime: // Parameters filtered by RestrictClockID(). + case __NR_clock_nanosleep: // Parameters filtered by RestrictClockID(). case __NR_clock_settime: // Privileged. #if defined(__i386__) || \ (defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS)) |