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