Home | History | Annotate | Download | only in common
      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