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> 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include <sys/resource.h> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/stat.h> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/types.h> 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/wait.h> 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <unistd.h> 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 15a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include <algorithm> 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 199ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/basictypes.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/file_util.h" 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/files/scoped_file.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 259ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/posix/eintr_wrapper.h" 26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/posix/unix_domain_socket_linux.h" 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "sandbox/linux/tests/test_utils.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sandbox/linux/tests/unit_tests.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sandbox { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass BrokerProcessTestHelper { 34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public: 35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch static int get_ipc_socketpair(const BrokerProcess* broker) { 36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return broker->ipc_socketpair_; 37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}; 39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 409ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochnamespace { 419ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 429ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// Creates and open a temporary file on creation and closes 439ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// and removes it on destruction. 449ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// Unlike base/ helpers, this does not require JNI on Android. 459ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochclass ScopedTemporaryFile { 469ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch public: 479ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch ScopedTemporaryFile() 489ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch : fd_(-1) { 499ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#if defined(OS_ANDROID) 509ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch static const char file_template[] = "/data/local/tmp/ScopedTempFileXXXXXX"; 519ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#else 529ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch static const char file_template[] = "/tmp/ScopedTempFileXXXXXX"; 539ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#endif // defined(OS_ANDROID) 549ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch COMPILE_ASSERT(sizeof(full_file_name_) >= sizeof(file_template), 559ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch full_file_name_is_large_enough); 569ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch memcpy(full_file_name_, file_template, sizeof(file_template)); 579ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch fd_ = mkstemp(full_file_name_); 589ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch CHECK_LE(0, fd_); 599ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch } 609ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch ~ScopedTemporaryFile() { 619ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch CHECK_EQ(0, unlink(full_file_name_)); 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CHECK_EQ(0, IGNORE_EINTR(close(fd_))); 639ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch } 649ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 659ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch int fd() const { return fd_; } 669ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch const char* full_file_name() const { return full_file_name_; } 679ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 689ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch private: 699ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch int fd_; 709ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch char full_file_name_[128]; 719ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch DISALLOW_COPY_AND_ASSIGN(ScopedTemporaryFile); 729ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}; 739ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool NoOpCallback() { return true; } 759ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BrokerProcess, CreateAndDestroy) { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> read_whitelist; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_whitelist.push_back("/proc/cpuinfo"); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<BrokerProcess> open_broker( 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new BrokerProcess(EPERM, read_whitelist, std::vector<std::string>())); 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback))); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(TestUtils::CurrentProcessHasChildren()); 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Destroy the broker and check it has exited properly. 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) open_broker.reset(); 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_FALSE(TestUtils::CurrentProcessHasChildren()); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(BrokerProcess, TestOpenAccessNull) { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<std::string> empty; 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrokerProcess open_broker(EPERM, empty, empty); 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = open_broker.Open(NULL, O_RDONLY); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -EFAULT); 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int ret = open_broker.Access(NULL, F_OK); 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -EFAULT); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TestOpenFilePerms(bool fast_check_in_client, int denied_errno) { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kR_WhiteListed[] = "/proc/DOESNOTEXIST1"; 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We can't debug the init process, and shouldn't be able to access 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // its auxv file. 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char kR_WhiteListedButDenied[] = "/proc/1/auxv"; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kW_WhiteListed[] = "/proc/DOESNOTEXIST2"; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kRW_WhiteListed[] = "/proc/DOESNOTEXIST3"; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char k_NotWhitelisted[] = "/proc/DOESNOTEXIST4"; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> read_whitelist; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_whitelist.push_back(kR_WhiteListed); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) read_whitelist.push_back(kR_WhiteListedButDenied); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_whitelist.push_back(kRW_WhiteListed); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> write_whitelist; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) write_whitelist.push_back(kW_WhiteListed); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) write_whitelist.push_back(kRW_WhiteListed); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrokerProcess open_broker(denied_errno, 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) read_whitelist, 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) write_whitelist, 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fast_check_in_client); 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = -1; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kR_WhiteListed, O_RDONLY); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -ENOENT); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kR_WhiteListed, O_WRONLY); 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kR_WhiteListed, O_RDWR); 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int ret = -1; 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, F_OK); 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, R_OK); 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, W_OK); 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, R_OK | W_OK); 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, X_OK); 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kR_WhiteListed, R_OK | X_OK); 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Android sometimes runs tests as root. 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // This part of the test requires a process that doesn't have 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // CAP_DAC_OVERRIDE. We check against a root euid as a proxy for that. 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (geteuid()) { 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fd = open_broker.Open(kR_WhiteListedButDenied, O_RDONLY); 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // The broker process will allow this, but the normal permission system 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // won't. 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_EQ(fd, -EACCES); 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fd = open_broker.Open(kR_WhiteListedButDenied, O_WRONLY); 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fd = open_broker.Open(kR_WhiteListedButDenied, O_RDWR); 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, F_OK); 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // The normal permission system will let us check that the file exists. 1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_EQ(ret, 0); 1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, R_OK); 1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_EQ(ret, -EACCES); 1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, W_OK); 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, R_OK | W_OK); 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, X_OK); 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ret = open_broker.Access(kR_WhiteListedButDenied, R_OK | X_OK); 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kW_WhiteListed, O_RDONLY); 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kW_WhiteListed, O_WRONLY); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -ENOENT); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kW_WhiteListed, O_RDWR); 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, F_OK); 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, R_OK); 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, W_OK); 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, R_OK | W_OK); 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, X_OK); 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kW_WhiteListed, R_OK | X_OK); 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kRW_WhiteListed, O_RDONLY); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -ENOENT); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kRW_WhiteListed, O_WRONLY); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -ENOENT); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(kRW_WhiteListed, O_RDWR); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -ENOENT); 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, F_OK); 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, R_OK); 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, W_OK); 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, R_OK | W_OK); 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(ret, -ENOENT); 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, X_OK); 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(kRW_WhiteListed, R_OK | X_OK); 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(k_NotWhitelisted, O_RDONLY); 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(k_NotWhitelisted, O_WRONLY); 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker.Open(k_NotWhitelisted, O_RDWR); 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, F_OK); 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, R_OK); 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, W_OK); 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, R_OK | W_OK); 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, X_OK); 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = open_broker.Access(k_NotWhitelisted, R_OK | X_OK); 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(ret, -denied_errno); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We have some extra sanity check for clearly wrong values. 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) fd = open_broker.Open(kRW_WhiteListed, O_RDONLY | O_WRONLY | O_RDWR); 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It makes no sense to allow O_CREAT in a 2-parameters open. Ensure this 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is denied. 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) fd = open_broker.Open(kRW_WhiteListed, O_RDWR | O_CREAT); 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ASSERT_EQ(fd, -denied_errno); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Run the same thing twice. The second time, we make sure that no security 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// check is performed on the client. 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BrokerProcess, OpenFilePermsWithClientCheck) { 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TestOpenFilePerms(true /* fast_check_in_client */, EPERM); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BrokerProcess, OpenOpenFilePermsNoClientCheck) { 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TestOpenFilePerms(false /* fast_check_in_client */, EPERM); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Run the same twice again, but with ENOENT instead of EPERM. 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(BrokerProcess, OpenFilePermsWithClientCheckNoEnt) { 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TestOpenFilePerms(true /* fast_check_in_client */, ENOENT); 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // expected. 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(BrokerProcess, OpenOpenFilePermsNoClientCheckNoEnt) { 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TestOpenFilePerms(false /* fast_check_in_client */, ENOENT); 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // expected. 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestOpenCpuinfo(bool fast_check_in_client) { 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kFileCpuInfo[] = "/proc/cpuinfo"; 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> read_whitelist; 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_whitelist.push_back(kFileCpuInfo); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<BrokerProcess> open_broker(new BrokerProcess( 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EPERM, read_whitelist, std::vector<std::string>(), fast_check_in_client)); 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback))); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = -1; 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd = open_broker->Open(kFileCpuInfo, O_RDWR); 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ScopedFD fd_closer(fd); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fd, -EPERM); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check we can read /proc/cpuinfo. 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int can_access = open_broker->Access(kFileCpuInfo, R_OK); 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(can_access, 0); 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) can_access = open_broker->Access(kFileCpuInfo, W_OK); 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(can_access, -EPERM); 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check we can not write /proc/cpuinfo. 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Open cpuinfo via the broker. 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int cpuinfo_fd = open_broker->Open(kFileCpuInfo, O_RDONLY); 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ScopedFD cpuinfo_fd_closer(cpuinfo_fd); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GE(cpuinfo_fd, 0); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char buf[3]; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memset(buf, 0, sizeof(buf)); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int read_len1 = read(cpuinfo_fd, buf, sizeof(buf)); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GT(read_len1, 0); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Open cpuinfo directly. 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int cpuinfo_fd2 = open(kFileCpuInfo, O_RDONLY); 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ScopedFD cpuinfo_fd2_closer(cpuinfo_fd2); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GE(cpuinfo_fd2, 0); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char buf2[3]; 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memset(buf2, 1, sizeof(buf2)); 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int read_len2 = read(cpuinfo_fd2, buf2, sizeof(buf2)); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GT(read_len1, 0); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The following is not guaranteed true, but will be in practice. 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(read_len1, read_len2); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Compare the cpuinfo as returned by the broker with the one we opened 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ourselves. 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(memcmp(buf, buf2, read_len1), 0); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(TestUtils::CurrentProcessHasChildren()); 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) open_broker.reset(); 317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_FALSE(TestUtils::CurrentProcessHasChildren()); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Run the same thing twice. The second time, we make sure that no security 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// check is performed on the client. 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BrokerProcess, OpenCpuinfoWithClientCheck) { 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestOpenCpuinfo(true /* fast_check_in_client */); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(BrokerProcess, OpenCpuinfoNoClientCheck) { 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestOpenCpuinfo(false /* fast_check_in_client */); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(BrokerProcess, OpenFileRW) { 3359ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch ScopedTemporaryFile tempfile; 3369ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch const char* tempfile_name = tempfile.full_file_name(); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> whitelist; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) whitelist.push_back(tempfile_name); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrokerProcess open_broker(EPERM, whitelist, whitelist); 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check we can access that file with read or write. 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int can_access = open_broker.Access(tempfile_name, R_OK | W_OK); 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(can_access, 0); 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int tempfile2 = -1; 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tempfile2 = open_broker.Open(tempfile_name, O_RDWR); 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GE(tempfile2, 0); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Write to the descriptor opened by the broker. 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char test_text[] = "TESTTESTTEST"; 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ssize_t len = write(tempfile2, test_text, sizeof(test_text)); 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(len, static_cast<ssize_t>(sizeof(test_text))); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Read back from the original file descriptor what we wrote through 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the descriptor provided by the broker. 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char buf[1024]; 3609ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch len = read(tempfile.fd(), buf, sizeof(buf)); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(len, static_cast<ssize_t>(sizeof(test_text))); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(memcmp(test_text, buf, sizeof(test_text)), 0); 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(close(tempfile2), 0); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// SANDBOX_TEST because the process could die with a SIGPIPE 3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// and we want this to happen in a subprocess. 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SANDBOX_TEST(BrokerProcess, BrokerDied) { 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> read_whitelist; 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_whitelist.push_back("/proc/cpuinfo"); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrokerProcess open_broker(EPERM, 3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) read_whitelist, 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string>(), 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true /* fast_check_in_client */, 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true /* quiet_failures_for_tests */); 379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SANDBOX_ASSERT(open_broker.Init(base::Bind(&NoOpCallback))); 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const pid_t broker_pid = open_broker.broker_pid(); 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(kill(broker_pid, SIGKILL) == 0); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Now we check that the broker has been signaled, but do not reap it. 384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) siginfo_t process_info; 385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SANDBOX_ASSERT(HANDLE_EINTR(waitid( 386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) P_PID, broker_pid, &process_info, WEXITED | WNOWAIT)) == 387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 0); 388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SANDBOX_ASSERT(broker_pid == process_info.si_pid); 389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SANDBOX_ASSERT(CLD_KILLED == process_info.si_code); 390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SANDBOX_ASSERT(SIGKILL == process_info.si_status); 391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Check that doing Open with a dead broker won't SIGPIPE us. 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(open_broker.Open("/proc/cpuinfo", O_RDONLY) == -ENOMEM); 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SANDBOX_ASSERT(open_broker.Access("/proc/cpuinfo", O_RDONLY) == -ENOMEM); 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TestOpenComplexFlags(bool fast_check_in_client) { 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char kCpuInfo[] = "/proc/cpuinfo"; 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> whitelist; 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) whitelist.push_back(kCpuInfo); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrokerProcess open_broker(EPERM, 4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) whitelist, 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) whitelist, 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fast_check_in_client); 406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback))); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Test that we do the right thing for O_CLOEXEC and O_NONBLOCK. 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = -1; 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int ret = 0; 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fd = open_broker.Open(kCpuInfo, O_RDONLY); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_GE(fd, 0); 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = fcntl(fd, F_GETFL); 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NE(-1, ret); 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The descriptor shouldn't have the O_CLOEXEC attribute, nor O_NONBLOCK. 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(0, ret & (O_CLOEXEC | O_NONBLOCK)); 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(0, close(fd)); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fd = open_broker.Open(kCpuInfo, O_RDONLY | O_CLOEXEC); 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_GE(fd, 0); 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = fcntl(fd, F_GETFD); 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NE(-1, ret); 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Important: use F_GETFD, not F_GETFL. The O_CLOEXEC flag in F_GETFL 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // is actually not used by the kernel. 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(FD_CLOEXEC & ret); 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(0, close(fd)); 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fd = open_broker.Open(kCpuInfo, O_RDONLY | O_NONBLOCK); 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_GE(fd, 0); 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ret = fcntl(fd, F_GETFL); 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NE(-1, ret); 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(O_NONBLOCK & ret); 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(0, close(fd)); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(BrokerProcess, OpenComplexFlagsWithClientCheck) { 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestOpenComplexFlags(true /* fast_check_in_client */); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(BrokerProcess, OpenComplexFlagsNoClientCheck) { 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestOpenComplexFlags(false /* fast_check_in_client */); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't do anything here, so that ASSERT works in the subfunction as 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected. 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 447a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// We need to allow noise because the broker will log when it receives our 448a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// bogus IPCs. 449a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochSANDBOX_TEST_ALLOW_NOISE(BrokerProcess, RecvMsgDescriptorLeak) { 450a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Find the four lowest available file descriptors. 451a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int available_fds[4]; 452a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SANDBOX_ASSERT(0 == pipe(available_fds)); 453a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SANDBOX_ASSERT(0 == pipe(available_fds + 2)); 454a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 455a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Save one FD to send to the broker later, and close the others. 456a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::ScopedFD message_fd(available_fds[0]); 457a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for (size_t i = 1; i < arraysize(available_fds); i++) { 458a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SANDBOX_ASSERT(0 == IGNORE_EINTR(close(available_fds[i]))); 459a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 460a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 461a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Lower our file descriptor limit to just allow three more file descriptors 462a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // to be allocated. (N.B., RLIMIT_NOFILE doesn't limit the number of file 463a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // descriptors a process can have: it only limits the highest value that can 464a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // be assigned to newly-created descriptors allocated by the process.) 465a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const rlim_t fd_limit = 466a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 1 + *std::max_element(available_fds, 467a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch available_fds + arraysize(available_fds)); 468a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 469a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Valgrind doesn't allow changing the hard descriptor limit, so we only 470a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // change the soft descriptor limit here. 471a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch struct rlimit rlim; 472a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SANDBOX_ASSERT(0 == getrlimit(RLIMIT_NOFILE, &rlim)); 473a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SANDBOX_ASSERT(fd_limit <= rlim.rlim_cur); 474a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch rlim.rlim_cur = fd_limit; 475a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SANDBOX_ASSERT(0 == setrlimit(RLIMIT_NOFILE, &rlim)); 476a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 477a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch static const char kCpuInfo[] = "/proc/cpuinfo"; 478a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::vector<std::string> read_whitelist; 479a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch read_whitelist.push_back(kCpuInfo); 480a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 481a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch BrokerProcess open_broker(EPERM, read_whitelist, std::vector<std::string>()); 482a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SANDBOX_ASSERT(open_broker.Init(base::Bind(&NoOpCallback))); 483a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 484a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const int ipc_fd = BrokerProcessTestHelper::get_ipc_socketpair(&open_broker); 485a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SANDBOX_ASSERT(ipc_fd >= 0); 486a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 487a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch static const char kBogus[] = "not a pickle"; 488a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::vector<int> fds; 489a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch fds.push_back(message_fd.get()); 490a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 491a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // The broker process should only have a couple spare file descriptors 492a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // available, but for good measure we send it fd_limit bogus IPCs anyway. 493a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for (rlim_t i = 0; i < fd_limit; ++i) { 494a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SANDBOX_ASSERT( 495a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch UnixDomainSocket::SendMsg(ipc_fd, kBogus, sizeof(kBogus), fds)); 496a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 497a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 498a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const int fd = open_broker.Open(kCpuInfo, O_RDONLY); 499a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SANDBOX_ASSERT(fd >= 0); 500a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SANDBOX_ASSERT(0 == IGNORE_EINTR(close(fd))); 501a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 502a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace sandbox 504