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/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