Skip to content

Commit

Permalink
Linux Sandbox: split the GPU policies to their own files.
Browse files Browse the repository at this point in the history
We split the GPU policies to their own independant files in order to make
sandbox_seccomp_bpf_linux.cc more sane.

Moreover, we clean up the logic so that the "WarmUp" process is an
implementation of SandboxBPFBasePolicy::PreSandboxHook().

More work remains to clean-up the GPU policies, but this is an important
first step.

In addition, we put all Linux sandboxing related files in content/common in
a new sandbox_linux directory.

BUG=325535
R=jorgelo@chromium.org, mseaborn@chromium.org, piman@chromium.org, rsesek@chromium.org

Review URL: https://codereview.chromium.org/99133015

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240509 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
jln@chromium.org committed Dec 13, 2013
1 parent 6c79aea commit 4dcd331
Show file tree
Hide file tree
Showing 26 changed files with 1,045 additions and 842 deletions.
9 changes: 6 additions & 3 deletions components/nacl.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,19 @@
],
'defines': [
'<@(nacl_defines)',
# Allow .cc files to know if they're being compiled as part
# of nacl_helper.
'IN_NACL_HELPER=1',
],
'sources': [
'nacl/loader/nacl_sandbox_linux.cc',
'nacl/loader/nacl_helper_linux.cc',
'nacl/loader/nacl_helper_linux.h',
'../base/posix/unix_domain_socket_linux.cc',
'../content/common/child_process_sandbox_support_impl_shm_linux.cc',
'../content/common/sandbox_bpf_base_policy_linux.cc',
'../content/common/sandbox_init_linux.cc',
'../content/common/sandbox_seccomp_bpf_linux.cc',
'../content/common/sandbox_linux/sandbox_bpf_base_policy_linux.cc',
'../content/common/sandbox_linux/sandbox_init_linux.cc',
'../content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc',
'../content/public/common/content_switches.cc',
],
'conditions': [
Expand Down
2 changes: 1 addition & 1 deletion content/browser/renderer_host/render_sandbox_host_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include "base/strings/string_util.h"
#include "content/child/webkitplatformsupport_impl.h"
#include "content/common/font_config_ipc_linux.h"
#include "content/common/sandbox_linux.h"
#include "content/common/sandbox_linux/sandbox_linux.h"
#include "content/common/set_process_title.h"
#include "content/public/common/content_switches.h"
#include "skia/ext/skia_utils_base.h"
Expand Down
5 changes: 0 additions & 5 deletions content/common/OWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ per-file pepper*=bauerb@chromium.org
per-file plugin*=ananta@chromium.org
per-file plugin*=bauerb@chromium.org

# Linux sandbox seccomp-bpf policies:
per-file sandbox_seccomp_bpf_linux.*=jln@chromium.org
per-file sandbox_seccomp_bpf_linux.*=cevans@chromium.org
per-file sandbox_seccomp_bpf_linux.*=jorgelo@chromium.org

# Changes to IPC messages require a security review to avoid introducing
# new sandbox escapes.
per-file *_messages*.h=set noparent
Expand Down
2 changes: 1 addition & 1 deletion content/common/child_process_sandbox_support_impl_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "base/posix/unix_domain_socket_linux.h"
#include "base/safe_numerics.h"
#include "base/sys_byteorder.h"
#include "content/common/sandbox_linux.h"
#include "content/common/sandbox_linux/sandbox_linux.h"
#include "third_party/WebKit/public/platform/linux/WebFontFamily.h"
#include "third_party/WebKit/public/platform/linux/WebFontRenderStyle.h"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include "base/pickle.h"
#include "base/posix/unix_domain_socket_linux.h"
#include "content/common/sandbox_linux.h"
#include "content/common/sandbox_linux/sandbox_linux.h"

namespace content {

Expand Down
3 changes: 3 additions & 0 deletions content/common/sandbox_linux/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cevans@chromium.org
jln@chromium.org
jorgelo@chromium.org
226 changes: 226 additions & 0 deletions content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
// Copyright (c) 2013 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 "content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h"

#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <vector>

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h"
#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
#include "sandbox/linux/services/linux_syscalls.h"

using sandbox::ErrorCode;
using sandbox::SandboxBPF;
using sandbox::SyscallSets;

namespace content {

namespace {

inline bool IsChromeOS() {
#if defined(OS_CHROMEOS)
return true;
#else
return false;
#endif
}

inline bool IsArchitectureArm() {
#if defined(__arm__)
return true;
#else
return false;
#endif
}

void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist,
std::vector<std::string>* write_whitelist) {
// Device file needed by the ARM GPU userspace.
static const char kMali0Path[] = "/dev/mali0";

// Devices needed for video decode acceleration on ARM.
static const char kDevMfcDecPath[] = "/dev/mfc-dec";
static const char kDevGsc1Path[] = "/dev/gsc1";

// Devices needed for video encode acceleration on ARM.
static const char kDevMfcEncPath[] = "/dev/mfc-enc";

read_whitelist->push_back(kMali0Path);
read_whitelist->push_back(kDevMfcDecPath);
read_whitelist->push_back(kDevGsc1Path);
read_whitelist->push_back(kDevMfcEncPath);

write_whitelist->push_back(kMali0Path);
write_whitelist->push_back(kDevMfcDecPath);
write_whitelist->push_back(kDevGsc1Path);
write_whitelist->push_back(kDevMfcEncPath);
}

void AddArmTegraGpuWhitelist(std::vector<std::string>* read_whitelist,
std::vector<std::string>* write_whitelist) {
// Device files needed by the Tegra GPU userspace.
static const char kDevNvhostCtrlPath[] = "/dev/nvhost-ctrl";
static const char kDevNvhostGr2dPath[] = "/dev/nvhost-gr2d";
static const char kDevNvhostGr3dPath[] = "/dev/nvhost-gr3d";
static const char kDevNvhostIspPath[] = "/dev/nvhost-isp";
static const char kDevNvhostViPath[] = "/dev/nvhost-vi";
static const char kDevNvmapPath[] = "/dev/nvmap";
static const char kDevTegraSemaPath[] = "/dev/tegra_sema";

read_whitelist->push_back(kDevNvhostCtrlPath);
read_whitelist->push_back(kDevNvhostGr2dPath);
read_whitelist->push_back(kDevNvhostGr3dPath);
read_whitelist->push_back(kDevNvhostIspPath);
read_whitelist->push_back(kDevNvhostViPath);
read_whitelist->push_back(kDevNvmapPath);
read_whitelist->push_back(kDevTegraSemaPath);

write_whitelist->push_back(kDevNvhostCtrlPath);
write_whitelist->push_back(kDevNvhostGr2dPath);
write_whitelist->push_back(kDevNvhostGr3dPath);
write_whitelist->push_back(kDevNvhostIspPath);
write_whitelist->push_back(kDevNvhostViPath);
write_whitelist->push_back(kDevNvmapPath);
write_whitelist->push_back(kDevTegraSemaPath);
}

void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist,
std::vector<std::string>* write_whitelist) {
// On ARM we're enabling the sandbox before the X connection is made,
// so we need to allow access to |.Xauthority|.
static const char kXAuthorityPath[] = "/home/chronos/.Xauthority";
static const char kLdSoCache[] = "/etc/ld.so.cache";

// Files needed by the ARM GPU userspace.
static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";

read_whitelist->push_back(kXAuthorityPath);
read_whitelist->push_back(kLdSoCache);
read_whitelist->push_back(kLibGlesPath);
read_whitelist->push_back(kLibEglPath);

AddArmMaliGpuWhitelist(read_whitelist, write_whitelist);
AddArmTegraGpuWhitelist(read_whitelist, write_whitelist);
}

class CrosArmGpuBrokerProcessPolicy : public CrosArmGpuProcessPolicy {
public:
CrosArmGpuBrokerProcessPolicy() : CrosArmGpuProcessPolicy(false) {}
virtual ~CrosArmGpuBrokerProcessPolicy() {}

virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
int system_call_number) const OVERRIDE;

private:
DISALLOW_COPY_AND_ASSIGN(CrosArmGpuBrokerProcessPolicy);
};

// A GPU broker policy is the same as a GPU policy with open and
// openat allowed.
ErrorCode CrosArmGpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
int sysno) const {
switch (sysno) {
case __NR_access:
case __NR_open:
case __NR_openat:
return ErrorCode(ErrorCode::ERR_ALLOWED);
default:
return CrosArmGpuProcessPolicy::EvaluateSyscall(sandbox, sysno);
}
}

