Index: components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc |
diff --git a/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc b/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc |
index 98e95c266aacbd24f03558d3de73241002ab7462..bd4ab955128fbfe8d5f8e4357f19957f10b5a33d 100644 |
--- a/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc |
+++ b/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc |
@@ -25,6 +25,7 @@ |
#include <time.h> |
#include <unistd.h> |
+#include "base/at_exit.h" |
#include "base/bind.h" |
#include "base/callback.h" |
#include "base/compiler_specific.h" |
@@ -42,6 +43,67 @@ |
#include "sandbox/linux/system_headers/linux_signal.h" |
#include "sandbox/linux/system_headers/linux_syscalls.h" |
+// These defines are for PNaCl toolchain build. |
+#if !defined(F_DUPFD_CLOEXEC) |
+#define F_DUPFD_CLOEXEC 1030 |
+#endif |
+ |
+#if !defined(MAP_POPULATE) |
+#define MAP_POPULATE 0x8000 |
+#endif |
+ |
+#if !defined(PROT_GROWSDOWN) |
+#define PROT_GROWSDOWN 0x01000000 |
+#endif |
+ |
+#if !defined(CLOCK_MONOTONIC_RAW) |
+#define CLOCK_MONOTONIC_RAW 4 |
+#endif |
+ |
+#if !defined(AF_INET) |
+#define AF_INET 2 |
+#endif |
+ |
+#if defined(__i386__) |
+ |
+#if !defined(SYS_SOCKET) |
+#define SYS_SOCKET 1 |
+#endif |
+ |
+#if !defined(SYS_BIND) |
+#define SYS_BIND 2 |
+#endif |
+ |
+#if !defined(SYS_CONNECT) |
+#define SYS_CONNECT 3 |
+#endif |
+ |
+#if !defined(SYS_LISTEN) |
+#define SYS_LISTEN 4 |
+#endif |
+ |
+#if !defined(SYS_ACCEPT) |
+#define SYS_ACCEPT 5 |
+#endif |
+ |
+#if !defined(SYS_GETSOCKNAME) |
+#define SYS_GETSOCKNAME 6 |
+#endif |
+ |
+#if !defined(SYS_GETPEERNAME) |
+#define SYS_GETPEERNAME 7 |
+#endif |
+ |
+#if !defined(SYS_SETSOCKOPT) |
+#define SYS_SETSOCKOPT 14 |
+#endif |
+ |
+#if !defined(SYS_GETSOCKOPT) |
+#define SYS_GETSOCKOPT 15 |
+#endif |
+ |
+#endif // defined(__i386__) |
+ |
namespace { |
void DoPipe(base::ScopedFD* fds) { |
@@ -368,18 +430,28 @@ BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
fcntl(fds[0].get(), F_SETFL, O_APPEND); |
} |
+void DoFcntl(int fd, int cmd) { |
+ // fcntl in PNaCl toolchain returns an error without calling actual system |
+ // call for unknown |cmd|. So, instead, here we use syscall(). |
+#if defined(OS_NACL_NONSFI) |
+ syscall(__NR_fcntl64, fd, cmd); |
+#else |
+ fcntl(fd, cmd); |
+#endif |
+} |
+ |
BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
fcntl_DUPFD, |
DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), |
nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
- fcntl(0, F_DUPFD); |
+ DoFcntl(0, F_DUPFD); |
} |
BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
fcntl_DUPFD_CLOEXEC, |
DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), |
nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
- fcntl(0, F_DUPFD_CLOEXEC); |
+ DoFcntl(0, F_DUPFD_CLOEXEC); |
} |
BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
@@ -403,6 +475,14 @@ BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
BPF_TEST_C(NaClNonSfiSandboxTest, |
StartingAndJoiningThreadWorks, |
nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
+#if defined(OS_NACL_NONSFI) |
+ // base::Thread internally uses LazyInstance, which registers a callback to |
+ // AtExitManager. However, in PNaCl toolchain build, it is not instantiated |
+ // by the test runner, unlike host toolchain build (nacl_loader_unittests). |
+ // Hence, declare it here so that the LazyInstance will work properly. |
+ base::AtExitManager at_exit; |
+#endif |
+ |
base::Thread thread("sandbox_tests"); |
BPF_ASSERT(thread.Start()); |
// |thread|'s destructor will join the thread. |
@@ -417,9 +497,20 @@ BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
_exit(1); |
} |
+void* DoMmap(int prot, int flags) { |
+#if defined(OS_NACL_NONSFI) |
+ // When PROT_EXEC is set, PNaCl toolchain's mmap() system call wrapper uses |
+ // two system calls mmap2(2) and mprotect(2), so that we cannot test |
+ // sandbox with the wrapper. Instead, here we use syscall(). |
+ return reinterpret_cast<void*>( |
+ syscall(__NR_mmap2, NULL, getpagesize(), prot, flags, -1, 0)); |
+#else |
+ return mmap(NULL, getpagesize(), prot, flags, -1, 0); |
+#endif |
+} |
+ |
void* DoAllowedAnonymousMmap() { |
- return mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, |
- MAP_ANONYMOUS | MAP_SHARED, -1, 0); |
+ return DoMmap(PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED); |
} |
BPF_TEST_C(NaClNonSfiSandboxTest, |
@@ -434,45 +525,42 @@ BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
mmap_unallowed_flag, |
DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), |
nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
- mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, |
- MAP_ANONYMOUS | MAP_POPULATE, -1, 0); |
+ DoMmap(PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_POPULATE); |
} |
BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
mmap_unallowed_prot, |
DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), |
nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
- mmap(NULL, getpagesize(), PROT_READ | PROT_GROWSDOWN, |
- MAP_ANONYMOUS, -1, 0); |
+ DoMmap(PROT_READ | PROT_GROWSDOWN, MAP_ANONYMOUS); |
} |
BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
mmap_exec, |
DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), |
nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
- mmap(NULL, getpagesize(), PROT_EXEC, MAP_ANONYMOUS, -1, 0); |
+ DoMmap(PROT_EXEC, MAP_ANONYMOUS); |
} |
BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
mmap_read_exec, |
DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), |
nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
- mmap(NULL, getpagesize(), PROT_READ | PROT_EXEC, MAP_ANONYMOUS, -1, 0); |
+ DoMmap(PROT_READ | PROT_EXEC, MAP_ANONYMOUS); |
} |
BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
mmap_write_exec, |
DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), |
nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
- mmap(NULL, getpagesize(), PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS, -1, 0); |
+ DoMmap(PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS); |
} |
BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
mmap_read_write_exec, |
DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), |
nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
- mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC, |
- MAP_ANONYMOUS, -1, 0); |
+ DoMmap(PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS); |
} |
BPF_TEST_C(NaClNonSfiSandboxTest, |
@@ -503,9 +591,13 @@ BPF_TEST_C(NaClNonSfiSandboxTest, |
// The kernel interface must return zero for brk. |
BPF_ASSERT_EQ(0, syscall(__NR_brk, next_brk)); |
// The libc wrapper translates it to ENOMEM. |
+ |
+ // Note: PNaCl toolchain does not provide brk() system call wrapper. |
+#if !defined(OS_NACL_NONSFI) |
errno = 0; |
BPF_ASSERT_EQ(-1, brk(next_brk)); |
BPF_ASSERT_EQ(ENOMEM, errno); |
+#endif |
} |
// clockid restrictions are mostly tested in sandbox/ with the |