broker_process_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sandbox/linux/services/broker_process.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <errno.h> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <fcntl.h> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/stat.h> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/types.h> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/wait.h> 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <unistd.h> 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 179ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/basictypes.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/file_util.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/files/scoped_file.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 239ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/posix/eintr_wrapper.h" 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "sandbox/linux/tests/test_utils.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sandbox/linux/tests/unit_tests.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sandbox { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 309ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochnamespace { 319ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 329ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// Creates and open a temporary file on creation and closes 339ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// and removes it on destruction. 349ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// Unlike base/ helpers, this does not require JNI on Android. 359ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochclass ScopedTemporaryFile { 369ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch public: 379ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch ScopedTemporaryFile() 389ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch : fd_(-1) { 399ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#if defined(OS_ANDROID) 409ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch static const char file_template[] = "/data/local/tmp/ScopedTempFileXXXXXX"; 419ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#else 429ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch static const char file_template[] = "/tmp/ScopedTempFileXXXXXX"; 439ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#endif // defined(OS_ANDROID) 449ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch COMPILE_ASSERT(sizeof(full_file_name_) >= sizeof(file_template), 459ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch full_file_name_is_large_enough); 469ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch memcpy(full_file_name_, file_template, sizeof(file_template)); 479ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch fd_ = mkstemp(full_file_name_); 489ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch CHECK_LE(0, fd_); 499ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch } 509ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch ~ScopedTemporaryFile() { 519ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch CHECK_EQ(0, unlink(full_file_name_)); 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CHECK_EQ(0, IGNORE_EINTR(close(fd_))); 539ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch } 549ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 559ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch int fd() const { return fd_; } 569ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch const char* full_file_name() const { return full_file_name_; } 579ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 589ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch private: 599ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch int fd_; 609ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch char full_file_name_[128]; 619ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch DISALLOW_COPY_AND_ASSIGN(ScopedTemporaryFile); 629ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}; 639ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool NoOpCallback() { return true; } 659ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BrokerProcess, CreateAndDestroy) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> read_whitelist; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_whitelist.push_back("/proc/cpuinfo"); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<BrokerProcess> open_broker( 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new BrokerProcess(EPERM, read_whitelist, std::vector<std::string>())); 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback))); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(TestUtils::CurrentProcessHasChildren()); 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Destroy the broker and check it has exited properly. 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) open_broker.reset(); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_FALSE(TestUtils::CurrentProcessHasChildren()); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(BrokerProcess, TestOpenAccessNull) { 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<std::string> empty; 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrokerProcess open_broker(EPERM, empty, empty); 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = open_broker.Open(NULL, O_RDONLY); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -EFAULT); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int ret = open_broker.Access(NULL, F_OK); 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -EFAULT); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TestOpenFilePerms(bool fast_check_in_client, int denied_errno) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kR_WhiteListed[] = "/proc/DOESNOTEXIST1"; 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We can't debug the init process, and shouldn't be able to access 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // its auxv file. 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char kR_WhiteListedButDenied[] = "/proc/1/auxv"; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kW_WhiteListed[] = "/proc/DOESNOTEXIST2"; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kRW_WhiteListed[] = "/proc/DOESNOTEXIST3"; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char k_NotWhitelisted[] = "/proc/DOESNOTEXIST4"; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> read_whitelist; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_whitelist.push_back(kR_WhiteListed); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) read_whitelist.push_back(kR_WhiteListedButDenied); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_whitelist.push_back(kRW_WhiteListed); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> write_whitelist; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) write_whitelist.push_back(kW_WhiteListed); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) write_whitelist.push_back(kRW_WhiteListed); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrokerProcess open_broker(denied_errno, 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) read_whitelist, 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) write_whitelist, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fast_check_in_client); 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = -1; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kR_WhiteListed, O_RDONLY); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -ENOENT); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kR_WhiteListed, O_WRONLY); 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kR_WhiteListed, O_RDWR); 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int ret = -1; 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, F_OK); 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, R_OK); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, W_OK); 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, R_OK | W_OK); 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, X_OK); 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, R_OK | X_OK); 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Android sometimes runs tests as root. 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // This part of the test requires a process that doesn't have 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // CAP_DAC_OVERRIDE. We check against a root euid as a proxy for that. 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (geteuid()) { 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fd = open_broker.Open(kR_WhiteListedButDenied, O_RDONLY); 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // The broker process will allow this, but the normal permission system 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // won't. 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_EQ(fd, -EACCES); 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fd = open_broker.Open(kR_WhiteListedButDenied, O_WRONLY); 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fd = open_broker.Open(kR_WhiteListedButDenied, O_RDWR); 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, F_OK); 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // The normal permission system will let us check that the file exists. 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_EQ(ret, 0); 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, R_OK); 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_EQ(ret, -EACCES); 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, W_OK); 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, R_OK | W_OK); 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, X_OK); 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, R_OK | X_OK); 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kW_WhiteListed, O_RDONLY); 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kW_WhiteListed, O_WRONLY); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -ENOENT); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kW_WhiteListed, O_RDWR); 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, F_OK); 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, R_OK); 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, W_OK); 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, R_OK | W_OK); 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, X_OK); 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, R_OK | X_OK); 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kRW_WhiteListed, O_RDONLY); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -ENOENT); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kRW_WhiteListed, O_WRONLY); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -ENOENT); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kRW_WhiteListed, O_RDWR); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -ENOENT); 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, F_OK); 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, R_OK); 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, W_OK); 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, R_OK | W_OK); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, X_OK); 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, R_OK | X_OK); 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(k_NotWhitelisted, O_RDONLY); 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(k_NotWhitelisted, O_WRONLY); 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(k_NotWhitelisted, O_RDWR); 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, F_OK); 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, R_OK); 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, W_OK); 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, R_OK | W_OK); 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, X_OK); 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, R_OK | X_OK); 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We have some extra sanity check for clearly wrong values. 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) fd = open_broker.Open(kRW_WhiteListed, O_RDONLY | O_WRONLY | O_RDWR); 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It makes no sense to allow O_CREAT in a 2-parameters open. Ensure this 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is denied. 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) fd = open_broker.Open(kRW_WhiteListed, O_RDWR | O_CREAT); 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Run the same thing twice. The second time, we make sure that no security 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// check is performed on the client. 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BrokerProcess, OpenFilePermsWithClientCheck) { 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TestOpenFilePerms(true /* fast_check_in_client */, EPERM); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BrokerProcess, OpenOpenFilePermsNoClientCheck) { 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TestOpenFilePerms(false /* fast_check_in_client */, EPERM); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Run the same twice again, but with ENOENT instead of EPERM. 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(BrokerProcess, OpenFilePermsWithClientCheckNoEnt) { 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TestOpenFilePerms(true /* fast_check_in_client */, ENOENT); 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // expected. 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(BrokerProcess, OpenOpenFilePermsNoClientCheckNoEnt) { 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TestOpenFilePerms(false /* fast_check_in_client */, ENOENT); 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // expected. 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestOpenCpuinfo(bool fast_check_in_client) { 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kFileCpuInfo[] = "/proc/cpuinfo"; 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> read_whitelist; 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_whitelist.push_back(kFileCpuInfo); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<BrokerProcess> open_broker(new BrokerProcess( 266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EPERM, read_whitelist, std::vector<std::string>(), fast_check_in_client)); 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback))); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = -1; 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker->Open(kFileCpuInfo, O_RDWR); 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ScopedFD fd_closer(fd); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -EPERM); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check we can read /proc/cpuinfo. 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int can_access = open_broker->Access(kFileCpuInfo, R_OK); 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(can_access, 0); 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) can_access = open_broker->Access(kFileCpuInfo, W_OK); 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(can_access, -EPERM); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check we can not write /proc/cpuinfo. 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Open cpuinfo via the broker. 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int cpuinfo_fd = open_broker->Open(kFileCpuInfo, O_RDONLY); 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ScopedFD cpuinfo_fd_closer(cpuinfo_fd); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GE(cpuinfo_fd, 0); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char buf[3]; 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memset(buf, 0, sizeof(buf)); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int read_len1 = read(cpuinfo_fd, buf, sizeof(buf)); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GT(read_len1, 0); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Open cpuinfo directly. 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int cpuinfo_fd2 = open(kFileCpuInfo, O_RDONLY); 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ScopedFD cpuinfo_fd2_closer(cpuinfo_fd2); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GE(cpuinfo_fd2, 0); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char buf2[3]; 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memset(buf2, 1, sizeof(buf2)); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int read_len2 = read(cpuinfo_fd2, buf2, sizeof(buf2)); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GT(read_len1, 0); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The following is not guaranteed true, but will be in practice. 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(read_len1, read_len2); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Compare the cpuinfo as returned by the broker with the one we opened 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ourselves. 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(memcmp(buf, buf2, read_len1), 0); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(TestUtils::CurrentProcessHasChildren()); 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) open_broker.reset(); 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_FALSE(TestUtils::CurrentProcessHasChildren()); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Run the same thing twice. The second time, we make sure that no security 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// check is performed on the client. 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BrokerProcess, OpenCpuinfoWithClientCheck) { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestOpenCpuinfo(true /* fast_check_in_client */); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BrokerProcess, OpenCpuinfoNoClientCheck) { 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestOpenCpuinfo(false /* fast_check_in_client */); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(BrokerProcess, OpenFileRW) { 3259ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch ScopedTemporaryFile tempfile; 3269ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch const char* tempfile_name = tempfile.full_file_name(); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> whitelist; 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) whitelist.push_back(tempfile_name); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrokerProcess open_broker(EPERM, whitelist, whitelist); 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check we can access that file with read or write. 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int can_access = open_broker.Access(tempfile_name, R_OK | W_OK); 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(can_access, 0); 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int tempfile2 = -1; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tempfile2 = open_broker.Open(tempfile_name, O_RDWR); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GE(tempfile2, 0); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Write to the descriptor opened by the broker. 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char test_text[] = "TESTTESTTEST"; 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ssize_t len = write(tempfile2, test_text, sizeof(test_text)); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(len, static_cast<ssize_t>(sizeof(test_text))); 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Read back from the original file descriptor what we wrote through 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the descriptor provided by the broker. 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char buf[1024]; 3509ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch len = read(tempfile.fd(), buf, sizeof(buf)); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(len, static_cast<ssize_t>(sizeof(test_text))); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(memcmp(test_text, buf, sizeof(test_text)), 0); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(close(tempfile2), 0); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// SANDBOX_TEST because the process could die with a SIGPIPE 3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// and we want this to happen in a subprocess. 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SANDBOX_TEST(BrokerProcess, BrokerDied) { 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> read_whitelist; 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_whitelist.push_back("/proc/cpuinfo"); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrokerProcess open_broker(EPERM, 3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) read_whitelist, 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string>(), 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true /* fast_check_in_client */, 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true /* quiet_failures_for_tests */); 369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SANDBOX_ASSERT(open_broker.Init(base::Bind(&NoOpCallback))); 370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const pid_t broker_pid = open_broker.broker_pid(); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(kill(broker_pid, SIGKILL) == 0); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Now we check that the broker has been signaled, but do not reap it. 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) siginfo_t process_info; 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SANDBOX_ASSERT(HANDLE_EINTR(waitid( 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) P_PID, broker_pid, &process_info, WEXITED | WNOWAIT)) == 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 0); 378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SANDBOX_ASSERT(broker_pid == process_info.si_pid); 379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SANDBOX_ASSERT(CLD_KILLED == process_info.si_code); 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SANDBOX_ASSERT(SIGKILL == process_info.si_status); 381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Check that doing Open with a dead broker won't SIGPIPE us. 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(open_broker.Open("/proc/cpuinfo", O_RDONLY) == -ENOMEM); 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SANDBOX_ASSERT(open_broker.Access("/proc/cpuinfo", O_RDONLY) == -ENOMEM); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TestOpenComplexFlags(bool fast_check_in_client) { 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char kCpuInfo[] = "/proc/cpuinfo"; 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> whitelist; 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) whitelist.push_back(kCpuInfo); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrokerProcess open_broker(EPERM, 3934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) whitelist, 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) whitelist, 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fast_check_in_client); 396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Test that we do the right thing for O_CLOEXEC and O_NONBLOCK. 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = -1; 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int ret = 0; 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fd = open_broker.Open(kCpuInfo, O_RDONLY); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GE(fd, 0); 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = fcntl(fd, F_GETFL); 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NE(-1, ret); 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The descriptor shouldn't have the O_CLOEXEC attribute, nor O_NONBLOCK. 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(0, ret & (O_CLOEXEC | O_NONBLOCK)); 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(0, close(fd)); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fd = open_broker.Open(kCpuInfo, O_RDONLY | O_CLOEXEC); 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_GE(fd, 0); 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = fcntl(fd, F_GETFD); 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NE(-1, ret); 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Important: use F_GETFD, not F_GETFL. The O_CLOEXEC flag in F_GETFL 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // is actually not used by the kernel. 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(FD_CLOEXEC & ret); 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(0, close(fd)); 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fd = open_broker.Open(kCpuInfo, O_RDONLY | O_NONBLOCK); 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_GE(fd, 0); 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = fcntl(fd, F_GETFL); 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NE(-1, ret); 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(O_NONBLOCK & ret); 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(0, close(fd)); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(BrokerProcess, OpenComplexFlagsWithClientCheck) { 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestOpenComplexFlags(true /* fast_check_in_client */); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(BrokerProcess, OpenComplexFlagsNoClientCheck) { 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestOpenComplexFlags(false /* fast_check_in_client */); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace sandbox 438