Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1198)

Unified Diff: sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc

Issue 348853006: Linux sandbox: add test to ensure that pread64 can be forwarded. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Exclude Android from new test. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sandbox/linux/sandbox_linux_test_sources.gypi ('k') | sandbox/linux/seccomp-bpf/syscall_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
index 06ba2090c915a4ba2429406943da893ec906d76f..95fcbc6b5eb800906fe6e2ef319066825b48b5b5 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
@@ -34,6 +34,7 @@
#include "sandbox/linux/seccomp-bpf/verifier.h"
#include "sandbox/linux/services/broker_process.h"
#include "sandbox/linux/services/linux_syscalls.h"
+#include "sandbox/linux/tests/scoped_temporary_file.h"
#include "sandbox/linux/tests/unit_tests.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -53,6 +54,17 @@ namespace {
const int kExpectedReturnValue = 42;
const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING";
+// Set the global environment to allow the use of UnsafeTrap() policies.
+void EnableUnsafeTraps() {
+ // The use of UnsafeTrap() causes us to print a warning message. This is
+ // generally desirable, but it results in the unittest failing, as it doesn't
+ // expect any messages on "stderr". So, temporarily disable messages. The
+ // BPF_TEST() is guaranteed to turn messages back on, after the policy
+ // function has completed.
+ setenv(kSandboxDebuggingEnv, "t", 0);
+ Die::SuppressInfoMessages(true);
+}
+
// This test should execute no matter whether we have kernel support. So,
// we make it a TEST() instead of a BPF_TEST().
TEST(SandboxBPF, DISABLE_ON_TSAN(CallSupports)) {
@@ -480,13 +492,10 @@ intptr_t CountSyscalls(const struct arch_seccomp_data& args, void* aux) {
}
ErrorCode GreyListedPolicy(SandboxBPF* sandbox, int sysno, int* aux) {
- // The use of UnsafeTrap() causes us to print a warning message. This is
- // generally desirable, but it results in the unittest failing, as it doesn't
- // expect any messages on "stderr". So, temporarily disable messages. The
- // BPF_TEST() is guaranteed to turn messages back on, after the policy
- // function has completed.
- setenv(kSandboxDebuggingEnv, "t", 0);
- Die::SuppressInfoMessages(true);
+ // Set the global environment for unsafe traps once.
+ if (sysno == MIN_SYSCALL) {
+ EnableUnsafeTraps();
+ }
// Some system calls must always be allowed, if our policy wants to make
// use of UnsafeTrap()
@@ -2059,6 +2068,88 @@ SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) {
}
}
+// Android does not expose pread64 nor pwrite64.
+#if !defined(OS_ANDROID)
+
+bool FullPwrite64(int fd, const char* buffer, size_t count, off64_t offset) {
+ while (count > 0) {
+ const ssize_t transfered =
+ HANDLE_EINTR(pwrite64(fd, buffer, count, offset));
+ if (transfered <= 0 || static_cast<size_t>(transfered) > count) {
+ return false;
+ }
+ count -= transfered;
+ buffer += transfered;
+ offset += transfered;
+ }
+ return true;
+}
+
+bool FullPread64(int fd, char* buffer, size_t count, off64_t offset) {
+ while (count > 0) {
+ const ssize_t transfered = HANDLE_EINTR(pread64(fd, buffer, count, offset));
+ if (transfered <= 0 || static_cast<size_t>(transfered) > count) {
+ return false;
+ }
+ count -= transfered;
+ buffer += transfered;
+ offset += transfered;
+ }
+ return true;
+}
+
+bool pread_64_was_forwarded = false;
+
+class TrapPread64Policy : public SandboxBPFPolicy {
+ public:
+ TrapPread64Policy() {}
+ virtual ~TrapPread64Policy() {}
+
+ virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
+ int system_call_number) const OVERRIDE {
+ // Set the global environment for unsafe traps once.
+ if (system_call_number == MIN_SYSCALL) {
+ EnableUnsafeTraps();
+ }
+
+ if (system_call_number == __NR_pread64) {
+ return sandbox_compiler->UnsafeTrap(ForwardPreadHandler, NULL);
+ }
+ return ErrorCode(ErrorCode::ERR_ALLOWED);
+ }
+
+ private:
+ static intptr_t ForwardPreadHandler(const struct arch_seccomp_data& args,
+ void* aux) {
+ BPF_ASSERT(args.nr == __NR_pread64);
+ pread_64_was_forwarded = true;
+
+ return SandboxBPF::ForwardSyscall(args);
+ }
+ DISALLOW_COPY_AND_ASSIGN(TrapPread64Policy);
+};
+
+// pread(2) takes a 64 bits offset. On 32 bits systems, it will be split
+// between two arguments. In this test, we make sure that ForwardSyscall() can
+// forward it properly.
+BPF_TEST_C(SandboxBPF, Pread64, TrapPread64Policy) {
+ ScopedTemporaryFile temp_file;
+ const uint64_t kLargeOffset = (static_cast<uint64_t>(1) << 32) | 0xBEEF;
mdempsky 2014/06/27 00:37:24 Might also be worth testing an offset in [2^31, 2^
jln (very slow on Chromium) 2014/06/27 01:25:14 Great point! I'll land as-is because of a time con
+ const char kTestString[] = "This is a test!";
+ BPF_ASSERT(FullPwrite64(
+ temp_file.fd(), kTestString, sizeof(kTestString), kLargeOffset));
+
+ char read_test_string[sizeof(kTestString)] = {0};
+ BPF_ASSERT(FullPread64(temp_file.fd(),
+ read_test_string,
+ sizeof(read_test_string),
+ kLargeOffset));
+ BPF_ASSERT_EQ(0, memcmp(kTestString, read_test_string, sizeof(kTestString)));
+ BPF_ASSERT(pread_64_was_forwarded);
+}
+
+#endif // !defined(OS_ANDROID)
+
} // namespace
} // namespace sandbox
« no previous file with comments | « sandbox/linux/sandbox_linux_test_sources.gypi ('k') | sandbox/linux/seccomp-bpf/syscall_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698