Internal change.

PiperOrigin-RevId: 265057217
Change-Id: Id00c867b373dbe8c9112c23ef4b0300ed3ca9e5b
This commit is contained in:
Christian Blichmann 2019-08-23 08:08:23 -07:00 committed by Copybara-Service
parent d91879f752
commit 276b7efc92
29 changed files with 316 additions and 321 deletions

View File

@ -23,62 +23,62 @@
namespace sapi {
::sapi::Status RPCChannel::Call(const FuncCall& call, uint32_t tag,
FuncRet* ret, v::Type exp_type) {
sapi::Status RPCChannel::Call(const FuncCall& call, uint32_t tag, FuncRet* ret,
v::Type exp_type) {
absl::MutexLock lock(&mutex_);
if (!comms_->SendTLV(tag, sizeof(call),
reinterpret_cast<const uint8_t*>(&call))) {
return ::sapi::UnavailableError("Sending TLV value failed");
return sapi::UnavailableError("Sending TLV value failed");
}
SAPI_ASSIGN_OR_RETURN(auto fret, Return(exp_type));
*ret = fret;
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::StatusOr<FuncRet> RPCChannel::Return(v::Type exp_type) {
sapi::StatusOr<FuncRet> RPCChannel::Return(v::Type exp_type) {
uint32_t tag;
uint64_t len;
FuncRet ret;
if (!comms_->RecvTLV(&tag, &len, &ret, sizeof(ret))) {
return ::sapi::UnavailableError("Receiving TLV value failed");
return sapi::UnavailableError("Receiving TLV value failed");
}
if (tag != comms::kMsgReturn) {
LOG(ERROR) << "tag != comms::kMsgReturn (" << absl::StrCat(absl::Hex(tag))
<< " != " << absl::StrCat(absl::Hex(comms::kMsgReturn)) << ")";
return ::sapi::UnavailableError("Received TLV has incorrect tag");
return sapi::UnavailableError("Received TLV has incorrect tag");
}
if (len != sizeof(FuncRet)) {
LOG(ERROR) << "len != sizeof(FuncReturn) (" << len
<< " != " << sizeof(FuncRet) << ")";
return ::sapi::UnavailableError("Received TLV has incorrect length");
return sapi::UnavailableError("Received TLV has incorrect length");
}
if (ret.ret_type != exp_type) {
LOG(ERROR) << "FuncRet->type != exp_type (" << ret.ret_type
<< " != " << exp_type << ")";
return ::sapi::UnavailableError("Received TLV has incorrect return type");
return sapi::UnavailableError("Received TLV has incorrect return type");
}
if (!ret.success) {
LOG(ERROR) << "FuncRet->success == false";
return ::sapi::UnavailableError("Function call failed");
return sapi::UnavailableError("Function call failed");
}
return ret;
}
::sapi::Status RPCChannel::Allocate(size_t size, void** addr) {
sapi::Status RPCChannel::Allocate(size_t size, void** addr) {
absl::MutexLock lock(&mutex_);
uint64_t sz = size;
if (!comms_->SendTLV(comms::kMsgAllocate, sizeof(sz),
reinterpret_cast<uint8_t*>(&sz))) {
return ::sapi::UnavailableError("Sending TLV value failed");
return sapi::UnavailableError("Sending TLV value failed");
}
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kPointer));
*addr = reinterpret_cast<void*>(fret.int_val);
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status RPCChannel::Reallocate(void* old_addr, size_t size,
void** new_addr) {
sapi::Status RPCChannel::Reallocate(void* old_addr, size_t size,
void** new_addr) {
absl::MutexLock lock(&mutex_);
comms::ReallocRequest req;
req.old_addr = reinterpret_cast<uint64_t>(old_addr);
@ -86,54 +86,54 @@ namespace sapi {
if (!comms_->SendTLV(comms::kMsgReallocate, sizeof(comms::ReallocRequest),
reinterpret_cast<uint8_t*>(&req))) {
return ::sapi::UnavailableError("Sending TLV value failed");
return sapi::UnavailableError("Sending TLV value failed");
}
auto fret_or = Return(v::Type::kPointer);
if (!fret_or.ok()) {
*new_addr = nullptr;
return ::sapi::UnavailableError(
return sapi::UnavailableError(
absl::StrCat("Reallocate() failed on the remote side: ",
fret_or.status().message()));
}
auto fret = std::move(fret_or).ValueOrDie();
*new_addr = reinterpret_cast<void*>(fret.int_val);
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status RPCChannel::Free(void* addr) {
sapi::Status RPCChannel::Free(void* addr) {
absl::MutexLock lock(&mutex_);
uint64_t remote = reinterpret_cast<uint64_t>(addr);
if (!comms_->SendTLV(comms::kMsgFree, sizeof(remote),
reinterpret_cast<uint8_t*>(&remote))) {
return ::sapi::UnavailableError("Sending TLV value failed");
return sapi::UnavailableError("Sending TLV value failed");
}
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
if (!fret.success) {
return ::sapi::UnavailableError("Free() failed on the remote side");
return sapi::UnavailableError("Free() failed on the remote side");
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status RPCChannel::Symbol(const char* symname, void** addr) {
sapi::Status RPCChannel::Symbol(const char* symname, void** addr) {
absl::MutexLock lock(&mutex_);
if (!comms_->SendTLV(comms::kMsgSymbol, strlen(symname) + 1,
reinterpret_cast<const uint8_t*>(symname))) {
return ::sapi::UnavailableError("Sending TLV value failed");
return sapi::UnavailableError("Sending TLV value failed");
}
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kPointer));
*addr = reinterpret_cast<void*>(fret.int_val);
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status RPCChannel::Exit() {
sapi::Status RPCChannel::Exit() {
absl::MutexLock lock(&mutex_);
if (comms_->IsTerminated()) {
VLOG(2) << "Comms channel already terminated";
return ::sapi::OkStatus();
return sapi::OkStatus();
}
// Try the RPC exit sequence. But, the only thing that matters as a success
@ -146,62 +146,62 @@ namespace sapi {
if (!comms_->IsTerminated()) {
LOG(ERROR) << "Comms channel not terminated in Exit()";
// TODO(hamacher): Better error code
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
"Comms channel not terminated in Exit()");
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status RPCChannel::SendFD(int local_fd, int* remote_fd) {
sapi::Status RPCChannel::SendFD(int local_fd, int* remote_fd) {
absl::MutexLock lock(&mutex_);
bool unused = true;
if (!comms_->SendTLV(comms::kMsgSendFd, sizeof(unused),
reinterpret_cast<uint8_t*>(&unused))) {
return ::sapi::UnavailableError("Sending TLV value failed");
return sapi::UnavailableError("Sending TLV value failed");
}
if (!comms_->SendFD(local_fd)) {
return ::sapi::UnavailableError("Sending FD failed");
return sapi::UnavailableError("Sending FD failed");
}
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kInt));
if (!fret.success) {
return ::sapi::UnavailableError("SendFD failed on the remote side");
return sapi::UnavailableError("SendFD failed on the remote side");
}
*remote_fd = fret.int_val;
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status RPCChannel::RecvFD(int remote_fd, int* local_fd) {
sapi::Status RPCChannel::RecvFD(int remote_fd, int* local_fd) {
absl::MutexLock lock(&mutex_);
if (!comms_->SendTLV(comms::kMsgRecvFd, sizeof(remote_fd),
reinterpret_cast<uint8_t*>(&remote_fd))) {
return ::sapi::UnavailableError("Sending TLV value failed");
return sapi::UnavailableError("Sending TLV value failed");
}
if (!comms_->RecvFD(local_fd)) {
return ::sapi::UnavailableError("Receving FD failed");
return sapi::UnavailableError("Receving FD failed");
}
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
if (!fret.success) {
return ::sapi::UnavailableError("RecvFD failed on the remote side");
return sapi::UnavailableError("RecvFD failed on the remote side");
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status RPCChannel::Close(int remote_fd) {
sapi::Status RPCChannel::Close(int remote_fd) {
absl::MutexLock lock(&mutex_);
if (!comms_->SendTLV(comms::kMsgClose, sizeof(remote_fd),
reinterpret_cast<uint8_t*>(&remote_fd))) {
return ::sapi::UnavailableError("Sending TLV value failed");
return sapi::UnavailableError("Sending TLV value failed");
}
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
if (!fret.success) {
return ::sapi::UnavailableError("Close() failed on the remote side");
return sapi::UnavailableError("Close() failed on the remote side");
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
} // namespace sapi

View File

@ -33,38 +33,38 @@ class RPCChannel {
explicit RPCChannel(sandbox2::Comms* comms) : comms_(comms) {}
// Calls a function.
::sapi::Status Call(const FuncCall& call, uint32_t tag, FuncRet* ret,
v::Type exp_type);
sapi::Status Call(const FuncCall& call, uint32_t tag, FuncRet* ret,
v::Type exp_type);
// Allocates memory.
::sapi::Status Allocate(size_t size, void** addr);
sapi::Status Allocate(size_t size, void** addr);
// Reallocates memory.
::sapi::Status Reallocate(void* old_addr, size_t size, void** new_addr);
sapi::Status Reallocate(void* old_addr, size_t size, void** new_addr);
// Frees memory.
::sapi::Status Free(void* addr);
sapi::Status Free(void* addr);
// Returns address of a symbol.
::sapi::Status Symbol(const char* symname, void** addr);
sapi::Status Symbol(const char* symname, void** addr);
// Makes the remote part exit.
::sapi::Status Exit();
sapi::Status Exit();
// Transfers fd to sandboxee.
::sapi::Status SendFD(int local_fd, int* remote_fd);
sapi::Status SendFD(int local_fd, int* remote_fd);
// Retrieves fd from sandboxee.
::sapi::Status RecvFD(int remote_fd, int* local_fd);
sapi::Status RecvFD(int remote_fd, int* local_fd);
// Closes fd in sandboxee.
::sapi::Status Close(int remote_fd);
sapi::Status Close(int remote_fd);
sandbox2::Comms* comms() const { return comms_; }
private:
// Receives the result after a call.
::sapi::StatusOr<FuncRet> Return(v::Type exp_type);
sapi::StatusOr<FuncRet> Return(v::Type exp_type);
sandbox2::Comms* comms_; // Owned by sandbox2;
absl::Mutex mutex_;

View File

@ -128,10 +128,10 @@ static std::string PathToSAPILib(const std::string& lib_path) {
: sandbox2::GetDataDependencyFilePath(lib_path);
}
::sapi::Status Sandbox::Init() {
sapi::Status Sandbox::Init() {
// It's already initialized
if (IsActive()) {
return ::sapi::OkStatus();
return sapi::OkStatus();
}
// Initialize the forkserver if it is not already running.
@ -146,14 +146,14 @@ static std::string PathToSAPILib(const std::string& lib_path) {
if (embed_lib_fd == -1) {
PLOG(ERROR) << "Cannot create executable FD for TOC:'"
<< embed_lib_toc_->name << "'";
return ::sapi::UnavailableError("Could not create executable FD");
return sapi::UnavailableError("Could not create executable FD");
}
lib_path = embed_lib_toc_->name;
} else {
lib_path = PathToSAPILib(GetLibPath());
if (lib_path.empty()) {
LOG(ERROR) << "SAPI library path is empty";
return ::sapi::FailedPreconditionError("No SAPI library path given");
return sapi::FailedPreconditionError("No SAPI library path given");
}
}
@ -173,7 +173,7 @@ static std::string PathToSAPILib(const std::string& lib_path) {
if (!fork_client_) {
LOG(ERROR) << "Could not start forkserver";
return ::sapi::UnavailableError("Could not start the forkserver");
return sapi::UnavailableError("Could not start the forkserver");
}
}
@ -210,38 +210,38 @@ static std::string PathToSAPILib(const std::string& lib_path) {
if (!res) {
Terminate();
return ::sapi::UnavailableError("Could not start the sandbox");
return sapi::UnavailableError("Could not start the sandbox");
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
bool Sandbox::IsActive() const { return s2_ && !s2_->IsTerminated(); }
::sapi::Status Sandbox::Allocate(v::Var* var, bool automatic_free) {
sapi::Status Sandbox::Allocate(v::Var* var, bool automatic_free) {
if (!IsActive()) {
return ::sapi::UnavailableError("Sandbox not active");
return sapi::UnavailableError("Sandbox not active");
}
return var->Allocate(GetRpcChannel(), automatic_free);
}
::sapi::Status Sandbox::Free(v::Var* var) {
sapi::Status Sandbox::Free(v::Var* var) {
if (!IsActive()) {
return ::sapi::UnavailableError("Sandbox not active");
return sapi::UnavailableError("Sandbox not active");
}
return var->Free(GetRpcChannel());
}
::sapi::Status Sandbox::SynchronizePtrBefore(v::Callable* ptr) {
sapi::Status Sandbox::SynchronizePtrBefore(v::Callable* ptr) {
if (!IsActive()) {
return ::sapi::UnavailableError("Sandbox not active");
return sapi::UnavailableError("Sandbox not active");
}
if (ptr->GetType() != v::Type::kPointer) {
return ::sapi::OkStatus();
return sapi::OkStatus();
}
// Cast is safe, since type is v::Type::kPointer
auto* p = static_cast<v::Ptr*>(ptr);
if (p->GetSyncType() == v::Pointable::SYNC_NONE) {
return ::sapi::OkStatus();
return sapi::OkStatus();
}
if (p->GetPointedVar()->GetRemote() == nullptr) {
@ -254,7 +254,7 @@ bool Sandbox::IsActive() const { return s2_ && !s2_->IsTerminated(); }
// memory is transferred to the sandboxee only if v::Pointable::SYNC_BEFORE
// was requested.
if ((p->GetSyncType() & v::Pointable::SYNC_BEFORE) == 0) {
return ::sapi::OkStatus();
return sapi::OkStatus();
}
VLOG(3) << "Synchronization (TO), ptr " << p << ", Type: " << p->GetSyncType()
@ -263,16 +263,16 @@ bool Sandbox::IsActive() const { return s2_ && !s2_->IsTerminated(); }
return p->GetPointedVar()->TransferToSandboxee(GetRpcChannel(), GetPid());
}
::sapi::Status Sandbox::SynchronizePtrAfter(v::Callable* ptr) const {
sapi::Status Sandbox::SynchronizePtrAfter(v::Callable* ptr) const {
if (!IsActive()) {
return ::sapi::UnavailableError("Sandbox not active");
return sapi::UnavailableError("Sandbox not active");
}
if (ptr->GetType() != v::Type::kPointer) {
return ::sapi::OkStatus();
return sapi::OkStatus();
}
v::Ptr* p = reinterpret_cast<v::Ptr*>(ptr);
if ((p->GetSyncType() & v::Pointable::SYNC_AFTER) == 0) {
return ::sapi::OkStatus();
return sapi::OkStatus();
}
VLOG(3) << "Synchronization (FROM), ptr " << p
@ -282,7 +282,7 @@ bool Sandbox::IsActive() const { return s2_ && !s2_->IsTerminated(); }
if (p->GetPointedVar()->GetRemote() == nullptr) {
LOG(ERROR) << "Trying to synchronize a variable which is not allocated in "
<< "the sandboxee p=" << p->ToString();
return ::sapi::FailedPreconditionError(absl::StrCat(
return sapi::FailedPreconditionError(absl::StrCat(
"Trying to synchronize a variable which is not allocated in the "
"sandboxee p=",
p->ToString()));
@ -291,10 +291,10 @@ bool Sandbox::IsActive() const { return s2_ && !s2_->IsTerminated(); }
return p->GetPointedVar()->TransferFromSandboxee(GetRpcChannel(), GetPid());
}
::sapi::Status Sandbox::Call(const std::string& func, v::Callable* ret,
std::initializer_list<v::Callable*> args) {
sapi::Status Sandbox::Call(const std::string& func, v::Callable* ret,
std::initializer_list<v::Callable*> args) {
if (!IsActive()) {
return ::sapi::UnavailableError("Sandbox not active");
return sapi::UnavailableError("Sandbox not active");
}
// Send data.
FuncCall rfcall{};
@ -368,26 +368,26 @@ bool Sandbox::IsActive() const { return s2_ && !s2_->IsTerminated(); }
VLOG(1) << "CALL EXIT: Type: " << ret->GetTypeString()
<< ", Size: " << ret->GetSize() << ", Val: " << ret->ToString();
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status Sandbox::Symbol(const char* symname, void** addr) {
sapi::Status Sandbox::Symbol(const char* symname, void** addr) {
if (!IsActive()) {
return ::sapi::UnavailableError("Sandbox not active");
return sapi::UnavailableError("Sandbox not active");
}
return rpc_channel_->Symbol(symname, addr);
}
::sapi::Status Sandbox::TransferToSandboxee(v::Var* var) {
sapi::Status Sandbox::TransferToSandboxee(v::Var* var) {
if (!IsActive()) {
return ::sapi::UnavailableError("Sandbox not active");
return sapi::UnavailableError("Sandbox not active");
}
return var->TransferToSandboxee(GetRpcChannel(), GetPid());
}
::sapi::Status Sandbox::TransferFromSandboxee(v::Var* var) {
sapi::Status Sandbox::TransferFromSandboxee(v::Var* var) {
if (!IsActive()) {
return ::sapi::UnavailableError("Sandbox not active");
return sapi::UnavailableError("Sandbox not active");
}
return var->TransferFromSandboxee(GetRpcChannel(), GetPid());
}
@ -400,12 +400,12 @@ const sandbox2::Result& Sandbox::AwaitResult() {
return result_;
}
::sapi::Status Sandbox::SetWallTimeLimit(time_t limit) const {
sapi::Status Sandbox::SetWallTimeLimit(time_t limit) const {
if (!IsActive()) {
return ::sapi::UnavailableError("Sandbox not active");
return sapi::UnavailableError("Sandbox not active");
}
s2_->SetWallTimeLimit(limit);
return ::sapi::OkStatus();
return sapi::OkStatus();
}
void Sandbox::Exit() const {

View File

@ -43,7 +43,7 @@ class Sandbox {
virtual ~Sandbox();
// Initializes a new sandboxing session.
::sapi::Status Init();
sapi::Status Init();
// Is the current sandboxing session alive?
bool IsActive() const;
@ -52,7 +52,7 @@ class Sandbox {
void Terminate(bool attempt_graceful_exit = true);
// Restarts the sandbox.
::sapi::Status Restart(bool attempt_graceful_exit) {
sapi::Status Restart(bool attempt_graceful_exit) {
Terminate(attempt_graceful_exit);
return Init();
}
@ -65,42 +65,41 @@ class Sandbox {
int GetPid() const { return pid_; }
// Synchronizes the underlying memory for the pointer before the call.
::sapi::Status SynchronizePtrBefore(v::Callable* ptr);
sapi::Status SynchronizePtrBefore(v::Callable* ptr);
// Synchronizes the underlying memory for pointer after the call.
::sapi::Status SynchronizePtrAfter(v::Callable* ptr) const;
sapi::Status SynchronizePtrAfter(v::Callable* ptr) const;
// Makes a call to the sandboxee.
template <typename... Args>
::sapi::Status Call(const std::string& func, v::Callable* ret,
Args&&... args) {
sapi::Status Call(const std::string& func, v::Callable* ret, Args&&... args) {
static_assert(sizeof...(Args) <= FuncCall::kArgsMax,
"Too many arguments to sapi::Sandbox::Call()");
return Call(func, ret, {std::forward<Args>(args)...});
}
::sapi::Status Call(const std::string& func, v::Callable* ret,
std::initializer_list<v::Callable*> args);
sapi::Status Call(const std::string& func, v::Callable* ret,
std::initializer_list<v::Callable*> args);
// Allocates memory in the sandboxee, automatic_free indicates whether the
// memory should be freed on the remote side when the 'var' goes out of scope.
::sapi::Status Allocate(v::Var* var, bool automatic_free = false);
sapi::Status Allocate(v::Var* var, bool automatic_free = false);
// Frees memory in the sandboxee.
::sapi::Status Free(v::Var* var);
sapi::Status Free(v::Var* var);
// Finds address of a symbol in the sandboxee.
::sapi::Status Symbol(const char* symname, void** addr);
sapi::Status Symbol(const char* symname, void** addr);
// Transfers memory (both directions). Status is returned (memory transfer
// succeeded/failed).
::sapi::Status TransferToSandboxee(v::Var* var);
::sapi::Status TransferFromSandboxee(v::Var* var);
sapi::Status TransferToSandboxee(v::Var* var);
sapi::Status TransferFromSandboxee(v::Var* var);
// Waits until the sandbox terminated and returns the result.
const sandbox2::Result& AwaitResult();
const sandbox2::Result& result() const { return result_; }
::sapi::Status SetWallTimeLimit(time_t limit) const;
sapi::Status SetWallTimeLimit(time_t limit) const;
protected:

View File

@ -29,12 +29,12 @@
namespace sandbox2 {
// Creates a new Buffer that is backed by the specified file descriptor.
::sapi::StatusOr<std::unique_ptr<Buffer>> Buffer::CreateFromFd(int fd) {
sapi::StatusOr<std::unique_ptr<Buffer>> Buffer::CreateFromFd(int fd) {
auto buffer = absl::WrapUnique(new Buffer{});
struct stat stat_buf;
if (fstat(fd, &stat_buf) != 0) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("Could not stat buffer fd: ", StrError(errno)));
}
size_t size = stat_buf.st_size;
@ -44,7 +44,7 @@ namespace sandbox2 {
buffer->buf_ =
reinterpret_cast<uint8_t*>(mmap(nullptr, size, prot, flags, fd, offset));
if (buffer->buf_ == MAP_FAILED) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("Could not map buffer fd: ", StrError(errno)));
}
buffer->fd_ = fd;
@ -54,13 +54,13 @@ namespace sandbox2 {
// Creates a new Buffer of the specified size, backed by a temporary file that
// will be immediately deleted.
::sapi::StatusOr<std::unique_ptr<Buffer>> Buffer::CreateWithSize(int64_t size) {
sapi::StatusOr<std::unique_ptr<Buffer>> Buffer::CreateWithSize(int64_t size) {
int fd;
if (!util::CreateMemFd(&fd)) {
return ::sapi::InternalError("Could not create buffer temp file");
return sapi::InternalError("Could not create buffer temp file");
}
if (ftruncate(fd, size) != 0) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("Could not extend buffer fd: ", StrError(errno)));
}
return CreateFromFd(fd);

View File

@ -37,11 +37,11 @@ class Buffer final {
// Creates a new Buffer that is backed by the specified file descriptor.
// The Buffer takes ownership of the descriptor and will close it when
// destroyed.
static ::sapi::StatusOr<std::unique_ptr<Buffer>> CreateFromFd(int fd);
static sapi::StatusOr<std::unique_ptr<Buffer>> CreateFromFd(int fd);
// Creates a new Buffer of the specified size, backed by a temporary file that
// will be immediately deleted.
static ::sapi::StatusOr<std::unique_ptr<Buffer>> CreateWithSize(int64_t size);
static sapi::StatusOr<std::unique_ptr<Buffer>> CreateWithSize(int64_t size);
// Returns a pointer to the buffer, which is read/write.
uint8_t* data() const { return buf_; }

View File

@ -308,7 +308,7 @@ TEST_F(CommsTest, TestSendRecvStatusOK) {
};
auto b = [](Comms* comms) {
// Send a good status.
ASSERT_THAT(comms->SendStatus(::sapi::OkStatus()), IsTrue());
ASSERT_THAT(comms->SendStatus(sapi::OkStatus()), IsTrue());
};
HandleCommunication(sockname_, a, b);
}

View File

@ -133,19 +133,19 @@ void RunInitProcess(std::set<int> open_fds) {
}
}
::sapi::Status SendPid(int signaling_fd) {
sapi::Status SendPid(int signaling_fd) {
// Send our PID (the actual sandboxee process) via SCM_CREDENTIALS.
// The ancillary message will be attached to the message as SO_PASSCRED is set
// on the socket.
char dummy = ' ';
if (TEMP_FAILURE_RETRY(send(signaling_fd, &dummy, 1, 0)) != 1) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("Sending PID: send: ", sandbox2::StrError(errno)));
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::StatusOr<pid_t> ReceivePid(int signaling_fd) {
sapi::StatusOr<pid_t> ReceivePid(int signaling_fd) {
union {
struct cmsghdr cmh;
char ctrl[CMSG_SPACE(sizeof(struct ucred))];
@ -164,13 +164,13 @@ void RunInitProcess(std::set<int> open_fds) {
iov.iov_len = sizeof(char);
if (TEMP_FAILURE_RETRY(recvmsg(signaling_fd, &msgh, MSG_WAITALL)) != 1) {
return ::sapi::InternalError(absl::StrCat("Receiving pid failed: recvmsg: ",
sandbox2::StrError(errno)));
return sapi::InternalError(absl::StrCat("Receiving pid failed: recvmsg: ",
sandbox2::StrError(errno)));
}
struct cmsghdr* cmsgp = CMSG_FIRSTHDR(&msgh);
if (cmsgp->cmsg_len != CMSG_LEN(sizeof(struct ucred)) ||
cmsgp->cmsg_level != SOL_SOCKET || cmsgp->cmsg_type != SCM_CREDENTIALS) {
return ::sapi::InternalError("Receiving pid failed");
return sapi::InternalError("Receiving pid failed");
}
struct ucred* ucredp = reinterpret_cast<struct ucred*>(CMSG_DATA(cmsgp));
return ucredp->pid;

View File

@ -97,15 +97,14 @@ absl::string_view GetOutsidePath(const MountTree::Node& node) {
}
}
::sapi::StatusOr<std::string> ExistingPathInsideDir(
sapi::StatusOr<std::string> ExistingPathInsideDir(
absl::string_view dir_path, absl::string_view relative_path) {
auto path = file::CleanPath(file::JoinPath(dir_path, relative_path));
if (file_util::fileops::StripBasename(path) != dir_path) {
return ::sapi::InvalidArgumentError(
"Relative path goes above the base dir");
return sapi::InvalidArgumentError("Relative path goes above the base dir");
}
if (!file_util::fileops::Exists(path, false)) {
return ::sapi::NotFoundError(absl::StrCat("Does not exist: ", path));
return sapi::NotFoundError(absl::StrCat("Does not exist: ", path));
}
return path;
}
@ -116,10 +115,10 @@ sapi::Status ValidateInterpreter(absl::string_view interpreter) {
};
if (!allowed_interpreters.contains(interpreter)) {
return ::sapi::InvalidArgumentError(
return sapi::InvalidArgumentError(
absl::StrCat("Interpreter not on the whitelist: ", interpreter));
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
std::string ResolveLibraryPath(absl::string_view lib_name,
@ -146,8 +145,8 @@ std::string GetPlatform(absl::string_view interpreter) {
} // namespace
::sapi::Status Mounts::Insert(absl::string_view path,
const MountTree::Node& new_node) {
sapi::Status Mounts::Insert(absl::string_view path,
const MountTree::Node& new_node) {
// Some sandboxes allow the inside/outside paths to be partially
// user-controlled with some sanitization.
// Since we're handling C++ strings and later convert them to C style
@ -155,7 +154,7 @@ std::string GetPlatform(absl::string_view interpreter) {
// and mount something not expected by the caller. Check for null bytes in the
// strings to protect against this.
if (PathContainsNullByte(path)) {
return ::sapi::InvalidArgumentError(
return sapi::InvalidArgumentError(
absl::StrCat("Inside path contains a null byte: ", path));
}
switch (new_node.node_case()) {
@ -163,10 +162,10 @@ std::string GetPlatform(absl::string_view interpreter) {
case MountTree::Node::kDirNode: {
auto outside_path = GetOutsidePath(new_node);
if (outside_path.empty()) {
return ::sapi::InvalidArgumentError("Outside path cannot be empty");
return sapi::InvalidArgumentError("Outside path cannot be empty");
}
if (PathContainsNullByte(outside_path)) {
return ::sapi::InvalidArgumentError(
return sapi::InvalidArgumentError(
absl::StrCat("Outside path contains a null byte: ", outside_path));
}
break;
@ -179,11 +178,11 @@ std::string GetPlatform(absl::string_view interpreter) {
std::string fixed_path = file::CleanPath(path);
if (!absl::StartsWith(fixed_path, "/")) {
return ::sapi::InvalidArgumentError("Only absolute paths are supported");
return sapi::InvalidArgumentError("Only absolute paths are supported");
}
if (fixed_path == "/") {
return ::sapi::InvalidArgumentError("The root already exists");
return sapi::InvalidArgumentError("The root already exists");
}
std::vector<absl::string_view> parts;
@ -204,7 +203,7 @@ std::string GetPlatform(absl::string_view interpreter) {
->insert({std::string(*part), MountTree()})
.first->second);
if (curtree->has_node() && curtree->node().has_file_node()) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("Cannot insert ", path,
" since a file is mounted as a parent directory"));
}
@ -217,28 +216,28 @@ std::string GetPlatform(absl::string_view interpreter) {
if (curtree->has_node()) {
if (IsEquivalentNode(curtree->node(), new_node)) {
SAPI_RAW_LOG(INFO, "Inserting %s with the same value twice", path);
return ::sapi::OkStatus();
return sapi::OkStatus();
}
return ::sapi::FailedPreconditionError(absl::StrCat(
return sapi::FailedPreconditionError(absl::StrCat(
"Inserting ", path, " twice with conflicting values ",
curtree->node().DebugString(), " vs. ", new_node.DebugString()));
}
if (new_node.has_file_node() && !curtree->entries().empty()) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("Trying to mount file over existing directory at ", path));
}
*curtree->mutable_node() = new_node;
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status Mounts::AddFile(absl::string_view path, bool is_ro) {
sapi::Status Mounts::AddFile(absl::string_view path, bool is_ro) {
return AddFileAt(path, path, is_ro);
}
::sapi::Status Mounts::AddFileAt(absl::string_view outside,
absl::string_view inside, bool is_ro) {
sapi::Status Mounts::AddFileAt(absl::string_view outside,
absl::string_view inside, bool is_ro) {
MountTree::Node node;
auto* file_node = node.mutable_file_node();
file_node->set_outside(std::string(outside));
@ -246,8 +245,8 @@ std::string GetPlatform(absl::string_view interpreter) {
return Insert(inside, node);
}
::sapi::Status Mounts::AddDirectoryAt(absl::string_view outside,
absl::string_view inside, bool is_ro) {
sapi::Status Mounts::AddDirectoryAt(absl::string_view outside,
absl::string_view inside, bool is_ro) {
MountTree::Node node;
auto dir_node = node.mutable_dir_node();
dir_node->set_outside(std::string(outside));
@ -265,12 +264,12 @@ void LogContainer(const std::vector<std::string>& container) {
} // namespace
::sapi::Status Mounts::AddMappingsForBinary(const std::string& path,
absl::string_view ld_library_path) {
sapi::Status Mounts::AddMappingsForBinary(const std::string& path,
absl::string_view ld_library_path) {
auto elf_or = ElfFile::ParseFromFile(
path, ElfFile::kGetInterpreter | ElfFile::kLoadImportedLibraries);
if (!elf_or.ok()) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("Could not parse ELF file: ", elf_or.status().message()));
}
auto elf = elf_or.ValueOrDie();
@ -278,7 +277,7 @@ void LogContainer(const std::vector<std::string>& container) {
if (interpreter.empty()) {
SAPI_RAW_VLOG(1, "The file %s is not a dynamic executable", path);
return ::sapi::OkStatus();
return sapi::OkStatus();
}
SAPI_RAW_VLOG(1, "The file %s is using interpreter %s", path, interpreter);
@ -331,7 +330,7 @@ void LogContainer(const std::vector<std::string>& container) {
{
auto imported_libs = elf.imported_libraries();
if (imported_libs.size() > kMaxWorkQueueSize) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
"Exceeded max entries pending resolving limit");
}
for (const auto& imported_lib : imported_libs) {
@ -360,11 +359,11 @@ void LogContainer(const std::vector<std::string>& container) {
to_resolve.pop_back();
++resolved;
if (resolved > kMaxResolvedEntries) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
"Exceeded max resolved entries limit");
}
if (depth > kMaxResolvingDepth) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
"Exceeded max resolving depth limit");
}
std::string resolved_lib = ResolveLibraryPath(lib, full_search_paths);
@ -380,20 +379,19 @@ void LogContainer(const std::vector<std::string>& container) {
imported_libraries.insert(resolved_lib);
if (imported_libraries.size() > kMaxImportedLibraries) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
"Exceeded max imported libraries limit");
}
++loaded;
if (loaded > kMaxLoadedEntries) {
return ::sapi::FailedPreconditionError(
"Exceeded max loaded entries limit");
return sapi::FailedPreconditionError("Exceeded max loaded entries limit");
}
SAPI_ASSIGN_OR_RETURN(
auto lib_elf,
ElfFile::ParseFromFile(resolved_lib, ElfFile::kLoadImportedLibraries));
auto imported_libs = lib_elf.imported_libraries();
if (imported_libs.size() > kMaxWorkQueueSize - to_resolve.size()) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
"Exceeded max entries pending resolving limit");
}
@ -414,10 +412,10 @@ void LogContainer(const std::vector<std::string>& container) {
SAPI_RETURN_IF_ERROR(AddFile(lib));
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status Mounts::AddTmpfs(absl::string_view inside, size_t sz) {
sapi::Status Mounts::AddTmpfs(absl::string_view inside, size_t sz) {
MountTree::Node node;
auto tmpfs_node = node.mutable_tmpfs_node();
tmpfs_node->set_tmpfs_options(absl::StrCat("size=", sz));

View File

@ -30,18 +30,18 @@ class Mounts {
Mounts() = default;
explicit Mounts(MountTree mount_tree) : mount_tree_(std::move(mount_tree)) {}
::sapi::Status AddFile(absl::string_view path, bool is_ro = true);
sapi::Status AddFile(absl::string_view path, bool is_ro = true);
::sapi::Status AddFileAt(absl::string_view outside, absl::string_view inside,
bool is_ro = true);
sapi::Status AddFileAt(absl::string_view outside, absl::string_view inside,
bool is_ro = true);
::sapi::Status AddDirectoryAt(absl::string_view outside,
absl::string_view inside, bool is_ro = true);
sapi::Status AddDirectoryAt(absl::string_view outside,
absl::string_view inside, bool is_ro = true);
::sapi::Status AddMappingsForBinary(const std::string& path,
absl::string_view ld_library_path = {});
sapi::Status AddMappingsForBinary(const std::string& path,
absl::string_view ld_library_path = {});
::sapi::Status AddTmpfs(absl::string_view inside, size_t sz);
sapi::Status AddTmpfs(absl::string_view inside, size_t sz);
void CreateMounts(const std::string& root_path) const;
@ -59,7 +59,7 @@ class Mounts {
private:
friend class MountTreeTest;
::sapi::Status Insert(absl::string_view path, const MountTree::Node& node);
sapi::Status Insert(absl::string_view path, const MountTree::Node& node);
MountTree mount_tree_;
};

View File

@ -634,20 +634,20 @@ PolicyBuilder& PolicyBuilder::DangerDefaultAllowAll() {
return *this;
}
::sapi::StatusOr<std::string> PolicyBuilder::ValidateAbsolutePath(
sapi::StatusOr<std::string> PolicyBuilder::ValidateAbsolutePath(
absl::string_view path) {
if (!file::IsAbsolutePath(path)) {
return ::sapi::InvalidArgumentError(
return sapi::InvalidArgumentError(
absl::StrCat("Path is not absolute: '", path, "'"));
}
return ValidatePath(path);
}
::sapi::StatusOr<std::string> PolicyBuilder::ValidatePath(
sapi::StatusOr<std::string> PolicyBuilder::ValidatePath(
absl::string_view path) {
std::string fixed_path = file::CleanPath(path);
if (fixed_path != path) {
return ::sapi::InvalidArgumentError(absl::StrCat(
return sapi::InvalidArgumentError(absl::StrCat(
"Path was not normalized. '", path, "' != '", fixed_path, "'"));
}
return fixed_path;
@ -658,13 +658,13 @@ std::vector<sock_filter> PolicyBuilder::ResolveBpfFunc(BpfFunc f) {
std::vector<sock_filter> policy = f(l);
if (bpf_resolve_jumps(&l, policy.data(), policy.size()) != 0) {
SetError(::sapi::InternalError("Cannot resolve bpf jumps"));
SetError(sapi::InternalError("Cannot resolve bpf jumps"));
}
return policy;
}
::sapi::StatusOr<std::unique_ptr<Policy>> PolicyBuilder::TryBuild() {
sapi::StatusOr<std::unique_ptr<Policy>> PolicyBuilder::TryBuild() {
CHECK_NE(use_namespaces_, disable_namespaces_)
<< "Namespaces should either be enabled (by calling EnableNamespaces(), "
"AddFile(), etc.) or disabled (by calling DisableNamespaces())";
@ -673,12 +673,12 @@ std::vector<sock_filter> PolicyBuilder::ResolveBpfFunc(BpfFunc f) {
}
if (!output_) {
return ::sapi::FailedPreconditionError("Can only build policy once.");
return sapi::FailedPreconditionError("Can only build policy once.");
}
if (use_namespaces_) {
if (allow_unrestricted_networking_ && hostname_ != kDefaultHostname) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
"Cannot set hostname without network namespaces.");
}
output_->SetNamespace(absl::make_unique<Namespace>(
@ -706,7 +706,7 @@ PolicyBuilder& PolicyBuilder::AddFile(absl::string_view path, bool is_ro) {
return AddFileAt(path, path, is_ro);
}
PolicyBuilder& PolicyBuilder::SetError(const ::sapi::Status& status) {
PolicyBuilder& PolicyBuilder::SetError(const sapi::Status& status) {
LOG(ERROR) << status;
last_status_ = status;
return *this;
@ -724,7 +724,7 @@ PolicyBuilder& PolicyBuilder::AddFileAt(absl::string_view outside,
auto fixed_outside = std::move(fixed_outside_or.ValueOrDie());
if (absl::StartsWith(fixed_outside, "/proc/self")) {
SetError(::sapi::InvalidArgumentError(
SetError(sapi::InvalidArgumentError(
absl::StrCat("Cannot add /proc/self mounts, you need to mount the "
"whole /proc instead. You tried to mount ",
outside)));
@ -733,9 +733,9 @@ PolicyBuilder& PolicyBuilder::AddFileAt(absl::string_view outside,
auto status = mounts_.AddFileAt(fixed_outside, inside, is_ro);
if (!status.ok()) {
SetError(::sapi::InternalError(absl::StrCat("Could not add file ", outside,
" => ", inside, ": ",
status.message())));
SetError(
sapi::InternalError(absl::StrCat("Could not add file ", outside, " => ",
inside, ": ", status.message())));
}
return *this;
@ -754,7 +754,7 @@ PolicyBuilder& PolicyBuilder::AddLibrariesForBinary(
auto status = mounts_.AddMappingsForBinary(fixed_path, ld_library_path);
if (!status.ok()) {
SetError(::sapi::InternalError(absl::StrCat(
SetError(sapi::InternalError(absl::StrCat(
"Could not add libraries for ", fixed_path, ": ", status.message())));
}
return *this;
@ -782,7 +782,7 @@ PolicyBuilder& PolicyBuilder::AddDirectoryAt(absl::string_view outside,
}
auto fixed_outside = std::move(fixed_outside_or.ValueOrDie());
if (absl::StartsWith(fixed_outside, "/proc/self")) {
SetError(::sapi::InvalidArgumentError(
SetError(sapi::InvalidArgumentError(
absl::StrCat("Cannot add /proc/self mounts, you need to mount the "
"whole /proc instead. You tried to mount ",
outside)));
@ -791,9 +791,9 @@ PolicyBuilder& PolicyBuilder::AddDirectoryAt(absl::string_view outside,
auto status = mounts_.AddDirectoryAt(fixed_outside, inside, is_ro);
if (!status.ok()) {
SetError(::sapi::InternalError(absl::StrCat("Could not add directory ",
outside, " => ", inside, ": ",
status.message())));
SetError(sapi::InternalError(absl::StrCat("Could not add directory ",
outside, " => ", inside, ": ",
status.message())));
}
return *this;
@ -804,8 +804,8 @@ PolicyBuilder& PolicyBuilder::AddTmpfs(absl::string_view inside, size_t sz) {
auto status = mounts_.AddTmpfs(inside, sz);
if (!status.ok()) {
SetError(::sapi::InternalError(absl::StrCat(
"Could not mount tmpfs ", inside, ": ", status.message())));
SetError(sapi::InternalError(absl::StrCat("Could not mount tmpfs ", inside,
": ", status.message())));
}
return *this;

View File

@ -388,7 +388,7 @@ class PolicyBuilder final {
// Builds the policy returning a unique_ptr to it. This should only be called
// once.
::sapi::StatusOr<std::unique_ptr<Policy>> TryBuild();
sapi::StatusOr<std::unique_ptr<Policy>> TryBuild();
// Builds the policy returning a unique_ptr to it. This should only be called
// once.
@ -518,9 +518,9 @@ class PolicyBuilder final {
std::vector<sock_filter> ResolveBpfFunc(BpfFunc f);
static ::sapi::StatusOr<std::string> ValidateAbsolutePath(
static sapi::StatusOr<std::string> ValidateAbsolutePath(
absl::string_view path);
static ::sapi::StatusOr<std::string> ValidatePath(absl::string_view path);
static sapi::StatusOr<std::string> ValidatePath(absl::string_view path);
void StoreDescription(PolicyBuilderDescription* pb_description);
@ -540,10 +540,10 @@ class PolicyBuilder final {
std::set<unsigned int> handled_syscalls_;
// Error handling
::sapi::Status last_status_;
sapi::Status last_status_;
// This function returns a PolicyBuilder so that we can use it in the status
// macros
PolicyBuilder& SetError(const ::sapi::Status& status);
PolicyBuilder& SetError(const sapi::Status& status);
};
} // namespace sandbox2

View File

@ -57,7 +57,7 @@ class PolicyBuilderPeer {
int policy_size() const { return builder_->output_->user_policy_.size(); }
static ::sapi::StatusOr<std::string> ValidateAbsolutePath(
static sapi::StatusOr<std::string> ValidateAbsolutePath(
absl::string_view path) {
return PolicyBuilder::ValidateAbsolutePath(path);
}

View File

@ -29,47 +29,47 @@
namespace sandbox2 {
::sapi::Status Regs::Fetch() {
sapi::Status Regs::Fetch() {
#if defined(__powerpc64__)
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
if (ptrace(PTRACE_GETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
return ::sapi::InternalError(absl::StrCat(
return sapi::InternalError(absl::StrCat(
"ptrace(PTRACE_GETREGSET, pid=", pid_, ") failed: ", StrError(errno)));
}
if (pt_iov.iov_len != sizeof(user_regs_)) {
return ::sapi::InternalError(absl::StrCat(
return sapi::InternalError(absl::StrCat(
"ptrace(PTRACE_GETREGSET, pid=", pid_,
") size returned: ", pt_iov.iov_len,
" different than sizeof(user_regs_): ", sizeof(user_regs_)));
}
#else
if (ptrace(PTRACE_GETREGS, pid_, 0, &user_regs_) == -1L) {
return ::sapi::InternalError(absl::StrCat(
"ptrace(PTRACE_GETREGS, pid=", pid_, ") failed: ", StrError(errno)));
return sapi::InternalError(absl::StrCat("ptrace(PTRACE_GETREGS, pid=", pid_,
") failed: ", StrError(errno)));
}
#endif
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status Regs::Store() {
sapi::Status Regs::Store() {
#if defined(__powerpc64__)
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
if (ptrace(PTRACE_SETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
return ::sapi::InternalError(absl::StrCat(
return sapi::InternalError(absl::StrCat(
"ptrace(PTRACE_SETREGSET, pid=", pid_, ") failed: ", StrError(errno)));
}
#else
if (ptrace(PTRACE_SETREGS, pid_, 0, &user_regs_) == -1) {
return ::sapi::InternalError(absl::StrCat(
"ptrace(PTRACE_SETREGS, pid=", pid_, ") failed: ", StrError(errno)));
return sapi::InternalError(absl::StrCat("ptrace(PTRACE_SETREGS, pid=", pid_,
") failed: ", StrError(errno)));
}
#endif
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status Regs::SkipSyscallReturnValue(uint64_t value) {
sapi::Status Regs::SkipSyscallReturnValue(uint64_t value) {
#if defined(__x86_64__)
user_regs_.orig_rax = -1;
user_regs_.rax = value;

View File

@ -40,13 +40,13 @@ class Regs {
explicit Regs(pid_t pid) : pid_(pid) {}
// Copies register values from the process
::sapi::Status Fetch();
sapi::Status Fetch();
// Copies register values to the process
::sapi::Status Store();
sapi::Status Store();
// Causes the process to skip current syscall and return given value instead
::sapi::Status SkipSyscallReturnValue(uint64_t value);
sapi::Status SkipSyscallReturnValue(uint64_t value);
// Converts raw register values obtained on syscall entry to syscall info
Syscall ToSyscall(Syscall::CpuArch syscall_arch) const;

View File

@ -43,19 +43,19 @@ Result& Result::operator=(const Result& other) {
return *this;
}
::sapi::Status Result::ToStatus() const {
sapi::Status Result::ToStatus() const {
switch (final_status()) {
case OK:
if (reason_code() == 0) {
return ::sapi::OkStatus();
return sapi::OkStatus();
}
break;
case TIMEOUT:
return ::sapi::DeadlineExceededError(ToString());
return sapi::DeadlineExceededError(ToString());
default:
break;
}
return ::sapi::InternalError(ToString());
return sapi::InternalError(ToString());
}
std::string Result::ToString() const {

View File

@ -143,9 +143,9 @@ class Result {
void SetProcMaps(const std::string& proc_maps) { proc_maps_ = proc_maps; }
// Converts this result to a ::sapi::Status object. The status will only be
// Converts this result to a sapi::Status object. The status will only be
// OK if the sandbox process exited normally with an exit code of 0.
::sapi::Status ToStatus() const;
sapi::Status ToStatus() const;
// Returns a descriptive string for final result.
std::string ToString() const;

View File

@ -41,8 +41,7 @@ sapi::StatusOr<Result> Sandbox2::AwaitResultWithTimeout(
auto done =
monitor_->done_notification_.WaitForNotificationWithTimeout(timeout);
if (!done) {
return ::sapi::DeadlineExceededError(
"Sandbox did not finish within timeout");
return sapi::DeadlineExceededError("Sandbox did not finish within timeout");
}
monitor_thread_->join();

View File

@ -76,7 +76,7 @@ class Sandbox2 final {
// Waits for sandbox execution to finish within the timeout.
// Returns execution result or a DeadlineExceededError if the sandboxee does
// not finish in time.
::sapi::StatusOr<Result> AwaitResultWithTimeout(absl::Duration timeout);
sapi::StatusOr<Result> AwaitResultWithTimeout(absl::Duration timeout);
// Requests termination of the sandboxee.
// Sandbox should still waited with AwaitResult(), as it may finish for other

View File

@ -180,15 +180,14 @@ bool CreateMemFd(int* fd, const char* name) {
return true;
}
::sapi::StatusOr<int> Communicate(const std::vector<std::string>& argv,
sapi::StatusOr<int> Communicate(const std::vector<std::string>& argv,
const std::vector<std::string>& envv,
std::string* output) {
int cout_pipe[2];
posix_spawn_file_actions_t action;
if (pipe(cout_pipe) == -1) {
return ::sapi::UnknownError(
absl::StrCat("creating pipe: ", StrError(errno)));
return sapi::UnknownError(absl::StrCat("creating pipe: ", StrError(errno)));
}
file_util::fileops::FDCloser cout_closer{cout_pipe[1]};
@ -217,7 +216,7 @@ bool CreateMemFd(int* fd, const char* name) {
pid_t pid;
if (posix_spawnp(&pid, args[0], &action, nullptr, args, envp) != 0) {
return ::sapi::UnknownError(
return sapi::UnknownError(
absl::StrCat("posix_spawnp() failed: ", StrError(errno)));
}
@ -229,7 +228,7 @@ bool CreateMemFd(int* fd, const char* name) {
int bytes_read =
TEMP_FAILURE_RETRY(read(cout_pipe[0], &buffer[0], buffer.length()));
if (bytes_read < 0) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("reading from cout pipe failed: ", StrError(errno)));
}
if (bytes_read == 0) {
@ -279,7 +278,7 @@ std::string GetRlimitName(int resource) {
}
}
::sapi::StatusOr<std::string> ReadCPathFromPid(pid_t pid, uintptr_t ptr) {
sapi::StatusOr<std::string> ReadCPathFromPid(pid_t pid, uintptr_t ptr) {
std::string path(PATH_MAX, '\0');
iovec local_iov[] = {{&path[0], path.size()}};
@ -304,7 +303,7 @@ std::string GetRlimitName(int resource) {
ssize_t sz = process_vm_readv(pid, local_iov, ABSL_ARRAYSIZE(local_iov),
remote_iov, ABSL_ARRAYSIZE(remote_iov), 0);
if (sz < 0) {
return ::sapi::InternalError(absl::StrFormat(
return sapi::InternalError(absl::StrFormat(
"process_vm_readv() failed for PID: %d at address: %#x: %s", pid,
reinterpret_cast<uintptr_t>(ptr), StrError(errno)));
}
@ -313,7 +312,7 @@ std::string GetRlimitName(int resource) {
// incorrect path (or >PATH_MAX).
auto pos = path.find('\0');
if (pos == std::string::npos) {
return ::sapi::FailedPreconditionError(absl::StrCat(
return sapi::FailedPreconditionError(absl::StrCat(
"No NUL-byte inside the C string '", absl::CHexEscape(path), "'"));
}
path.resize(pos);

View File

@ -62,7 +62,7 @@ bool CreateMemFd(int* fd, const char* name = "buffer_file");
// Executes a the program given by argv and the specified environment and
// captures any output to stdout/stderr.
::sapi::StatusOr<int> Communicate(const std::vector<std::string>& argv,
sapi::StatusOr<int> Communicate(const std::vector<std::string>& argv,
const std::vector<std::string>& envv,
std::string* output);
@ -74,7 +74,7 @@ std::string GetRlimitName(int resource);
// Reads a path string (NUL-terminated, shorter than PATH_MAX) from another
// process memory
::sapi::StatusOr<std::string> ReadCPathFromPid(pid_t pid, uintptr_t ptr);
sapi::StatusOr<std::string> ReadCPathFromPid(pid_t pid, uintptr_t ptr);
} // namespace util
} // namespace sandbox2

View File

@ -18,7 +18,7 @@
namespace sandbox2 {
::sapi::StatusOr<std::vector<MapsEntry>> ParseProcMaps(
sapi::StatusOr<std::vector<MapsEntry>> ParseProcMaps(
const std::string& contents) {
// Note: The format string
// https://github.com/torvalds/linux/blob/v4.14/fs/proc/task_mmu.c#L289
@ -45,7 +45,7 @@ namespace sandbox2 {
} else if (n_matches == 11) {
entry.path.resize(strlen(entry.path.c_str()));
} else {
return ::sapi::FailedPreconditionError("Invalid format");
return sapi::FailedPreconditionError("Invalid format");
}
entry.is_readable = r == 'r';
entry.is_writable = w == 'w';

View File

@ -38,7 +38,7 @@ struct MapsEntry {
std::string path;
};
::sapi::StatusOr<std::vector<MapsEntry>> ParseProcMaps(
sapi::StatusOr<std::vector<MapsEntry>> ParseProcMaps(
const std::string& contents);
} // namespace sandbox2

View File

@ -51,23 +51,23 @@ constexpr int kEvCurrent = 1; // ELF version
namespace {
// NOLINTNEXTLINE
::sapi::Status CheckedFSeek(FILE* f, long offset, int whence) {
sapi::Status CheckedFSeek(FILE* f, long offset, int whence) {
if (fseek(f, offset, whence)) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("Fseek on ELF failed: ", StrError(errno)));
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status CheckedFRead(void* dst, size_t size, size_t nmemb, FILE* f) {
sapi::Status CheckedFRead(void* dst, size_t size, size_t nmemb, FILE* f) {
if (fread(dst, size, nmemb, f) == nmemb) {
return ::sapi::OkStatus();
return sapi::OkStatus();
}
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("Reading ELF data failed: ", StrError(errno)));
}
::sapi::Status CheckedRead(std::string* s, FILE* f) {
sapi::Status CheckedRead(std::string* s, FILE* f) {
return CheckedFRead(&(*s)[0], 1, s->size(), f);
}
@ -96,7 +96,7 @@ class ElfParser {
static constexpr size_t kMaxInterpreterSize = 1000;
ElfParser() = default;
::sapi::StatusOr<ElfFile> Parse(FILE* elf, uint32_t features);
sapi::StatusOr<ElfFile> Parse(FILE* elf, uint32_t features);
private:
// Endianess support functions
@ -130,25 +130,25 @@ class ElfParser {
void Load(int64_t* dst, const void* src) { *dst = Load64(src); }
// Reads elf file size.
::sapi::Status ReadFileSize();
sapi::Status ReadFileSize();
// Reads elf header.
::sapi::Status ReadFileHeader();
sapi::Status ReadFileHeader();
// Reads a single elf program header.
::sapi::StatusOr<Elf64_Phdr> ReadProgramHeader(absl::string_view src);
sapi::StatusOr<Elf64_Phdr> ReadProgramHeader(absl::string_view src);
// Reads all elf program headers.
::sapi::Status ReadProgramHeaders();
sapi::Status ReadProgramHeaders();
// Reads a single elf section header.
::sapi::StatusOr<Elf64_Shdr> ReadSectionHeader(absl::string_view src);
sapi::StatusOr<Elf64_Shdr> ReadSectionHeader(absl::string_view src);
// Reads all elf section headers.
::sapi::Status ReadSectionHeaders();
sapi::Status ReadSectionHeaders();
// Reads contents of an elf section.
::sapi::StatusOr<std::string> ReadSectionContents(int idx);
::sapi::StatusOr<std::string> ReadSectionContents(
sapi::StatusOr<std::string> ReadSectionContents(int idx);
sapi::StatusOr<std::string> ReadSectionContents(
const Elf64_Shdr& section_header);
// Reads all symbols from symtab section.
::sapi::Status ReadSymbolsFromSymtab(const Elf64_Shdr& symtab);
sapi::Status ReadSymbolsFromSymtab(const Elf64_Shdr& symtab);
// Reads all imported libraries from dynamic section.
::sapi::Status ReadImportedLibrariesFromDynamic(const Elf64_Shdr& dynamic);
sapi::Status ReadImportedLibrariesFromDynamic(const Elf64_Shdr& dynamic);
ElfFile result_;
FILE* elf_ = nullptr;
@ -171,37 +171,37 @@ constexpr int ElfParser::kMaxSymbolEntries;
constexpr int ElfParser::kMaxDynamicEntries;
constexpr size_t ElfParser::kMaxInterpreterSize;
::sapi::Status ElfParser::ReadFileSize() {
sapi::Status ElfParser::ReadFileSize() {
fseek(elf_, 0, SEEK_END);
file_size_ = ftell(elf_);
if (file_size_ < kElfHeaderSize) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("file too small: ", file_size_, " bytes, at least ",
kElfHeaderSize, " bytes expected"));
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status ElfParser::ReadFileHeader() {
sapi::Status ElfParser::ReadFileHeader() {
std::string header(kElfHeaderSize, '\0');
SAPI_RETURN_IF_ERROR(CheckedFSeek(elf_, 0, SEEK_SET));
SAPI_RETURN_IF_ERROR(CheckedRead(&header, elf_));
if (!absl::StartsWith(header, kElfMagic)) {
return ::sapi::FailedPreconditionError("magic not found, not an ELF");
return sapi::FailedPreconditionError("magic not found, not an ELF");
}
if (header[kEiClassOffset] != kEiClass64) {
return ::sapi::FailedPreconditionError("invalid ELF class");
return sapi::FailedPreconditionError("invalid ELF class");
}
const auto elf_data = header[kEiDataOffset];
elf_little_ = elf_data == kEiDataLittle;
if (!elf_little_ && elf_data != kEiDataBig) {
return ::sapi::FailedPreconditionError("invalid endianness");
return sapi::FailedPreconditionError("invalid endianness");
}
if (header[kEiVersionOffset] != kEvCurrent) {
return ::sapi::FailedPreconditionError("invalid ELF version");
return sapi::FailedPreconditionError("invalid ELF version");
}
LOAD_MEMBER(file_header_, e_ident, header.data());
LOAD_MEMBER(file_header_, e_type, header.data());
@ -217,13 +217,13 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
LOAD_MEMBER(file_header_, e_shentsize, header.data());
LOAD_MEMBER(file_header_, e_shnum, header.data());
LOAD_MEMBER(file_header_, e_shstrndx, header.data());
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::StatusOr<Elf64_Shdr> ElfParser::ReadSectionHeader(
sapi::StatusOr<Elf64_Shdr> ElfParser::ReadSectionHeader(
absl::string_view src) {
if (src.size() < sizeof(Elf64_Shdr)) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("invalid section header data: got ", src.size(),
" bytes, ", sizeof(Elf64_Shdr), " bytes expected."));
}
@ -241,18 +241,18 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
return rv;
}
::sapi::Status ElfParser::ReadSectionHeaders() {
sapi::Status ElfParser::ReadSectionHeaders() {
if (file_header_.e_shoff > file_size_) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("invalid section header offset: ", file_header_.e_shoff));
}
if (file_header_.e_shentsize != sizeof(Elf64_Shdr)) {
return ::sapi::FailedPreconditionError(absl::StrCat(
return sapi::FailedPreconditionError(absl::StrCat(
"section header entry size incorrect: ", file_header_.e_shentsize,
" bytes, ", sizeof(Elf64_Shdr), " expected."));
}
if (file_header_.e_shnum > kMaxSectionHeaderEntries) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("too many section header entries: ", file_header_.e_shnum,
" limit: ", kMaxSectionHeaderEntries));
}
@ -265,27 +265,27 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
SAPI_ASSIGN_OR_RETURN(section_headers_[i], ReadSectionHeader(src));
src = src.substr(file_header_.e_shentsize);
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::StatusOr<std::string> ElfParser::ReadSectionContents(int idx) {
sapi::StatusOr<std::string> ElfParser::ReadSectionContents(int idx) {
if (idx < 0 || idx >= section_headers_.size()) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("invalid section header index: ", idx));
}
return ReadSectionContents(section_headers_.at(idx));
}
::sapi::StatusOr<std::string> ElfParser::ReadSectionContents(
sapi::StatusOr<std::string> ElfParser::ReadSectionContents(
const Elf64_Shdr& section_header) {
auto offset = section_header.sh_offset;
if (offset > file_size_) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("invalid section offset: ", offset));
}
auto size = section_header.sh_size;
if (size > kMaxSectionSize) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("section too big: ", size, " limit: ", kMaxSectionSize));
}
std::string rv(size, '\0');
@ -294,10 +294,10 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
return rv;
}
::sapi::StatusOr<Elf64_Phdr> ElfParser::ReadProgramHeader(
sapi::StatusOr<Elf64_Phdr> ElfParser::ReadProgramHeader(
absl::string_view src) {
if (src.size() < sizeof(Elf64_Phdr)) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("invalid program header data: got ", src.size(),
" bytes, ", sizeof(Elf64_Phdr), " bytes expected."));
}
@ -313,18 +313,18 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
return rv;
}
::sapi::Status ElfParser::ReadProgramHeaders() {
sapi::Status ElfParser::ReadProgramHeaders() {
if (file_header_.e_phoff > file_size_) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("invalid program header offset: ", file_header_.e_phoff));
}
if (file_header_.e_phentsize != sizeof(Elf64_Phdr)) {
return ::sapi::FailedPreconditionError(absl::StrCat(
return sapi::FailedPreconditionError(absl::StrCat(
"section header entry size incorrect: ", file_header_.e_phentsize,
" bytes, ", sizeof(Elf64_Phdr), " expected."));
}
if (file_header_.e_phnum > kMaxProgramHeaderEntries) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("too many program header entries: ", file_header_.e_phnum,
" limit: ", kMaxProgramHeaderEntries));
}
@ -337,29 +337,29 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
SAPI_ASSIGN_OR_RETURN(program_headers_[i], ReadProgramHeader(src));
src = src.substr(file_header_.e_phentsize);
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status ElfParser::ReadSymbolsFromSymtab(const Elf64_Shdr& symtab) {
sapi::Status ElfParser::ReadSymbolsFromSymtab(const Elf64_Shdr& symtab) {
if (symtab.sh_type != SHT_SYMTAB) {
return ::sapi::FailedPreconditionError("invalid symtab type");
return sapi::FailedPreconditionError("invalid symtab type");
}
if (symtab.sh_entsize != sizeof(Elf64_Sym)) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("invalid symbol entry size: ", symtab.sh_entsize));
}
if ((symtab.sh_size % symtab.sh_entsize) != 0) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("invalid symbol table size: ", symtab.sh_size));
}
size_t symbol_entries = symtab.sh_size / symtab.sh_entsize;
if (symbol_entries > kMaxSymbolEntries - symbol_entries_read) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("too many symbols: ", symbol_entries));
}
symbol_entries_read += symbol_entries;
if (symtab.sh_link >= section_headers_.size()) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("invalid symtab's strtab reference: ", symtab.sh_link));
}
SAPI_RAW_VLOG(1, "Symbol table with %d entries found", symbol_entries);
@ -384,53 +384,53 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
continue;
}
if (symbol.st_shndx >= section_headers_.size()) {
return ::sapi::FailedPreconditionError(absl::StrCat(
return sapi::FailedPreconditionError(absl::StrCat(
"invalid symbol data: section index: ", symbol.st_shndx));
}
if (symbol.st_name >= strtab.size()) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("invalid name reference: REL", symbol.st_value));
}
result_.symbols_.push_back(
{symbol.st_value, std::string(ReadName(symbol.st_name, strtab))});
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::Status ElfParser::ReadImportedLibrariesFromDynamic(
sapi::Status ElfParser::ReadImportedLibrariesFromDynamic(
const Elf64_Shdr& dynamic) {
if (dynamic.sh_type != SHT_DYNAMIC) {
return ::sapi::FailedPreconditionError("invalid dynamic type");
return sapi::FailedPreconditionError("invalid dynamic type");
}
if (dynamic.sh_entsize != sizeof(Elf64_Dyn)) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("invalid dynamic entry size: ", dynamic.sh_entsize));
}
if ((dynamic.sh_size % dynamic.sh_entsize) != 0) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("invalid dynamic table size: ", dynamic.sh_size));
}
size_t entries = dynamic.sh_size / dynamic.sh_entsize;
if (entries > kMaxDynamicEntries - dynamic_entries_read) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("too many dynamic entries: ", entries));
}
dynamic_entries_read += entries;
if (dynamic.sh_link >= section_headers_.size()) {
return ::sapi::InternalError(
return sapi::InternalError(
absl::StrCat("invalid dynamic's strtab reference: ", dynamic.sh_link));
}
SAPI_RAW_VLOG(1, "Dynamic section with %d entries found", entries);
// strtab may be shared with symbols and therefore huge
const auto& strtab_section = section_headers_.at(dynamic.sh_link);
if (strtab_section.sh_offset > file_size_) {
return ::sapi::FailedPreconditionError(absl::StrCat(
return sapi::FailedPreconditionError(absl::StrCat(
"invalid symtab's strtab section offset: ", strtab_section.sh_offset));
}
if (strtab_section.sh_size >= kMaxStrtabSize ||
strtab_section.sh_size >= file_size_ ||
strtab_section.sh_offset >= file_size_ - strtab_section.sh_size) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("symtab's strtab too big: ", strtab_section.sh_size));
}
auto strtab_end = strtab_section.sh_offset + strtab_section.sh_size;
@ -444,7 +444,7 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
continue;
}
if (dyn.d_un.d_val >= strtab_section.sh_size) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("invalid name reference"));
}
auto offset = strtab_section.sh_offset + dyn.d_un.d_val;
@ -454,14 +454,14 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
path.resize(size);
result_.imported_libraries_.push_back(path.substr(0, path.find('\0')));
}
return ::sapi::OkStatus();
return sapi::OkStatus();
}
::sapi::StatusOr<ElfFile> ElfParser::Parse(FILE* elf, uint32_t features) {
sapi::StatusOr<ElfFile> ElfParser::Parse(FILE* elf, uint32_t features) {
elf_ = elf;
// Basic sanity check.
if (features & ~(ElfFile::kAll)) {
return ::sapi::InvalidArgumentError("Unknown feature flags specified");
return sapi::InvalidArgumentError("Unknown feature flags specified");
}
SAPI_RETURN_IF_ERROR(ReadFileSize());
SAPI_RETURN_IF_ERROR(ReadFileHeader());
@ -473,7 +473,7 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
result_.position_independent_ = true;
break;
default:
return ::sapi::FailedPreconditionError("not an executable: ");
return sapi::FailedPreconditionError("not an executable: ");
}
if (features & ElfFile::kGetInterpreter) {
SAPI_RETURN_IF_ERROR(ReadProgramHeaders());
@ -484,7 +484,7 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
// No interpreter usually means that the executable was statically linked.
if (it != program_headers_.end()) {
if (it->p_filesz > kMaxInterpreterSize) {
return ::sapi::FailedPreconditionError(
return sapi::FailedPreconditionError(
absl::StrCat("program interpeter path too long: ", it->p_filesz));
}
SAPI_RETURN_IF_ERROR(CheckedFSeek(elf, it->p_offset, SEEK_SET));
@ -514,12 +514,12 @@ constexpr size_t ElfParser::kMaxInterpreterSize;
return std::move(result_);
}
::sapi::StatusOr<ElfFile> ElfFile::ParseFromFile(const std::string& filename,
sapi::StatusOr<ElfFile> ElfFile::ParseFromFile(const std::string& filename,
uint32_t features) {
std::unique_ptr<FILE, void (*)(FILE*)> elf{fopen(filename.c_str(), "r"),
[](FILE* f) { fclose(f); }};
if (!elf) {
return ::sapi::UnknownError(
return sapi::UnknownError(
absl::StrCat("cannot open file: ", filename, ": ", StrError(errno)));
}

View File

@ -33,7 +33,7 @@ class ElfFile {
std::string name;
};
static ::sapi::StatusOr<ElfFile> ParseFromFile(const std::string& filename,
static sapi::StatusOr<ElfFile> ParseFromFile(const std::string& filename,
uint32_t features);
int64_t file_size() const { return file_size_; }

View File

@ -33,17 +33,17 @@ namespace {
constexpr absl::string_view kMktempSuffix = "XXXXXX";
} // namespace
::sapi::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
sapi::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
absl::string_view prefix) {
std::string name_template = absl::StrCat(prefix, kMktempSuffix);
int fd = mkstemp(&name_template[0]);
if (fd < 0) {
return ::sapi::UnknownError(absl::StrCat("mkstemp():", StrError(errno)));
return sapi::UnknownError(absl::StrCat("mkstemp():", StrError(errno)));
}
return std::pair<std::string, int>{std::move(name_template), fd};
}
::sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
absl::string_view prefix) {
auto result_or = CreateNamedTempFile(prefix);
if (result_or.ok()) {
@ -56,10 +56,10 @@ constexpr absl::string_view kMktempSuffix = "XXXXXX";
return result_or.status();
}
::sapi::StatusOr<std::string> CreateTempDir(absl::string_view prefix) {
sapi::StatusOr<std::string> CreateTempDir(absl::string_view prefix) {
std::string name_template = absl::StrCat(prefix, kMktempSuffix);
if (mkdtemp(&name_template[0]) == nullptr) {
return ::sapi::UnknownError(absl::StrCat("mkdtemp():", StrError(errno)));
return sapi::UnknownError(absl::StrCat("mkdtemp():", StrError(errno)));
}
return name_template;
}

View File

@ -23,18 +23,18 @@ namespace sandbox2 {
// Creates a temporary file under a path starting with prefix. File is not
// unlinked and its path is returned together with an open fd.
::sapi::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
sapi::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
absl::string_view prefix);
// Creates a temporary file under a path starting with prefix. File is not
// unlinked and its path is returned. FD of the created file is closed just
// after creation.
::sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
absl::string_view prefix);
// Creates a temporary directory under a path starting with prefix.
// Returns the path of the created directory.
::sapi::StatusOr<std::string> CreateTempDir(absl::string_view prefix);
sapi::StatusOr<std::string> CreateTempDir(absl::string_view prefix);
} // namespace sandbox2

View File

@ -457,8 +457,8 @@ class ReturnType(ArgumentType):
"""Class representing function return type.
Attributes:
return_type: ::sapi::StatusOr<T> where T is original return type, or
::sapi::Status for functions returning void
return_type: sapi::StatusOr<T> where T is original return type, or
sapi::Status for functions returning void
"""
def __init__(self, function, arg_type):
@ -470,8 +470,8 @@ class ReturnType(ArgumentType):
"""Returns function return type prepared from the type."""
# TODO(szwl): const ptrs do not play well with SAPI C++ API...
spelling = self._clang_type.spelling.replace('const', '')
return_type = '::sapi::StatusOr<{}>'.format(spelling)
return_type = '::sapi::Status' if self.is_void() else return_type
return_type = 'sapi::StatusOr<{}>'.format(spelling)
return_type = 'sapi::Status' if self.is_void() else return_type
return return_type
@ -832,7 +832,7 @@ class Generator(object):
result.append(' SAPI_RETURN_IF_ERROR(sandbox_->Call("{}", &ret{}));'
''.format(f.name, ', '.join(call_arguments)))
return_status = 'return ::sapi::OkStatus();'
return_status = 'return sapi::OkStatus();'
if f.result and not f.result.is_void():
if f.result and f.result.is_enum():
return_status = ('return static_cast<{}>'

View File

@ -32,7 +32,7 @@ class TestApi {
::sapi::Sandbox* sandbox() const { return sandbox_; }
// int function_a(int, int)
::sapi::StatusOr<int> function_a(int x, int y) {
sapi::StatusOr<int> function_a(int x, int y) {
::sapi::v::Int ret;
::sapi::v::Int x_((x));
::sapi::v::Int y_((y));
@ -42,7 +42,7 @@ class TestApi {
}
// int types_1(bool, unsigned char, char, unsigned short, short)
::sapi::StatusOr<int> types_1(bool a0, unsigned char a1, char a2, unsigned short a3, short a4) {
sapi::StatusOr<int> types_1(bool a0, unsigned char a1, char a2, unsigned short a3, short a4) {
::sapi::v::Int ret;
::sapi::v::Bool a0_((a0));
::sapi::v::UChar a1_((a1));
@ -55,7 +55,7 @@ class TestApi {
}
// int types_2(int, unsigned int, long, unsigned long)
::sapi::StatusOr<int> types_2(int a0, unsigned int a1, long a2, unsigned long a3) {
sapi::StatusOr<int> types_2(int a0, unsigned int a1, long a2, unsigned long a3) {
::sapi::v::Int ret;
::sapi::v::Int a0_((a0));
::sapi::v::UInt a1_((a1));
@ -67,7 +67,7 @@ class TestApi {
}
// int types_3(long long, unsigned long long, float, double)
::sapi::StatusOr<int> types_3(long long a0, unsigned long long a1, float a2, double a3) {
sapi::StatusOr<int> types_3(long long a0, unsigned long long a1, float a2, double a3) {
::sapi::v::Int ret;
::sapi::v::LLong a0_((a0));
::sapi::v::ULLong a1_((a1));
@ -79,7 +79,7 @@ class TestApi {
}
// int types_4(signed char, short, int, long)
::sapi::StatusOr<int> types_4(signed char a0, short a1, int a2, long a3) {
sapi::StatusOr<int> types_4(signed char a0, short a1, int a2, long a3) {
::sapi::v::Int ret;
::sapi::v::SChar a0_((a0));
::sapi::v::Short a1_((a1));
@ -91,7 +91,7 @@ class TestApi {
}
// int types_5(long long, long double)
::sapi::StatusOr<int> types_5(long long a0, long double a1) {
sapi::StatusOr<int> types_5(long long a0, long double a1) {
::sapi::v::Int ret;
::sapi::v::LLong a0_((a0));
::sapi::v::Reg<long double> a1_((a1));
@ -101,11 +101,11 @@ class TestApi {
}
// void types_6(char *)
::sapi::Status types_6(::sapi::v::Ptr* a0) {
sapi::Status types_6(::sapi::v::Ptr* a0) {
::sapi::v::Void ret;
SAPI_RETURN_IF_ERROR(sandbox_->Call("types_6", &ret, a0));
return ::sapi::OkStatus();
return sapi::OkStatus();
}
private:
@ -136,7 +136,7 @@ class TestApi {
::sapi::Sandbox* sandbox() const { return sandbox_; }
// uint function(uintp)
::sapi::StatusOr<uint> function(::sapi::v::Ptr* a) {
sapi::StatusOr<uint> function(::sapi::v::Ptr* a) {
::sapi::v::UInt ret;
SAPI_RETURN_IF_ERROR(sandbox_->Call("function", &ret, a));
@ -173,7 +173,7 @@ class TestApi {
::sapi::Sandbox* sandbox() const { return sandbox_; }
// ProcessStatus ProcessDatapoint(ProcessStatus)
::sapi::StatusOr<ProcessStatus> ProcessDatapoint(ProcessStatus status) {
sapi::StatusOr<ProcessStatus> ProcessDatapoint(ProcessStatus status) {
::sapi::v::IntBase<ProcessStatus> ret;
::sapi::v::IntBase<ProcessStatus> status_((status));