Chromium Code Reviews| Index: sandbox/mac/seatbelt_exec.cc |
| diff --git a/sandbox/mac/seatbelt_exec.cc b/sandbox/mac/seatbelt_exec.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..11a3a247f63278e13317b727550bbcbf5e7e48f4 |
| --- /dev/null |
| +++ b/sandbox/mac/seatbelt_exec.cc |
| @@ -0,0 +1,146 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "sandbox/mac/seatbelt_exec.h" |
| + |
| +#include <sys/socket.h> |
| +#include <sys/uio.h> |
| +#include <unistd.h> |
| + |
| +#include <vector> |
| + |
| +#include "base/logging.h" |
| +#include "base/posix/eintr_wrapper.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "sandbox/mac/seatbelt.h" |
| + |
| +namespace sandbox { |
| + |
| +SeatbeltExecClient::SeatbeltExecClient() { |
| + PCHECK(pipe(pipe_) == 0) << "pipe"; |
| +} |
| + |
| +SeatbeltExecClient::~SeatbeltExecClient() { |
| + if (!got_fd_) |
| + close(pipe_[1]); |
|
Robert Sesek
2017/05/10 15:25:28
Use IGNORE_EINTR.
Greg K
2017/05/11 17:44:15
Done.
|
| + |
| + close(pipe_[0]); |
|
Robert Sesek
2017/05/10 15:25:29
Same.
Greg K
2017/05/11 17:44:15
Done.
|
| +} |
| + |
| +bool SeatbeltExecClient::SetBooleanParameter(const std::string& key, |
| + bool value) { |
| + google::protobuf::MapPair<std::string, std::string> pair( |
| + key, value ? "TRUE" : "FALSE"); |
| + return params_.mutable_params()->insert(pair).second; |
| +} |
| + |
| +bool SeatbeltExecClient::SetParameter(const std::string& key, |
| + const std::string& value) { |
| + google::protobuf::MapPair<std::string, std::string> pair(key, value); |
| + return params_.mutable_params()->insert(pair).second; |
| +} |
| + |
| +void SeatbeltExecClient::SetPolicy(const char* policy) { |
| + params_.set_policy(policy); |
| +} |
| + |
| +int SeatbeltExecClient::GetSandboxFD() { |
| + std::string serialized_protobuf; |
| + if (!params_.SerializeToString(&serialized_protobuf)) |
| + LOG(FATAL) << "failed to serialize protobuf"; |
|
Robert Sesek
2017/05/10 15:25:29
Why is this LOG(FATAL) and not a return -1?
Greg K
2017/05/11 17:44:15
Done.
|
| + |
| + if (!WriteString(serialized_protobuf)) |
| + return -1; |
| + |
| + got_fd_ = true; |
| + close(pipe_[1]); |
| + |
| + return pipe_[0]; |
| +} |
| + |
| +bool SeatbeltExecClient::WriteString(const std::string& str) { |
| + // iov takes a non-const pointer. |
|
Robert Sesek
2017/05/10 15:25:28
Can you use &str[0] ?
Greg K
2017/05/11 17:44:15
The compiler says that &str[0] is also a const cha
|
| + char buffer[str.size() + 1]; |
| + memcpy(buffer, str.c_str(), sizeof(buffer)); |
| + |
| + struct iovec iov[1]; |
| + iov[0].iov_base = buffer; |
| + iov[0].iov_len = sizeof(buffer); |
| + |
| + ssize_t written = |
| + HANDLE_EINTR(writev(pipe_[1], iov, sizeof(iov) / sizeof(iov[0]))); |
|
Robert Sesek
2017/05/10 15:25:28
Use arraysize().
Greg K
2017/05/11 17:44:15
Done.
|
| + if (written < 0) |
| + return false; |
|
Robert Sesek
2017/05/10 15:25:29
PLOG(ERROR)?
Greg K
2017/05/11 17:44:15
Done.
|
| + return static_cast<uint64_t>(written) == str.size(); |
| +} |
| + |
| +SeatbeltExecServer::SeatbeltExecServer(int fd) : fd_(fd) {} |
| + |
| +SeatbeltExecServer::~SeatbeltExecServer() { |
| + close(fd_); |
| +} |
| + |
| +void SeatbeltExecServer::AllowProcessExec(const std::string& exec_path) { |
| + exec_path_ = exec_path; |
| +} |
| + |
| +int SeatbeltExecServer::InitializeSandbox() { |
| + std::string params_string; |
| + if (!ReadString(¶ms_string)) { |
| + LOG(ERROR) << "ReadString"; |
|
Robert Sesek
2017/05/10 15:25:28
Not necessary to log here since ReadString logs in
Greg K
2017/05/11 17:44:15
Done.
|
| + return -1; |
| + } |
| + |
| + mac::SandboxParams params; |
| + if (!params.ParseFromString(params_string)) { |
| + LOG(ERROR) << "ParseFromString failed"; |
| + return -1; |
| + } |
| + |
| + return ApplySandboxProfile(params); |
| +} |
| + |
| +int SeatbeltExecServer::ApplySandboxProfile(const mac::SandboxParams& params) { |
| + std::vector<const char*> weak_params; |
| + for (const auto& pair : params.params()) { |
| + weak_params.push_back(pair.first.c_str()); |
| + weak_params.push_back(pair.second.c_str()); |
| + } |
| + weak_params.push_back("EXECUTABLE_PATH"); |
| + weak_params.push_back(exec_path_.c_str()); |
| + weak_params.push_back("CHROMIUM_PID"); |
|
Robert Sesek
2017/05/10 15:25:28
What's with this magic variable? //sandbox general
Greg K
2017/05/11 17:44:15
The calling code will just add those as parameters
|
| + weak_params.push_back(std::to_string(getppid()).c_str()); |
| + weak_params.push_back(nullptr); |
| + |
| + char* error = nullptr; |
| + int rv = Seatbelt::InitWithParams(params.policy().c_str(), 0, |
| + weak_params.data(), &error); |
| + if (error) { |
| + LOG(ERROR) << "Failed to initialize sandbox: -" << rv << " " << error; |
|
Robert Sesek
2017/05/10 17:53:28
No need for the negative sign in the string, appar
Greg K
2017/05/11 17:44:15
Done.
|
| + Seatbelt::FreeError(error); |
| + return rv; |
| + } |
| + |
| + return rv; |
| +} |
| + |
| +bool SeatbeltExecServer::ReadString(std::string* str) { |
| + // 4 pages of memory is enough to hold the sandbox profiles. |
| + char buffer[4096 * 4]; |
|
Robert Sesek
2017/05/10 15:25:29
Use std::vector<char> instead.
Greg K
2017/05/11 17:44:15
Done.
|
| + memset(buffer, '\0', sizeof(buffer)); |
| + |
| + struct iovec iov[1]; |
| + iov[0].iov_base = buffer; |
| + iov[0].iov_len = sizeof(buffer); |
| + |
| + ssize_t read_length = readv(fd_, iov, sizeof(iov) / sizeof(iov[0])); |
|
Robert Sesek
2017/05/10 15:25:28
HANDLE_EINTR
Robert Sesek
2017/05/10 15:25:28
Use arraysize().
Greg K
2017/05/11 17:44:14
Done.
Greg K
2017/05/11 17:44:15
Done.
Greg K
2017/05/11 17:44:15
Done.
|
| + if (read_length < 0) { |
| + PLOG(ERROR) << "ReadString"; |
|
Robert Sesek
2017/05/10 15:25:28
"readv" not "ReadString"
Greg K
2017/05/11 17:44:14
Done.
|
| + return false; |
| + } |
| + str->assign(buffer); |
| + return true; |
| +} |
| + |
| +} // namespace sandbox |