bool EnableArmGpuBrokerPolicyCallback() {
return SandboxSeccompBPF::StartSandboxWithExternalPolicy(
scoped_ptr<sandbox::SandboxBPFPolicy>(new CrosArmGpuBrokerProcessPolicy));
}

} // namespace

CrosArmGpuProcessPolicy::CrosArmGpuProcessPolicy(bool allow_shmat)
: allow_shmat_(allow_shmat) {}

CrosArmGpuProcessPolicy::~CrosArmGpuProcessPolicy() {}

ErrorCode CrosArmGpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
int sysno) const {
#if defined(__arm__)
if (allow_shmat_ && sysno == __NR_shmat)
return ErrorCode(ErrorCode::ERR_ALLOWED);
#endif // defined(__arm__)

switch (sysno) {
#if defined(__arm__)
// ARM GPU sandbox is started earlier so we need to allow networking
// in the sandbox.
case __NR_connect:
case __NR_getpeername:
case __NR_getsockname:
case __NR_sysinfo:
case __NR_uname:
return ErrorCode(ErrorCode::ERR_ALLOWED);
// Allow only AF_UNIX for |domain|.
case __NR_socket:
case __NR_socketpair:
return sandbox->Cond(0, ErrorCode::TP_32BIT,
ErrorCode::OP_EQUAL, AF_UNIX,
ErrorCode(ErrorCode::ERR_ALLOWED),
ErrorCode(EPERM));
#endif // defined(__arm__)
default:
if (SyscallSets::IsAdvancedScheduler(sysno))
return ErrorCode(ErrorCode::ERR_ALLOWED);

// Default to the generic GPU policy.
return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno);
}
}

