Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #import <Foundation/Foundation.h> | |
| 6 #import <IOSurface/IOSurface.h> | |
| 7 | |
| 8 #include <fcntl.h> | |
| 9 #include <stdint.h> | |
| 10 #include <sys/mman.h> | |
| 11 #include <sys/types.h> | |
| 12 #include <sys/stat.h> | |
| 13 #include <sys/sysctl.h> | |
| 14 #include <unistd.h> | |
| 15 | |
| 16 #include "base/files/file.h" | |
| 17 #include "base/files/file_path.h" | |
| 18 #include "base/mac/mac_util.h" | |
| 19 #include "base/process/kill.h" | |
| 20 #include "base/test/multiprocess_test.h" | |
| 21 #include "base/test/test_timeouts.h" | |
| 22 #include "sandbox/mac/sandbox_compiler.h" | |
| 23 #include "testing/gtest/include/gtest/gtest.h" | |
| 24 #include "testing/multiprocess_func_list.h" | |
| 25 | |
| 26 namespace sandbox { | |
| 27 | |
| 28 // These tests are designed to begin testing the V2 style sandbox rules on the | |
| 29 // bots, rendering the earliest possible test results on how the rules perform | |
| 30 // consistently across all test bots and supported OS versions. | |
| 31 class SandboxMacCompilerV2Test : public base::MultiProcessTest {}; | |
| 32 | |
| 33 MULTIPROCESS_TEST_MAIN(V2ProfileProcess) { | |
| 34 // Note: newlines are not necessary in the profile, but do make it easier to | |
| 35 // print the profile out for debugging purposes. | |
| 36 std::string profile = | |
| 37 "(version 1)\n" | |
| 38 "(deny default)\n" | |
| 39 "(define allowed-dir \"ALLOWED_READ_DIR\")\n" | |
| 40 "(define temp-file \"ALLOWED_TEMP_FILE\")\n" | |
| 41 "(define is-pre-10_10 \"IS_PRE_10_10\")\n" | |
| 42 "; Make it easier to drop (literal) once we stop supporting 10.9\n" | |
| 43 "(define (path x) (literal x))\n" | |
| 44 "(allow file-read-metadata (subpath \"/Applications\"))\n" | |
| 45 "(allow file-read* (subpath (param allowed-dir)))\n" | |
| 46 "(allow file-read-data (path \"/usr/share/zoneinfo/zone.tab\"))\n" | |
| 47 "(allow file-write* (path (param temp-file)))\n" | |
| 48 "(allow ipc-posix-shm-read-data (ipc-posix-name " | |
| 49 "\"apple.shm.notification_center\"))\n" | |
| 50 "(allow mach-lookup (global-name \"com.apple.logd\"))\n" | |
| 51 "(allow sysctl-read (sysctl-name \"hw.activecpu\"))\n"; | |
| 52 | |
| 53 std::string temp_file_path = "/private/tmp/sf234234wfsfsdfdsf"; | |
| 54 SandboxCompiler compiler(profile); | |
| 55 CHECK(compiler.InsertStringParam("ALLOWED_READ_DIR", "/usr/lib")); | |
| 56 CHECK(compiler.InsertStringParam("ALLOWED_TEMP_FILE", temp_file_path)); | |
| 57 CHECK(compiler.InsertBooleanParam("IS_PRE_10_10", | |
| 58 !base::mac::IsAtLeastOS10_10())); | |
| 59 | |
| 60 std::string error; | |
| 61 bool result = compiler.CompileAndApplyProfile(&error); | |
| 62 CHECK(result) << error; | |
|
Robert Sesek
2017/02/07 21:13:39
Use ASSERT_TRUE instead of CHECK.
Greg K
2017/02/08 00:25:44
Unfortunately the ASSERT_* macros don't work in th
| |
| 63 | |
| 64 // Now attempt the appropriate resource access. | |
| 65 base::FilePath path("/usr/lib/libsandbox.dylib"); | |
| 66 base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); | |
| 67 CHECK(file.IsValid()); | |
| 68 | |
| 69 char buf[4096]; | |
| 70 EXPECT_EQ(static_cast<int>(sizeof(buf)), | |
| 71 file.Read(/*offset=*/0, buf, sizeof(buf))); | |
| 72 file.Close(); // Protect again other checks accidentally using this file. | |
| 73 | |
| 74 struct stat sb; | |
| 75 EXPECT_EQ(0, stat("/Applications/TextEdit.app", &sb)); | |
| 76 | |
| 77 base::FilePath zone_path("/usr/share/zoneinfo/zone.tab"); | |
| 78 base::File zone_file(zone_path, | |
| 79 base::File::FLAG_OPEN | base::File::FLAG_READ); | |
| 80 CHECK(zone_file.IsValid()); | |
| 81 | |
| 82 char zone_buf[2]; | |
| 83 EXPECT_EQ(static_cast<int>(sizeof(zone_buf)), | |
| 84 zone_file.Read(/*offset=*/0, zone_buf, sizeof(zone_buf))); | |
| 85 zone_file.Close(); | |
| 86 | |
| 87 // Make sure we cannot read any files in zoneinfo. | |
| 88 base::FilePath zone_dir_path("/usr/share/zoneinfo"); | |
| 89 base::File zoneinfo(zone_dir_path, | |
| 90 base::File::FLAG_OPEN | base::File::FLAG_READ); | |
| 91 EXPECT_FALSE(zoneinfo.IsValid()); | |
| 92 | |
| 93 base::FilePath temp_path(temp_file_path); | |
| 94 base::File temp_file(temp_path, | |
| 95 base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE); | |
| 96 CHECK(temp_file.IsValid()); | |
| 97 | |
| 98 const char msg[] = "I can write this file."; | |
| 99 EXPECT_EQ(static_cast<int>(sizeof(msg)), | |
| 100 temp_file.WriteAtCurrentPos(msg, sizeof(msg))); | |
| 101 temp_file.Close(); | |
| 102 | |
| 103 int shm_fd = shm_open("apple.shm.notification_center", O_RDONLY, 0644); | |
| 104 EXPECT_GE(shm_fd, 0); | |
| 105 | |
| 106 NSPort* mach = [[NSMachBootstrapServer sharedInstance] | |
| 107 servicePortWithName:@"com.apple.logd"]; | |
| 108 EXPECT_NE(nil, mach); | |
| 109 | |
| 110 NSPort* forbidden_mach = [[NSMachBootstrapServer sharedInstance] | |
| 111 servicePortWithName:@"com.apple.fonts."]; | |
| 112 EXPECT_EQ(nil, forbidden_mach); | |
| 113 | |
| 114 size_t oldp_len; | |
| 115 EXPECT_EQ(0, sysctlbyname("hw.activecpu", NULL, &oldp_len, NULL, 0)); | |
| 116 | |
| 117 char oldp[oldp_len]; | |
| 118 EXPECT_EQ(0, sysctlbyname("hw.activecpu", oldp, &oldp_len, NULL, 0)); | |
| 119 | |
| 120 size_t ncpu_len; | |
| 121 EXPECT_NE(0, sysctlbyname("hw.ncpu", NULL, &ncpu_len, NULL, 0)); | |
| 122 | |
| 123 return 0; | |
| 124 } | |
| 125 | |
| 126 TEST_F(SandboxMacCompilerV2Test, V2ProfileTest) { | |
| 127 base::Process process = SpawnChild("V2ProfileProcess"); | |
| 128 ASSERT_TRUE(process.IsValid()); | |
| 129 int exit_code = 42; | |
| 130 EXPECT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), | |
| 131 &exit_code)); | |
| 132 EXPECT_EQ(exit_code, 0); | |
| 133 } | |
| 134 | |
| 135 } // namespace sandbox | |
| OLD | NEW |