1 // Copyright (c) 2012 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 <Cocoa/Cocoa.h> 6 7 #include "base/file_util.h" 8 #include "base/logging.h" 9 #include "base/strings/sys_string_conversions.h" 10 #include "content/common/sandbox_mac.h" 11 #include "content/common/sandbox_mac_unittest_helper.h" 12 #include "crypto/nss_util.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 namespace content { 16 17 //--------------------- Clipboard Sandboxing ---------------------- 18 // Test case for checking sandboxing of clipboard access. 19 class MacSandboxedClipboardTestCase : public MacSandboxTestCase { 20 public: 21 MacSandboxedClipboardTestCase(); 22 virtual ~MacSandboxedClipboardTestCase(); 23 24 virtual bool SandboxedTest() OVERRIDE; 25 26 virtual void SetTestData(const char* test_data) OVERRIDE; 27 private: 28 NSString* clipboard_name_; 29 }; 30 31 REGISTER_SANDBOX_TEST_CASE(MacSandboxedClipboardTestCase); 32 33 MacSandboxedClipboardTestCase::MacSandboxedClipboardTestCase() : 34 clipboard_name_(nil) {} 35 36 MacSandboxedClipboardTestCase::~MacSandboxedClipboardTestCase() { 37 [clipboard_name_ release]; 38 } 39 40 bool MacSandboxedClipboardTestCase::SandboxedTest() { 41 // Shouldn't be able to open the pasteboard in the sandbox. 42 43 if ([clipboard_name_ length] == 0) { 44 LOG(ERROR) << "Clipboard name is empty"; 45 return false; 46 } 47 48 NSPasteboard* pb = [NSPasteboard pasteboardWithName:clipboard_name_]; 49 if (pb != nil) { 50 LOG(ERROR) << "Was able to access named clipboard"; 51 return false; 52 } 53 54 pb = [NSPasteboard generalPasteboard]; 55 if (pb != nil) { 56 LOG(ERROR) << "Was able to access system clipboard"; 57 return false; 58 } 59 60 return true; 61 } 62 63 void MacSandboxedClipboardTestCase::SetTestData(const char* test_data) { 64 clipboard_name_ = [base::SysUTF8ToNSString(test_data) retain]; 65 } 66 67 TEST_F(MacSandboxTest, ClipboardAccess) { 68 NSPasteboard* pb = [NSPasteboard pasteboardWithUniqueName]; 69 EXPECT_EQ([[pb types] count], 0U); 70 71 std::string pasteboard_name = base::SysNSStringToUTF8([pb name]); 72 EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedClipboardTestCase", 73 pasteboard_name.c_str())); 74 75 // After executing the test, the clipboard should still be empty. 76 EXPECT_EQ([[pb types] count], 0U); 77 } 78 79 //--------------------- File Access Sandboxing ---------------------- 80 // Test case for checking sandboxing of filesystem apis. 81 class MacSandboxedFileAccessTestCase : public MacSandboxTestCase { 82 public: 83 virtual bool SandboxedTest() OVERRIDE; 84 }; 85 86 REGISTER_SANDBOX_TEST_CASE(MacSandboxedFileAccessTestCase); 87 88 bool MacSandboxedFileAccessTestCase::SandboxedTest() { 89 int fdes = open("/etc/passwd", O_RDONLY); 90 file_util::ScopedFD file_closer(&fdes); 91 return fdes == -1; 92 } 93 94 TEST_F(MacSandboxTest, FileAccess) { 95 EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedFileAccessTestCase", NULL)); 96 } 97 98 //--------------------- /dev/urandom Sandboxing ---------------------- 99 // /dev/urandom is available to any sandboxed process. 100 class MacSandboxedUrandomTestCase : public MacSandboxTestCase { 101 public: 102 virtual bool SandboxedTest() OVERRIDE; 103 }; 104 105 REGISTER_SANDBOX_TEST_CASE(MacSandboxedUrandomTestCase); 106 107 bool MacSandboxedUrandomTestCase::SandboxedTest() { 108 int fdes = open("/dev/urandom", O_RDONLY); 109 file_util::ScopedFD file_closer(&fdes); 110 111 // Opening /dev/urandom succeeds under the sandbox. 112 if (fdes == -1) 113 return false; 114 115 char buf[16]; 116 int rc = read(fdes, buf, sizeof(buf)); 117 return rc == sizeof(buf); 118 } 119 120 TEST_F(MacSandboxTest, UrandomAccess) { 121 EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedUrandomTestCase", NULL)); 122 } 123 124 //--------------------- NSS Sandboxing ---------------------- 125 // Test case for checking sandboxing of NSS initialization. 126 class MacSandboxedNSSTestCase : public MacSandboxTestCase { 127 public: 128 virtual bool SandboxedTest() OVERRIDE; 129 }; 130 131 REGISTER_SANDBOX_TEST_CASE(MacSandboxedNSSTestCase); 132 133 bool MacSandboxedNSSTestCase::SandboxedTest() { 134 // If NSS cannot read from /dev/urandom, NSS initialization will call abort(), 135 // which will cause this test case to fail. 136 crypto::ForceNSSNoDBInit(); 137 crypto::EnsureNSSInit(); 138 return true; 139 } 140 141 TEST_F(MacSandboxTest, NSSAccess) { 142 EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedNSSTestCase", NULL)); 143 } 144 145 } // namespace content 146