summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorjln <jln@chromium.org>2014-09-11 19:47:44 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-12 02:53:00 +0000
commitfcdfb1094c7db30011101c0442957b8e1b5252d1 (patch)
tree23ec244b8f3bfe7b009020ed67834c51b780d632 /sandbox
parentc6d19cf91bc709f1fa52b4e9e4a44dc4eb5562be (diff)
downloadchromium_src-fcdfb1094c7db30011101c0442957b8e1b5252d1.zip
chromium_src-fcdfb1094c7db30011101c0442957b8e1b5252d1.tar.gz
chromium_src-fcdfb1094c7db30011101c0442957b8e1b5252d1.tar.bz2
Linux sandbox: move RestrictClockID() to sandbox/
We move RestrictClockID() from the NaCl NonSFI sandbox to the main helpers in sandbox/. BUG=413469 TBR=brettw Review URL: https://codereview.chromium.org/563043005 Cr-Commit-Position: refs/heads/master@{#294533}
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/linux/BUILD.gn1
-rw-r--r--sandbox/linux/sandbox_linux_test_sources.gypi1
-rw-r--r--sandbox/linux/seccomp-bpf-helpers/DEPS1
-rw-r--r--sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc17
-rw-r--r--sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h9
-rw-r--r--sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc136
6 files changed, 165 insertions, 0 deletions
diff --git a/sandbox/linux/BUILD.gn b/sandbox/linux/BUILD.gn
index 708543f..b2521af 100644
--- a/sandbox/linux/BUILD.gn
+++ b/sandbox/linux/BUILD.gn
@@ -96,6 +96,7 @@ test("sandbox_linux_unittests") {
"bpf_dsl/bpf_dsl_unittest.cc",
"bpf_dsl/cons_unittest.cc",
"seccomp-bpf-helpers/baseline_policy_unittest.cc",
+ "seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc",
"seccomp-bpf/bpf_tests_unittest.cc",
"seccomp-bpf/codegen_unittest.cc",
"seccomp-bpf/errorcode_unittest.cc",
diff --git a/sandbox/linux/sandbox_linux_test_sources.gypi b/sandbox/linux/sandbox_linux_test_sources.gypi
index c2f365b..75717ea 100644
--- a/sandbox/linux/sandbox_linux_test_sources.gypi
+++ b/sandbox/linux/sandbox_linux_test_sources.gypi
@@ -37,6 +37,7 @@
'bpf_dsl/bpf_dsl_unittest.cc',
'bpf_dsl/cons_unittest.cc',
'seccomp-bpf-helpers/baseline_policy_unittest.cc',
+ 'seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc',
'seccomp-bpf/bpf_tests_unittest.cc',
'seccomp-bpf/codegen_unittest.cc',
'seccomp-bpf/errorcode_unittest.cc',
diff --git a/sandbox/linux/seccomp-bpf-helpers/DEPS b/sandbox/linux/seccomp-bpf-helpers/DEPS
index d4b2611..01e1fe2 100644
--- a/sandbox/linux/seccomp-bpf-helpers/DEPS
+++ b/sandbox/linux/seccomp-bpf-helpers/DEPS
@@ -2,4 +2,5 @@ include_rules = [
"+sandbox/linux/bpf_dsl",
"+sandbox/linux/services",
"+sandbox/linux/seccomp-bpf",
+ "+third_party/lss/linux_syscall_support.h",
]
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
index b61b8ea..94c2333 100644
--- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
@@ -18,11 +18,13 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
+#include <time.h>
#include <unistd.h>
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
#include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
@@ -247,4 +249,19 @@ ResultExpr RestrictGetSetpriority(pid_t target_pid) {
.Else(CrashSIGSYS());
}
+ResultExpr RestrictClockID() {
+ COMPILE_ASSERT(4 == sizeof(clockid_t), clockid_is_not_32bit);
+ const Arg<clockid_t> clockid(0);
+ return If(
+#if defined(OS_CHROMEOS)
+ // Allow the special clock for Chrome OS used by Chrome tracing.
+ clockid == base::TimeTicks::kClockSystemTrace ||
+#endif
+ clockid == CLOCK_MONOTONIC ||
+ clockid == CLOCK_PROCESS_CPUTIME_ID ||
+ clockid == CLOCK_REALTIME ||
+ clockid == CLOCK_THREAD_CPUTIME_ID,
+ Allow()).Else(CrashSIGSYS());
+}
+
} // namespace sandbox.
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h
index 7a0c197..6509f3f 100644
--- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h
+++ b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h
@@ -66,6 +66,15 @@ bpf_dsl::ResultExpr RestrictFutex();
// |target_pid| while calling setpriority(2) / getpriority(2).
bpf_dsl::ResultExpr RestrictGetSetpriority(pid_t target_pid);
+// 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.
+// On Chrome OS, base::TimeTicks::kClockSystemTrace is also allowed.
+SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictClockID();
+
} // namespace sandbox.
#endif // SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SYSCALL_PARAMETERS_RESTRICTIONS_H_
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc
new file mode 100644
index 0000000..d631bb0
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc
@@ -0,0 +1,136 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
+
+#include <time.h>
+
+#include "base/sys_info.h"
+#include "base/time/time.h"
+#include "build/build_config.h"
+#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
+#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
+#include "sandbox/linux/seccomp-bpf/bpf_tests.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
+#include "sandbox/linux/seccomp-bpf/syscall.h"
+#include "sandbox/linux/services/linux_syscalls.h"
+#include "sandbox/linux/tests/unit_tests.h"
+#include "third_party/lss/linux_syscall_support.h" // for MAKE_PROCESS_CPUCLOCK
+
+namespace sandbox {
+
+namespace {
+
+// NOTE: most of the parameter restrictions are tested in
+// baseline_policy_unittest.cc as a more end-to-end test.
+
+using sandbox::bpf_dsl::Allow;
+using sandbox::bpf_dsl::ResultExpr;
+using sandbox::bpf_dsl::SandboxBPFDSLPolicy;
+
+class RestrictClockIdPolicy : public SandboxBPFDSLPolicy {
+ public:
+ RestrictClockIdPolicy() {}
+ virtual ~RestrictClockIdPolicy() {}
+
+ virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE {
+ switch (sysno) {
+ case __NR_clock_gettime:
+ case __NR_clock_getres:
+ return RestrictClockID();
+ default:
+ return Allow();
+ }
+ }
+};
+
+void CheckClock(clockid_t clockid) {
+ struct timespec ts;
+ ts.tv_sec = ts.tv_nsec = -1;
+ BPF_ASSERT_EQ(0, clock_gettime(clockid, &ts));
+ BPF_ASSERT_LE(0, ts.tv_sec);
+ BPF_ASSERT_LE(0, ts.tv_nsec);
+}
+
+BPF_TEST_C(ParameterRestrictions,
+ clock_gettime_allowed,
+ RestrictClockIdPolicy) {
+ CheckClock(CLOCK_MONOTONIC);
+ CheckClock(CLOCK_PROCESS_CPUTIME_ID);
+ CheckClock(CLOCK_REALTIME);
+ CheckClock(CLOCK_THREAD_CPUTIME_ID);
+}
+
+BPF_DEATH_TEST_C(ParameterRestrictions,
+ clock_gettime_crash_monotonic_raw,
+ DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+ RestrictClockIdPolicy) {
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+}
+
+#if defined(OS_CHROMEOS)
+
+// A custom BPF tester delegate to run IsRunningOnChromeOS() before
+// the sandbox is enabled because we cannot run it with non-SFI BPF
+// sandbox enabled.
+class ClockSystemTesterDelegate : public sandbox::BPFTesterDelegate {
+ public:
+ ClockSystemTesterDelegate()
+ : is_running_on_chromeos_(base::SysInfo::IsRunningOnChromeOS()) {}
+ virtual ~ClockSystemTesterDelegate() {}
+
+ virtual scoped_ptr<sandbox::SandboxBPFPolicy> GetSandboxBPFPolicy() OVERRIDE {
+ return scoped_ptr<sandbox::SandboxBPFPolicy>(
+ new RestrictClockIdPolicy());
+ }
+ virtual void RunTestFunction() OVERRIDE {
+ if (is_running_on_chromeos_) {
+ CheckClock(base::TimeTicks::kClockSystemTrace);
+ } else {
+ struct timespec ts;
+ // kClockSystemTrace is 11, which is CLOCK_THREAD_CPUTIME_ID of
+ // the init process (pid=1). If kernel supports this feature,
+ // this may succeed even if this is not running on Chrome OS. We
+ // just check this clock_gettime call does not crash.
+ clock_gettime(base::TimeTicks::kClockSystemTrace, &ts);
+ }
+ }
+
+ private:
+ const bool is_running_on_chromeos_;
+ DISALLOW_COPY_AND_ASSIGN(ClockSystemTesterDelegate);
+};
+
+BPF_TEST_D(BPFTest, BPFTestWithDelegateClass, ClockSystemTesterDelegate);
+
+#elif defined(OS_LINUX)
+
+BPF_DEATH_TEST_C(ParameterRestrictions,
+ clock_gettime_crash_system_trace,
+ DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+ RestrictClockIdPolicy) {
+ struct timespec ts;
+ clock_gettime(base::TimeTicks::kClockSystemTrace, &ts);
+}
+
+#endif // defined(OS_CHROMEOS)
+
+BPF_DEATH_TEST_C(ParameterRestrictions,
+ clock_gettime_crash_cpu_clock,
+ DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+ RestrictClockIdPolicy) {
+ // We can't use clock_getcpuclockid() because it's not implemented in newlib,
+ // and it might not work inside the sandbox anyway.
+ const pid_t kInitPID = 1;
+ const clockid_t kInitCPUClockID =
+ MAKE_PROCESS_CPUCLOCK(kInitPID, CPUCLOCK_SCHED);
+
+ struct timespec ts;
+ clock_gettime(kInitCPUClockID, &ts);
+}
+
+} // namespace
+
+} // namespace sandbox