bool CrosArmGpuProcessPolicy::PreSandboxHook() {
DCHECK(IsChromeOS() && IsArchitectureArm());
// Create a new broker process.
DCHECK(!broker_process());

std::vector<std::string> read_whitelist_extra;
std::vector<std::string> write_whitelist_extra;
// Add ARM-specific files to whitelist in the broker.

AddArmGpuWhitelist(&read_whitelist_extra, &write_whitelist_extra);
InitGpuBrokerProcess(EnableArmGpuBrokerPolicyCallback,
read_whitelist_extra,
write_whitelist_extra);

const int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE;

// Preload the Mali library.
dlopen("/usr/lib/libmali.so", dlopen_flag);

// Preload the Tegra libraries.
dlopen("/usr/lib/libnvrm.so", dlopen_flag);
dlopen("/usr/lib/libnvrm_graphics.so", dlopen_flag);
dlopen("/usr/lib/libnvos.so", dlopen_flag);
dlopen("/usr/lib/libnvddk_2d.so", dlopen_flag);
dlopen("/usr/lib/libardrv_dynamic.so", dlopen_flag);
dlopen("/usr/lib/libnvwsi.so", dlopen_flag);
dlopen("/usr/lib/libnvglsi.so", dlopen_flag);
dlopen("/usr/lib/libcgdrv.so", dlopen_flag);

return true;
}

} // namespace content
29 changes: 29 additions & 0 deletions content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2013 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 CONTENT_COMMON_SANDBOX_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_
#define CONTENT_COMMON_SANDBOX_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_

#include "content/common/sandbox_linux/bpf_gpu_policy_linux.h"

namespace content {

// This policy is for Chrome OS ARM.
class CrosArmGpuProcessPolicy : public GpuProcessPolicy {
public:
explicit CrosArmGpuProcessPolicy(bool allow_shmat);
virtual ~CrosArmGpuProcessPolicy();

virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
int system_call_number) const OVERRIDE;
virtual bool PreSandboxHook() OVERRIDE;

private:
const bool allow_shmat_; // Allow shmat(2).
DISALLOW_COPY_AND_ASSIGN(CrosArmGpuProcessPolicy);
};

} // namespace content

#endif // CONTENT_COMMON_SANDBOX_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_
Loading

0 comments on commit 4dcd331

Please sign in to comment.