Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 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 #include "sandbox/mac/seatbelt_exec.h" | |
| 6 | |
| 7 #include <sys/socket.h> | |
| 8 #include <sys/uio.h> | |
| 9 #include <unistd.h> | |
| 10 | |
| 11 #include <vector> | |
| 12 | |
| 13 #include "base/logging.h" | |
| 14 #include "base/macros.h" | |
| 15 #include "base/posix/eintr_wrapper.h" | |
| 16 #include "base/strings/stringprintf.h" | |
| 17 #include "sandbox/mac/seatbelt.h" | |
| 18 | |
| 19 namespace sandbox { | |
| 20 | |
| 21 SeatbeltExecClient::SeatbeltExecClient() { | |
| 22 PCHECK(pipe(pipe_) == 0) << "pipe"; | |
| 23 } | |
| 24 | |
| 25 SeatbeltExecClient::~SeatbeltExecClient() { | |
| 26 if (pipe_[1] != -1) | |
| 27 IGNORE_EINTR(close(pipe_[1])); | |
| 28 // If pipe() fails, PCHECK() will be hit in the constructor, so this file | |
| 29 // descriptor should always be closed if the proess is alive at this point. | |
| 30 IGNORE_EINTR(close(pipe_[0])); | |
| 31 } | |
| 32 | |
| 33 bool SeatbeltExecClient::SetBooleanParameter(const std::string& key, | |
| 34 bool value) { | |
| 35 google::protobuf::MapPair<std::string, std::string> pair( | |
| 36 key, value ? "TRUE" : "FALSE"); | |
| 37 return policy_.mutable_params()->insert(pair).second; | |
| 38 } | |
| 39 | |
| 40 bool SeatbeltExecClient::SetParameter(const std::string& key, | |
| 41 const std::string& value) { | |
| 42 google::protobuf::MapPair<std::string, std::string> pair(key, value); | |
| 43 return policy_.mutable_params()->insert(pair).second; | |
| 44 } | |
| 45 | |
| 46 void SeatbeltExecClient::SetProfile(const char* policy) { | |
| 47 policy_.set_profile(policy); | |
| 48 } | |
| 49 | |
| 50 int SeatbeltExecClient::SendProfileAndGetFD() { | |
| 51 std::string serialized_protobuf; | |
| 52 if (!policy_.SerializeToString(&serialized_protobuf)) | |
| 53 return -1; | |
| 54 | |
| 55 if (!WriteString(serialized_protobuf)) | |
| 56 return -1; | |
| 57 | |
| 58 close(pipe_[1]); | |
|
Robert Sesek
2017/05/15 21:05:24
IGNORE_EINTR
Greg K
2017/05/17 17:57:24
Done.
| |
| 59 pipe_[1] = -1; | |
| 60 | |
| 61 return pipe_[0]; | |
| 62 } | |
| 63 | |
| 64 bool SeatbeltExecClient::WriteString(const std::string& str) { | |
| 65 // iov takes a non-const pointer. | |
|
Robert Sesek
2017/05/15 21:05:24
&str[0] is probably const because the arg is. If y
Greg K
2017/05/17 17:57:24
Done.
| |
| 66 char buffer[str.size() + 1]; | |
| 67 memcpy(buffer, str.c_str(), sizeof(buffer)); | |
| 68 | |
| 69 struct iovec iov[1]; | |
| 70 iov[0].iov_base = buffer; | |
| 71 iov[0].iov_len = sizeof(buffer); | |
| 72 | |
| 73 ssize_t written = HANDLE_EINTR(writev(pipe_[1], iov, arraysize(iov))); | |
| 74 if (written < 0) { | |
| 75 PLOG(ERROR) << "writev"; | |
| 76 return false; | |
| 77 } | |
| 78 return static_cast<uint64_t>(written) == str.size(); | |
| 79 } | |
| 80 | |
| 81 SeatbeltExecServer::SeatbeltExecServer(int fd) : fd_(fd) {} | |
| 82 | |
| 83 SeatbeltExecServer::~SeatbeltExecServer() { | |
| 84 close(fd_); | |
|
Robert Sesek
2017/05/15 21:05:24
IGNORE_EINTR
Greg K
2017/05/17 17:57:24
This no longer exists because it uses a ScopedFD.
| |
| 85 } | |
| 86 | |
| 87 int SeatbeltExecServer::InitializeSandbox() { | |
| 88 std::string policy_string; | |
| 89 if (!ReadString(&policy_string)) | |
| 90 return -1; | |
| 91 | |
| 92 mac::SandboxPolicy policy; | |
| 93 if (!policy.ParseFromString(policy_string)) { | |
| 94 LOG(ERROR) << "ParseFromString failed"; | |
| 95 return -1; | |
| 96 } | |
| 97 | |
| 98 return ApplySandboxProfile(policy); | |
| 99 } | |
| 100 | |
| 101 int SeatbeltExecServer::ApplySandboxProfile(const mac::SandboxPolicy& policy) { | |
| 102 std::vector<const char*> weak_params; | |
| 103 for (const auto& pair : policy.params()) { | |
| 104 weak_params.push_back(pair.first.c_str()); | |
| 105 weak_params.push_back(pair.second.c_str()); | |
| 106 } | |
| 107 weak_params.push_back(nullptr); | |
| 108 | |
| 109 char* error = nullptr; | |
| 110 int rv = Seatbelt::InitWithParams(policy.profile().c_str(), 0, | |
| 111 weak_params.data(), &error); | |
| 112 if (error) { | |
| 113 LOG(ERROR) << "Failed to initialize sandbox: " << rv << " " << error; | |
| 114 Seatbelt::FreeError(error); | |
| 115 return rv; | |
| 116 } | |
| 117 | |
| 118 return rv; | |
| 119 } | |
| 120 | |
| 121 bool SeatbeltExecServer::ReadString(std::string* str) { | |
| 122 // 4 pages of memory is enough to hold the sandbox profiles. | |
| 123 std::vector<char> buffer(4096 * 4); | |
| 124 memset(buffer.data(), '\0', buffer.size()); | |
|
Robert Sesek
2017/05/15 21:05:24
Drop the memset in favor of constructor #2
http:/
Greg K
2017/05/17 17:57:24
Done.
| |
| 125 | |
| 126 struct iovec iov[1]; | |
| 127 iov[0].iov_base = buffer.data(); | |
| 128 iov[0].iov_len = buffer.size(); | |
| 129 | |
| 130 ssize_t read_length = HANDLE_EINTR(readv(fd_, iov, arraysize(iov))); | |
| 131 if (read_length < 0) { | |
| 132 PLOG(ERROR) << "readv"; | |
| 133 return false; | |
| 134 } | |
| 135 str->assign(buffer.data()); | |
| 136 return true; | |
| 137 } | |
| 138 | |
| 139 } // namespace sandbox | |
| OLD | NEW |