summaryrefslogtreecommitdiffstats
path: root/chrome/test/nacl_security_tests
diff options
context:
space:
mode:
authorjvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-15 23:02:52 +0000
committerjvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-15 23:02:52 +0000
commit23acfc08defd8db4cd54d91e86593baf47b461ea (patch)
treefe9e80355421a03b7fab0bf372834144adf4bd21 /chrome/test/nacl_security_tests
parent9d098779ae0342c1bf8db56d0bacbb57c3858215 (diff)
downloadchromium_src-23acfc08defd8db4cd54d91e86593baf47b461ea.zip
chromium_src-23acfc08defd8db4cd54d91e86593baf47b461ea.tar.gz
chromium_src-23acfc08defd8db4cd54d91e86593baf47b461ea.tar.bz2
Set up tests to exercise the chrome outersandbox from the nacl loader.
It is similar to the renderer sandbox tests in that the test code is separated into a DLL and only loaded based on commandline flags. Currently tests file open, process creation, and connect. This is currently not set up for Linux. To set it up for Linux, we need to be more careful about what tests are expected to pass, and will need to look into zygote process for how to get the test shared lib loaded. BUG=39409 TEST=none Review URL: http://codereview.chromium.org/1549046 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52567 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/nacl_security_tests')
-rw-r--r--chrome/test/nacl_security_tests/commands_posix.cc112
-rw-r--r--chrome/test/nacl_security_tests/commands_posix.h53
-rw-r--r--chrome/test/nacl_security_tests/nacl_security_tests_linux.cc36
-rw-r--r--chrome/test/nacl_security_tests/nacl_security_tests_mac.cc46
-rw-r--r--chrome/test/nacl_security_tests/nacl_security_tests_posix.h12
-rw-r--r--chrome/test/nacl_security_tests/nacl_security_tests_win.cc145
-rw-r--r--chrome/test/nacl_security_tests/nacl_security_tests_win.h12
7 files changed, 416 insertions, 0 deletions
diff --git a/chrome/test/nacl_security_tests/commands_posix.cc b/chrome/test/nacl_security_tests/commands_posix.cc
new file mode 100644
index 0000000..85196e3
--- /dev/null
+++ b/chrome/test/nacl_security_tests/commands_posix.cc
@@ -0,0 +1,112 @@
+// Copyright (c) 2010 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 "./commands_posix.h"
+
+#include <fcntl.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <string>
+
+// Sandbox access tests (mimic'ing "sandbox/tests/validation_tests/commands.h")
+
+namespace sandbox {
+
+SboxTestResult TestOpenReadFile(const char *path) {
+ int fd = open(path, O_RDONLY | O_CREAT);
+ if (-1 == fd) {
+ return SBOX_TEST_DENIED;
+ } else {
+ fprintf(stderr, "OOPS: Opened file for read %s %d\n", path, fd);
+ close(fd);
+ return SBOX_TEST_SUCCEEDED;
+ }
+}
+
+SboxTestResult TestOpenWriteFile(const char *path) {
+ int fd = open(path, O_WRONLY | O_CREAT);
+ if (-1 == fd) {
+ return SBOX_TEST_DENIED;
+ } else {
+ fprintf(stderr, "OOPS: Opened file for write %s %d\n", path, fd);
+ close(fd);
+ return SBOX_TEST_SUCCEEDED;
+ }
+}
+
+SboxTestResult TestCreateProcess(const char *path) {
+ pid_t pid;
+ int exec_res;
+ int child_stat;
+
+ pid = fork();
+ if (0 == pid) {
+ exec_res = execl(path, path, NULL);
+ if (exec_res) {
+ return SBOX_TEST_DENIED;
+ } else {
+ return SBOX_TEST_SUCCEEDED;
+ }
+ return SBOX_TEST_SUCCEEDED;
+ } else if (0 < pid) {
+ fprintf(stderr, "PARENT: Oops, forked child!\n");
+ waitpid(pid, &child_stat, WNOHANG);
+ return SBOX_TEST_SUCCEEDED;
+ } else {
+ return SBOX_TEST_DENIED;
+ }
+}
+
+SboxTestResult TestConnect(const char *url) {
+ int conn_sock;
+ struct addrinfo hints, *servinfo, *p;
+ int rv;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ rv = getaddrinfo(url, "http", &hints, &servinfo);
+ if (0 != rv) {
+ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
+ return SBOX_TEST_DENIED;
+ }
+
+ p = servinfo;
+ // Just try the first entry.
+ conn_sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+ if (-1 == conn_sock) {
+ perror("socket");
+ freeaddrinfo(servinfo);
+ fprintf(stderr, "Error at socket()\n");
+ return SBOX_TEST_DENIED;
+ }
+
+ if (-1 == connect(conn_sock, p->ai_addr, p->ai_addrlen)) {
+ close(conn_sock);
+ freeaddrinfo(servinfo);
+ return SBOX_TEST_DENIED;
+ }
+
+ fprintf(stderr, "Connected to server.\n");
+ shutdown(conn_sock, SHUT_RDWR);
+ close(conn_sock);
+ freeaddrinfo(servinfo);
+ return SBOX_TEST_SUCCEEDED;
+}
+
+// TODO(jvoung): test more: e.g., bind and accept.
+// chmod, unlink, symlink, ... if guaranteed a test file that would normally
+// allow us to do such things (i.e., we want the test operations to be
+// context-independent, yet leave no traces).
+
+SboxTestResult TestDummyFails() {
+ fprintf(stderr, "Running dummy sandbox test, which should fail\n");
+ return SBOX_TEST_SUCCEEDED;
+}
+
+} // namespace sandbox
diff --git a/chrome/test/nacl_security_tests/commands_posix.h b/chrome/test/nacl_security_tests/commands_posix.h
new file mode 100644
index 0000000..95d5647
--- /dev/null
+++ b/chrome/test/nacl_security_tests/commands_posix.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_TEST_NACL_SECURITY_TESTS_COMMANDS_POSIX_H_
+#define CHROME_TEST_NACL_SECURITY_TESTS_COMMANDS_POSIX_H_
+
+// TODO(jvoung): factor out the SboxTestResult from
+// sandbox/tests/common/controller.h
+// to make it OS independent.
+
+namespace sandbox {
+
+#define SEVERITY_INFO_FLAGS 0x40000000
+#define SEVERITY_ERROR_FLAGS 0xC0000000
+#define CUSTOMER_CODE 0x20000000
+#define SBOX_TESTS_FACILITY 0x05B10000
+
+enum SboxTestResult {
+ SBOX_TEST_FIRST_RESULT = 8998,
+ SBOX_TEST_SUCCEEDED,
+ SBOX_TEST_PING_OK,
+ SBOX_TEST_FIRST_INFO = SBOX_TEST_FIRST_RESULT | SEVERITY_INFO_FLAGS,
+ SBOX_TEST_DENIED, // Access was denied.
+ SBOX_TEST_NOT_FOUND, // The resource was not found.
+ SBOX_TEST_FIRST_ERROR = SBOX_TEST_FIRST_RESULT | SEVERITY_ERROR_FLAGS,
+ SBOX_TEST_INVALID_PARAMETER,
+ SBOX_TEST_FAILED_TO_RUN_TEST,
+ SBOX_TEST_FAILED_TO_EXECUTE_COMMAND,
+ SBOX_TEST_TIMED_OUT,
+ SBOX_TEST_FAILED,
+ SBOX_TEST_LAST_RESULT
+};
+
+// Sandbox access tests for Mac and Linux
+// (mimic'ing "sandbox/tests/validation_tests/commands.h")
+
+SboxTestResult TestOpenReadFile(const char* path);
+
+SboxTestResult TestOpenWriteFile(const char* path);
+
+SboxTestResult TestCreateProcess(const char* path);
+
+SboxTestResult TestConnect(const char* url);
+
+// Dummy test that returns SBOX_TEST_SUCCEEDED
+// (so it fails, because everything should be denied).
+SboxTestResult TestDummyFails();
+
+} // namespace sandbox
+
+#endif // CHROME_TEST_NACL_SECURITY_TESTS_COMMANDS_POSIX_H_
+
diff --git a/chrome/test/nacl_security_tests/nacl_security_tests_linux.cc b/chrome/test/nacl_security_tests/nacl_security_tests_linux.cc
new file mode 100644
index 0000000..768aa55
--- /dev/null
+++ b/chrome/test/nacl_security_tests/nacl_security_tests_linux.cc
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 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 "chrome/test/nacl_security_tests/nacl_security_tests_posix.h"
+#include <string>
+#include "chrome/test/nacl_security_tests/commands_posix.h"
+
+#define RETURN_IF_NOT_DENIED(x) \
+ if (sandbox::SBOX_TEST_DENIED != x) { \
+ return false; \
+ }
+
+// Runs the security tests of sandbox for the nacl loader process.
+extern "C" bool RunNaClLoaderTests(void) {
+ // Need to check if the system supports CLONE_NEWPID before testing
+ // the filesystem accesses (otherwise the sandbox is not enabled).
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile("/etc"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile("/tmp"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile("$HOME"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/etc"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/etc/passwd"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/bin"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/usr/bin"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/usr/bin/bash"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/usr/bin/login"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/usr/sbin"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("$HOME"));
+
+ // Linux (suid) sandbox doesn't block connect, etc...
+ RETURN_IF_NOT_DENIED(sandbox::TestCreateProcess("/usr/bin/env"));
+ RETURN_IF_NOT_DENIED(sandbox::TestConnect("www.archive.org"));
+
+ return true;
+}
+
diff --git a/chrome/test/nacl_security_tests/nacl_security_tests_mac.cc b/chrome/test/nacl_security_tests/nacl_security_tests_mac.cc
new file mode 100644
index 0000000..12f7583
--- /dev/null
+++ b/chrome/test/nacl_security_tests/nacl_security_tests_mac.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2010 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 "chrome/test/nacl_security_tests/nacl_security_tests_posix.h"
+#include <string>
+#include "testing/gtest/include/gtest/gtest.h"
+#include "chrome/test/nacl_security_tests/commands_posix.h"
+
+__attribute__((constructor))
+static void initializer(void) {
+}
+
+__attribute__((destructor))
+static void finalizer(void) {
+}
+
+namespace {
+void CheckDenied(sandbox::SboxTestResult x) {
+ EXPECT_EQ(sandbox::SBOX_TEST_DENIED, x);
+}
+} // anon namespace
+
+extern "C"
+__attribute__((visibility("default")))
+bool RunNaClLoaderTests(void) {
+ CheckDenied(sandbox::TestOpenReadFile("/etc"));
+ CheckDenied(sandbox::TestOpenReadFile("/tmp"));
+ CheckDenied(sandbox::TestOpenReadFile("$HOME"));
+ CheckDenied(sandbox::TestOpenWriteFile("/etc"));
+ CheckDenied(sandbox::TestOpenWriteFile("/etc/passwd"));
+ CheckDenied(sandbox::TestOpenWriteFile("/bin"));
+ CheckDenied(sandbox::TestOpenWriteFile("/usr/bin"));
+ CheckDenied(sandbox::TestOpenWriteFile("/usr/bin/bash"));
+ CheckDenied(sandbox::TestOpenWriteFile("/usr/bin/login"));
+ CheckDenied(sandbox::TestOpenWriteFile("/usr/sbin"));
+ CheckDenied(sandbox::TestOpenWriteFile("$HOME"));
+
+ CheckDenied(sandbox::TestCreateProcess("/usr/bin/env"));
+ CheckDenied(sandbox::TestConnect("www.archive.org"));
+
+ return !(testing::Test::HasFatalFailure() ||
+ testing::Test::HasNonfatalFailure());
+}
+
diff --git a/chrome/test/nacl_security_tests/nacl_security_tests_posix.h b/chrome/test/nacl_security_tests/nacl_security_tests_posix.h
new file mode 100644
index 0000000..251e3f0
--- /dev/null
+++ b/chrome/test/nacl_security_tests/nacl_security_tests_posix.h
@@ -0,0 +1,12 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_POSIX_H_
+#define CHROME_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_POSIX_H_
+
+// Runs security tests against the outer sandbox of the nacl loader process.
+extern "C" bool RunNaClLoaderTests(void);
+
+#endif // CHROME_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_POSIX_H_
+
diff --git a/chrome/test/nacl_security_tests/nacl_security_tests_win.cc b/chrome/test/nacl_security_tests/nacl_security_tests_win.cc
new file mode 100644
index 0000000..e95e17f
--- /dev/null
+++ b/chrome/test/nacl_security_tests/nacl_security_tests_win.cc
@@ -0,0 +1,145 @@
+// Copyright (c) 2010 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 "chrome/test/nacl_security_tests/nacl_security_tests_win.h"
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#include <string>
+
+// TODO(jvoung): factor out the enum SboxTestResult from
+// "sandbox/tests/common/controller.h" to make it OS independent
+
+#include "sandbox/tests/common/controller.h"
+#include "sandbox/tests/validation_tests/commands.h"
+
+BOOL APIENTRY DllMain(HMODULE module, DWORD ul_reason_for_call,
+ LPVOID lpReserved) {
+ return TRUE;
+}
+
+#define RETURN_IF_NOT_DENIED(x) \
+ if (sandbox::SBOX_TEST_DENIED != x) { \
+ return false; \
+ }
+
+////////////////////////////////////////////////////////////
+// Additional sandbox access tests
+// (not in "sandbox/tests/validation_tests/commands.h")
+////////////////////////////////////////////////////////////
+
+namespace sandbox {
+
+SboxTestResult TestCreateProcess(const wchar_t *path_str, wchar_t *cmd_str) {
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory(&si, sizeof(si));
+ ZeroMemory(&pi, sizeof(pi));
+ if (!::CreateProcess(path_str, cmd_str, NULL, NULL, FALSE, 0,
+ NULL, NULL, &si, &pi)) {
+ if (ERROR_ACCESS_DENIED == ::GetLastError()) {
+ fprintf(stderr, "Create process denied\n");
+ return SBOX_TEST_DENIED;
+ } else {
+ fprintf(stderr, "Created process denied for misc reason: %ld\n",
+ ::GetLastError());
+ return SBOX_TEST_DENIED;
+ }
+ } else {
+ fprintf(stderr, "Created process\n");
+ return SBOX_TEST_SUCCEEDED;
+ }
+}
+
+SboxTestResult TestConnect(const char* url) {
+ WSADATA wsaData;
+ int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (NO_ERROR != iResult) {
+ fprintf(stderr, "Error at WSAStartup()\n");
+ }
+
+ struct addrinfo hints, *servinfo, *p;
+ DWORD dwRet;
+ ZeroMemory(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ dwRet = getaddrinfo(url, "80", &hints, &servinfo);
+ if (0 != dwRet) {
+ fprintf(stderr, "getaddrinfo failed with %d\n", dwRet);
+ WSACleanup();
+ return SBOX_TEST_DENIED;
+ }
+
+ p = servinfo;
+ // Just try the first entry.
+ SOCKET sock;
+ sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+ if (INVALID_SOCKET == sock) {
+ fprintf(stderr, "Error at socket(): %ld\n", WSAGetLastError());
+ freeaddrinfo(servinfo);
+ WSACleanup();
+ return SBOX_TEST_DENIED;
+ }
+
+ if (SOCKET_ERROR == connect(sock, p->ai_addr,
+ static_cast<int>(p->ai_addrlen))) {
+ fprintf(stderr, "Failed to connect\n");
+ freeaddrinfo(servinfo);
+ closesocket(sock);
+ WSACleanup();
+ return SBOX_TEST_DENIED;
+ }
+
+ fprintf(stderr, "OOPS: Connected to server.\n");
+ freeaddrinfo(servinfo);
+ closesocket(sock);
+ WSACleanup();
+ return SBOX_TEST_SUCCEEDED;
+}
+
+} // namespace sandbox
+
+////////////////////////////////////////////////////////////
+
+
+// Runs the security tests of sandbox for the nacl loader process.
+// If a test fails, the return value is FALSE and test_count contains the
+// number of tests executed, including the failing test.
+extern "C" bool __declspec(dllexport) RunNaClLoaderTests(void) {
+ // Filesystem and Registry tests borrowed from renderer security_tests.dll
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%SystemDrive%"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%SystemRoot%"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%ProgramFiles%"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%SystemRoot%\\System32"));
+ RETURN_IF_NOT_DENIED(
+ sandbox::TestOpenReadFile(L"%SystemRoot%\\explorer.exe"));
+ RETURN_IF_NOT_DENIED(
+ sandbox::TestOpenReadFile(L"%SystemRoot%\\Cursors\\arrow_i.cur"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile(L"%SystemRoot%"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile(L"%ProgramFiles%"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile(L"%SystemRoot%\\System32"));
+ RETURN_IF_NOT_DENIED(
+ sandbox::TestOpenWriteFile(L"%SystemRoot%\\explorer.exe"));
+ RETURN_IF_NOT_DENIED(
+ sandbox::TestOpenWriteFile(L"%SystemRoot%\\Cursors\\arrow_i.cur"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%AllUsersProfile%"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%Temp%"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%AppData%"));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenKey(HKEY_LOCAL_MACHINE, L""));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenKey(HKEY_CURRENT_USER, L""));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenKey(HKEY_USERS, L""));
+ RETURN_IF_NOT_DENIED(sandbox::TestOpenKey(HKEY_LOCAL_MACHINE,
+ L"Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon"));
+
+ RETURN_IF_NOT_DENIED(sandbox::TestConnect("www.archive.org"));
+ RETURN_IF_NOT_DENIED(sandbox::TestConnect("www.google.com"));
+
+ RETURN_IF_NOT_DENIED(sandbox::TestCreateProcess(L"%SystemRoot%\\explorer.exe",
+ L"%SystemRoot%\\explorer.exe"));
+
+ return true;
+}
diff --git a/chrome/test/nacl_security_tests/nacl_security_tests_win.h b/chrome/test/nacl_security_tests/nacl_security_tests_win.h
new file mode 100644
index 0000000..5e3bda6
--- /dev/null
+++ b/chrome/test/nacl_security_tests/nacl_security_tests_win.h
@@ -0,0 +1,12 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_WIN_H_
+#define CHROME_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_WIN_H_
+
+// Runs security tests against the outer sandbox of the nacl loader process.
+extern "C" bool __declspec(dllexport) RunNaClLoaderTests(void);
+
+#endif // CHROME_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_WIN_H_
+