Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(917)

Unified Diff: content/common/sandbox_seccomp_bpf_linux.cc

Issue 11569028: Linux Sandbox: Basic support for GPU broker. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sandbox/linux/services/broker_process.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/sandbox_seccomp_bpf_linux.cc
diff --git a/content/common/sandbox_seccomp_bpf_linux.cc b/content/common/sandbox_seccomp_bpf_linux.cc
index 5491e8b79fa37b10e7ded6aa4c31970f258c087c..6217db3af99700a0db6363a0b860076d0b177430 100644
--- a/content/common/sandbox_seccomp_bpf_linux.cc
+++ b/content/common/sandbox_seccomp_bpf_linux.cc
@@ -23,6 +23,7 @@
#include "content/common/sandbox_linux.h"
#include "content/common/sandbox_seccomp_bpf_linux.h"
#include "content/public/common/content_switches.h"
+#include "sandbox/linux/services/broker_process.h"
// These are the only architectures supported for now.
#if defined(__i386__) || defined(__x86_64__) || \
@@ -37,6 +38,7 @@
using playground2::arch_seccomp_data;
using playground2::ErrorCode;
using playground2::Sandbox;
+using sandbox::BrokerProcess;
namespace {
@@ -100,71 +102,28 @@ bool IsAcceleratedVideoDecodeEnabled() {
return is_enabled;
}
-static const char kDriRcPath[] = "/etc/drirc";
-
-// TODO(jorgelo): limited to /etc/drirc for now, extend this to cover
-// other sandboxed file access cases.
-int OpenWithCache(const char* pathname, int flags) {
- static int drircfd = -1;
- static bool do_open = true;
- int res = -1;
-
- if (strcmp(pathname, kDriRcPath) == 0 && flags == O_RDONLY) {
- if (do_open) {
- drircfd = open(pathname, flags);
- do_open = false;
- res = drircfd;
- } else {
- // dup() man page:
- // "After a successful return from one of these system calls,
- // the old and new file descriptors may be used interchangeably.
- // They refer to the same open file description and thus share
- // file offset and file status flags; for example, if the file offset
- // is modified by using lseek(2) on one of the descriptors,
- // the offset is also changed for the other."
- // Since |drircfd| can be dup()'ed and read many times, we need to
- // lseek() it to the beginning of the file before returning.
- // We assume the caller will not keep more than one fd open at any
- // one time. Intel driver code in Mesa that parses /etc/drirc does
- // open()/read()/close() in the same function.
- if (drircfd < 0) {
- errno = ENOENT;
- return -1;
- }
- int newfd = dup(drircfd);
- if (newfd < 0) {
- errno = ENOMEM;
- return -1;
- }
- if (lseek(newfd, 0, SEEK_SET) == static_cast<off_t>(-1)) {
- (void) HANDLE_EINTR(close(newfd));
- errno = ENOMEM;
- return -1;
- }
- res = newfd;
- }
- } else {
- res = open(pathname, flags);
- }
-
- return res;
-}
-
-// We allow the GPU process to open /etc/drirc because it's needed by Mesa.
-// OpenWithCache() has been called before enabling the sandbox, and has cached
-// a file descriptor for /etc/drirc.
intptr_t GpuOpenSIGSYS_Handler(const struct arch_seccomp_data& args,
- void* aux) {
- uint64_t arg0 = args.args[0];
- uint64_t arg1 = args.args[1];
- const char* pathname = reinterpret_cast<const char*>(arg0);
- int flags = static_cast<int>(arg1);
-
- if (strcmp(pathname, kDriRcPath) == 0) {
- int ret = OpenWithCache(pathname, flags);
- return (ret == -1) ? -errno : ret;
- } else {
- return -ENOENT;
+ void* aux_broker_process) {
+ RAW_CHECK(aux_broker_process);
+ BrokerProcess* broker_process =
+ static_cast<BrokerProcess*>(aux_broker_process);
+ switch(args.nr) {
+ case __NR_open:
+ return broker_process->Open(reinterpret_cast<const char*>(args.args[0]),
+ static_cast<int>(args.args[1]));
+ case __NR_openat:
+ // We only call open() so if we arrive here, it's because glibc uses
+ // the openat() system call.
+ if (static_cast<int>(args.args[0]) == AT_FDCWD) {
+ return
+ broker_process->Open(reinterpret_cast<const char*>(args.args[1]),
+ static_cast<int>(args.args[2]));
+ } else {
+ return -EPERM;
+ }
+ default:
+ RAW_CHECK(false);
+ return -ENOSYS;
}
}
@@ -1234,7 +1193,7 @@ ErrorCode BaselinePolicy(int sysno) {
}
// x86_64 only for now. Needs to be adapted and tested for i386/ARM.
-ErrorCode GpuProcessPolicy_x86_64(int sysno, void *) {
+ErrorCode GpuProcessPolicy_x86_64(int sysno, void *broker_process) {
switch(sysno) {
case __NR_ioctl:
#if defined(ADDRESS_SANITIZER)
@@ -1243,20 +1202,8 @@ ErrorCode GpuProcessPolicy_x86_64(int sysno, void *) {
#endif
return ErrorCode(ErrorCode::ERR_ALLOWED);
case __NR_open:
- // Accelerated video decode is enabled by default only on Chrome OS.
- if (IsAcceleratedVideoDecodeEnabled()) {
- // Accelerated video decode needs to open /dev/dri/card0, and
- // dup()'ing an already open file descriptor does not work.
- // Allow open() even though it severely weakens the sandbox,
- // to test the sandboxing mechanism in general.
- // TODO(jorgelo): remove this once we solve the libva issue.
- return ErrorCode(ErrorCode::ERR_ALLOWED);
- } else {
- // Hook open() in the GPU process to allow opening /etc/drirc,
- // needed by Mesa.
- // The hook needs dup(), lseek(), and close() to be allowed.
- return Sandbox::Trap(GpuOpenSIGSYS_Handler, NULL);
- }
+ case __NR_openat:
+ return Sandbox::Trap(GpuOpenSIGSYS_Handler, broker_process);
default:
if (IsEventFd(sysno))
return ErrorCode(ErrorCode::ERR_ALLOWED);
@@ -1358,11 +1305,29 @@ ErrorCode AllowAllPolicy(int sysno, void *) {
}
}
+// Start a broker process to handle open() inside the sandbox.
+void InitGpu64BrokerProcess(BrokerProcess** broker_process) {
Jorge Lucangeli Obes 2012/12/14 19:13:22 X86_64 I guess, although it does make the name of
jln (very slow on Chromium) 2012/12/14 20:30:25 Done.
+ static const char kDriRcPath[] = "/etc/drirc";
+ static const char kDriCard0Path[] = "/dev/dri/card0";
+
+ CHECK(broker_process);
+ CHECK(*broker_process == NULL);
+
+ std::vector<std::string> read_whitelist;
+ read_whitelist.push_back(kDriCard0Path);
+ read_whitelist.push_back(kDriRcPath);
+ std::vector<std::string> write_whitelist;
+ write_whitelist.push_back(kDriCard0Path);
+
+ *broker_process = new BrokerProcess(read_whitelist, write_whitelist);
+ CHECK((*broker_process)->Init(NULL));
+}
+
// Warms up/preloads resources needed by the policies.
-void WarmupPolicy(Sandbox::EvaluateSyscall policy) {
+void WarmupPolicy(Sandbox::EvaluateSyscall policy,
+ BrokerProcess** broker_process) {
#if defined(__x86_64__)
if (policy == GpuProcessPolicy_x86_64) {
- OpenWithCache(kDriRcPath, O_RDONLY);
// Accelerated video decode dlopen()'s this shared object
// inside the sandbox, so preload it now.
// TODO(jorgelo): generalize this to other platforms.
@@ -1371,6 +1336,7 @@ void WarmupPolicy(Sandbox::EvaluateSyscall policy) {
"/usr/lib64/va/drivers/i965_drv_video.so";
dlopen(kI965DrvVideoPath_64, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
}
+ InitGpu64BrokerProcess(broker_process);
}
#endif
}
@@ -1410,15 +1376,18 @@ Sandbox::EvaluateSyscall GetProcessSyscallPolicy(
}
// Initialize the seccomp-bpf sandbox.
+// Eventually create a BrokerProcess and return it to broker_process.
bool StartBpfSandbox(const CommandLine& command_line,
const std::string& process_type) {
Sandbox::EvaluateSyscall SyscallPolicy =
GetProcessSyscallPolicy(command_line, process_type);
- // Warms up resources needed by the policy we're about to enable.
- WarmupPolicy(SyscallPolicy);
+ BrokerProcess* broker_process = NULL;
+ // Warms up resources needed by the policy we're about to enable and
+ // eventually start a broker process.
Jorge Lucangeli Obes 2012/12/14 19:13:22 'starts' to match 'Warms'.
jln (very slow on Chromium) 2012/12/14 20:30:25 Done.
+ WarmupPolicy(SyscallPolicy, &broker_process);
- Sandbox::setSandboxPolicy(SyscallPolicy, NULL);
+ Sandbox::setSandboxPolicy(SyscallPolicy, broker_process);
Sandbox::startSandbox();
return true;
« no previous file with comments | « no previous file | sandbox/linux/services/broker_process.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698