Commit b35515df authored by Greg Kerr's avatar Greg Kerr Committed by Commit Bot

Remove sandbox/mac dependency on //base.

This removes the mac sandbox libraries dependency on //base. 
The dependency was causing the Chromium Helper binary to be 
linked against everything //base uses 
(AppKit, Security.framework, etc.), which is bad for security 
because of the resource access that happens in those libraries 
initializers.

Bug: 757577
Change-Id: I4699b9cd490c188e1659932e5c97621e37438f32
Reviewed-on: https://chromium-review.googlesource.com/676262
Commit-Queue: Greg Kerr <kerrnel@chromium.org>
Reviewed-by: default avatarMark Mentovai <mark@chromium.org>
Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#506440}
parent c871319d
......@@ -17,6 +17,8 @@ component("seatbelt") {
sources = [
"sandbox_compiler.cc",
"sandbox_compiler.h",
"sandbox_logging.cc",
"sandbox_logging.h",
"seatbelt.cc",
"seatbelt.h",
"seatbelt_exec.cc",
......@@ -28,7 +30,6 @@ component("seatbelt") {
":seatbelt_proto",
]
public_deps = [
"//base",
"//third_party/protobuf:protobuf_lite",
]
defines = [ "SEATBELT_IMPLEMENTATION" ]
......
// 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/sandbox_logging.h"
#include <asl.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <limits>
#include <string>
#define ABORT() \
{ \
asm volatile( \
"int3; ud2; push %0;" ::"i"(static_cast<unsigned char>(__COUNTER__))); \
__builtin_unreachable(); \
}
namespace sandbox {
namespace logging {
namespace {
enum class Level { FATAL, ERR, WARN, INFO };
void SendAslLog(Level level, const char* message) {
class ASLClient {
public:
explicit ASLClient()
: client_(asl_open(nullptr,
"com.apple.console",
ASL_OPT_STDERR | ASL_OPT_NO_DELAY)) {}
~ASLClient() { asl_close(client_); }
aslclient get() const { return client_; }
ASLClient(const ASLClient&) = delete;
ASLClient& operator=(const ASLClient&) = delete;
private:
aslclient client_;
} asl_client;
class ASLMessage {
public:
ASLMessage() : message_(asl_new(ASL_TYPE_MSG)) {}
~ASLMessage() { asl_free(message_); }
aslmsg get() const { return message_; }
ASLMessage(const ASLMessage&) = delete;
ASLMessage& operator=(const ASLMessage&) = delete;
private:
aslmsg message_;
} asl_message;
// By default, messages are only readable by the admin group. Explicitly
// make them readable by the user generating the messages.
char euid_string[12];
snprintf(euid_string, sizeof(euid_string) / sizeof(euid_string[0]), "%d",
geteuid());
asl_set(asl_message.get(), ASL_KEY_READ_UID, euid_string);
std::string asl_level_string;
switch (level) {
case Level::FATAL:
asl_level_string = ASL_STRING_CRIT;
break;
case Level::ERR:
asl_level_string = ASL_STRING_ERR;
break;
case Level::WARN:
asl_level_string = ASL_STRING_WARNING;
break;
case Level::INFO:
default:
asl_level_string = ASL_STRING_INFO;
break;
}
asl_set(asl_message.get(), ASL_KEY_LEVEL, asl_level_string.c_str());
asl_set(asl_message.get(), ASL_KEY_MSG, message);
asl_send(asl_client.get(), asl_message.get());
}
// |error| is strerror(errno) when a P* logging function is called. Pass
// |nullptr| if no errno is set.
void DoLogging(Level level,
const char* fmt,
va_list args,
const std::string* error) {
char message[4096];
int ret = vsnprintf(message, sizeof(message), fmt, args);
if (ret < 0) {
SendAslLog(level, "warning: log message could not be formatted");
return;
}
// int |ret| is not negative so casting to a larger type is safe.
bool truncated = static_cast<unsigned long>(ret) > sizeof(message) - 1;
std::string final_message = message;
if (error)
final_message += ": " + *error;
SendAslLog(level, final_message.c_str());
if (truncated)
SendAslLog(level, "warning: previous log message truncated");
}
} // namespace
void Info(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
DoLogging(Level::INFO, fmt, args, nullptr);
va_end(args);
}
void Warning(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
DoLogging(Level::WARN, fmt, args, nullptr);
va_end(args);
}
void Error(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
DoLogging(Level::ERR, fmt, args, nullptr);
va_end(args);
}
void Fatal(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
DoLogging(Level::FATAL, fmt, args, nullptr);
va_end(args);
ABORT();
}
void PError(const char* fmt, ...) {
std::string error = strerror(errno);
va_list args;
va_start(args, fmt);
DoLogging(Level::ERR, fmt, args, &error);
va_end(args);
}
void PFatal(const char* fmt, ...) {
std::string error = strerror(errno);
va_list args;
va_start(args, fmt);
DoLogging(Level::FATAL, fmt, args, &error);
va_end(args);
ABORT();
}
} // namespace logging
} // namespace sandbox
// 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.
#ifndef SANDBOX_SANDBOX_LOGGING_H_
#define SANDBOX_SANDBOX_LOGGING_H_
namespace sandbox {
// Sandbox has its own logging implementation to avoid linking against //base.
// Sandbox should not link against libbase because libbase brings in numerous
// system libraries that increase the attack surface of the sandbox code.
namespace logging {
// The follow three functions log a format string and its arguments at
// the platform specific version of the given log levels.
void Info(const char* fmt, ...);
void Warning(const char* fmt, ...);
void Error(const char* fmt, ...);
// This logs a platform specific critical message and aborts the process.
void Fatal(const char* fmt, ...);
// The PError and PFatal functions log the errno information as well.
void PError(const char* fmt, ...);
void PFatal(const char* fmt, ...);
} // namespace logging
} // namespace sandbox
#endif // SANDBOX_SANDBOX_LOGGING_H_
......@@ -4,22 +4,24 @@
#include "sandbox/mac/seatbelt_exec.h"
#include <stdarg.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <unistd.h>
#include <vector>
#include "base/logging.h"
#include "base/macros.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/stringprintf.h"
#include "sandbox/mac/sandbox_logging.h"
#include "sandbox/mac/seatbelt.h"
namespace sandbox {
SeatbeltExecClient::SeatbeltExecClient() {
PCHECK(pipe(pipe_) == 0) << "pipe";
if (pipe(pipe_) != 0)
logging::PFatal("SeatbeltExecClient: pipe failed");
}
SeatbeltExecClient::~SeatbeltExecClient() {
......@@ -30,22 +32,21 @@ SeatbeltExecClient::~SeatbeltExecClient() {
IGNORE_EINTR(close(pipe_[0]));
}
bool SeatbeltExecClient::SetBooleanParameter(const base::StringPiece key,
bool SeatbeltExecClient::SetBooleanParameter(const std::string& key,
bool value) {
google::protobuf::MapPair<std::string, std::string> pair(
key.as_string(), value ? "TRUE" : "FALSE");
key, value ? "TRUE" : "FALSE");
return policy_.mutable_params()->insert(pair).second;
}
bool SeatbeltExecClient::SetParameter(const base::StringPiece key,
const base::StringPiece value) {
google::protobuf::MapPair<std::string, std::string> pair(key.as_string(),
value.as_string());
bool SeatbeltExecClient::SetParameter(const std::string& key,
const std::string& value) {
google::protobuf::MapPair<std::string, std::string> pair(key, value);
return policy_.mutable_params()->insert(pair).second;
}
void SeatbeltExecClient::SetProfile(const base::StringPiece policy) {
policy_.set_profile(policy.as_string());
void SeatbeltExecClient::SetProfile(const std::string& policy) {
policy_.set_profile(policy);
}
int SeatbeltExecClient::SendProfileAndGetFD() {
......@@ -69,7 +70,7 @@ bool SeatbeltExecClient::WriteString(std::string* str) {
ssize_t written = HANDLE_EINTR(writev(pipe_[1], iov, arraysize(iov)));
if (written < 0) {
PLOG(ERROR) << "writev";
logging::PError("SeatbeltExecClient: writev failed");
return false;
}
return static_cast<uint64_t>(written) == str->size();
......@@ -77,7 +78,9 @@ bool SeatbeltExecClient::WriteString(std::string* str) {
SeatbeltExecServer::SeatbeltExecServer(int fd) : fd_(fd), extra_params_() {}
SeatbeltExecServer::~SeatbeltExecServer() {}
SeatbeltExecServer::~SeatbeltExecServer() {
close(fd_);
}
bool SeatbeltExecServer::InitializeSandbox() {
std::string policy_string;
......@@ -86,7 +89,7 @@ bool SeatbeltExecServer::InitializeSandbox() {
mac::SandboxPolicy policy;
if (!policy.ParseFromString(policy_string)) {
LOG(ERROR) << "ParseFromString failed";
logging::Error("SeatbeltExecServer: ParseFromString failed");
return false;
}
......@@ -109,7 +112,8 @@ bool SeatbeltExecServer::ApplySandboxProfile(const mac::SandboxPolicy& policy) {
int rv = Seatbelt::InitWithParams(policy.profile().c_str(), 0,
weak_params.data(), &error);
if (error) {
LOG(ERROR) << "Failed to initialize sandbox: " << rv << " " << error;
logging::Error("SeatbeltExecServer: Failed to initialize sandbox: %d %s",
rv, error);
Seatbelt::FreeError(error);
return false;
}
......@@ -125,20 +129,18 @@ bool SeatbeltExecServer::ReadString(std::string* str) {
iov[0].iov_base = buffer.data();
iov[0].iov_len = buffer.size();
ssize_t read_length = HANDLE_EINTR(readv(fd_.get(), iov, arraysize(iov)));
ssize_t read_length = HANDLE_EINTR(readv(fd_, iov, arraysize(iov)));
if (read_length < 0) {
PLOG(ERROR) << "readv";
logging::PError("SeatbeltExecServer: readv failed");
return false;
}
str->assign(buffer.data());
return true;
}
bool SeatbeltExecServer::SetParameter(const base::StringPiece key,
const base::StringPiece value) {
return extra_params_
.insert(std::make_pair(key.as_string(), value.as_string()))
.second;
bool SeatbeltExecServer::SetParameter(const std::string& key,
const std::string& value) {
return extra_params_.insert(std::make_pair(key, value)).second;
}
} // namespace sandbox
......@@ -8,8 +8,6 @@
#include <string>
#include "base/compiler_specific.h"
#include "base/files/scoped_file.h"
#include "base/strings/string_piece.h"
#include "sandbox/mac/seatbelt.pb.h"
#include "sandbox/mac/seatbelt_export.h"
......@@ -28,15 +26,15 @@ class SEATBELT_EXPORT SeatbeltExecClient {
// added successfully.
// Set a boolean parameter in the sandbox profile.
bool SetBooleanParameter(const base::StringPiece key,
bool SetBooleanParameter(const std::string& key,
bool value) WARN_UNUSED_RESULT;
// Set a string parameter in the sandbox profile.
bool SetParameter(const base::StringPiece key,
const base::StringPiece value) WARN_UNUSED_RESULT;
bool SetParameter(const std::string& key,
const std::string& value) WARN_UNUSED_RESULT;
// Set the actual sandbox profile, using the scheme-like SBPL.
void SetProfile(const base::StringPiece policy);
void SetProfile(const std::string& policy);
// Sends the policy to the SeatbeltExecServer and returns the communication
// FD. The FD should be mapped into the sandboxed child process.
......@@ -78,8 +76,8 @@ class SEATBELT_EXPORT SeatbeltExecServer {
// server because the process about to initialize a sandbox may need to add
// some extra parameters, such as the path to the executable or the current
// PID. This must be called before InitializeSandbox().
bool SetParameter(const base::StringPiece key,
const base::StringPiece value) WARN_UNUSED_RESULT;
bool SetParameter(const std::string& key,
const std::string& value) WARN_UNUSED_RESULT;
private:
// Reads from the |fd_| and stores the data into a string. This does
......@@ -87,7 +85,7 @@ class SEATBELT_EXPORT SeatbeltExecServer {
bool ReadString(std::string* string);
// The file descriptor used to communicate with the launcher process.
base::ScopedFD fd_;
int fd_;
// Extra parameters added by the server process.
std::map<std::string, std::string> extra_params_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment