summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-15 20:13:38 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-15 20:13:38 +0000
commitad6d2c4304320a300009682901199278fabd3148 (patch)
treea85ecca65867c1a5696c7075a3def08525a496e2
parent2f4e8134c2a1d868eb4264dfb110cab5a94f43d7 (diff)
downloadchromium_src-ad6d2c4304320a300009682901199278fabd3148.zip
chromium_src-ad6d2c4304320a300009682901199278fabd3148.tar.gz
chromium_src-ad6d2c4304320a300009682901199278fabd3148.tar.bz2
Linux: add support for SELinux.
This patch adds support for a selinux GYP variable which, when set to one, does the following: * Removes the seccomp sandbox from the compile * Removes support for SUID sandboxing from the zygote * Performs a dynamic transition, in the zygote, to chromium_renderer_t. This code requires that the system policy have a sensible set of access vectors for the chromium_renderer_t type. Such a policy will be found in sandbox/selinux in the future. http://codereview.chromium.org/203071 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26257 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--build/common.gypi6
-rw-r--r--build/linux/system.gyp9
-rw-r--r--chrome/browser/zygote_main_linux.cc78
-rw-r--r--chrome/chrome.gyp19
-rw-r--r--chrome/renderer/renderer_main_platform_delegate_linux.cc2
-rw-r--r--sandbox/sandbox.gyp11
6 files changed, 103 insertions, 22 deletions
diff --git a/build/common.gypi b/build/common.gypi
index aeb5d11..7b8ad12 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -112,6 +112,9 @@
# sandbox the zygote process and, thus, all renderer processes.
'linux_sandbox_path%': '',
+ # Set this to true to enable SELinux support.
+ 'selinux%': 0,
+
'conditions': [
['OS=="linux"', {
'conditions': [
@@ -189,6 +192,9 @@
['chromeos==1', {
'defines': ['OS_CHROMEOS=1'],
}],
+ ['selinux==1', {
+ 'defines': ['CHROMIUM_SELINUX=1'],
+ }],
['coverage!=0', {
'conditions': [
['OS=="mac"', {
diff --git a/build/linux/system.gyp b/build/linux/system.gyp
index 7b6d82c..5275373 100644
--- a/build/linux/system.gyp
+++ b/build/linux/system.gyp
@@ -135,6 +135,15 @@
],
},
},
+ {
+ 'target_name': 'selinux',
+ 'type': 'settings',
+ 'link_settings': {
+ 'libraries': [
+ '-lselinux',
+ ],
+ },
+ },
# TODO(evanm): temporarily disabled while we figure out whether to depend
# on gnome-keyring etc.
# http://code.google.com/p/chromium/issues/detail?id=12351
diff --git a/chrome/browser/zygote_main_linux.cc b/chrome/browser/zygote_main_linux.cc
index ac9067f..fd365ab 100644
--- a/chrome/browser/zygote_main_linux.cc
+++ b/chrome/browser/zygote_main_linux.cc
@@ -32,6 +32,11 @@
#include "skia/ext/SkFontHost_fontconfig_control.h"
+#if defined(CHROMIUM_SELINUX)
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+#endif
+
// http://code.google.com/p/chromium/wiki/LinuxZygote
static const int kMagicSandboxIPCDescriptor = 5;
@@ -207,6 +212,10 @@ class Zygote {
}
};
+// With SELinux we can carve out a precise sandbox, so we don't have to play
+// with intercepting libc calls.
+#if !defined(CHROMIUM_SELINUX)
+
static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output,
char* timezone_out,
size_t timezone_out_len) {
@@ -351,22 +360,11 @@ static void WarnOnceAboutBrokenDlsym() {
have_shown_warning = true;
}
}
+#endif // !CHROMIUM_SELINUX
-static bool MaybeEnterChroot() {
- const char* const sandbox_fd_string = getenv("SBX_D");
- if (sandbox_fd_string) {
- // The SUID sandbox sets this environment variable to a file descriptor
- // over which we can signal that we have completed our startup and can be
- // chrooted.
-
- char* endptr;
- const long fd_long = strtol(sandbox_fd_string, &endptr, 10);
- if (!*sandbox_fd_string || *endptr || fd_long < 0 || fd_long > INT_MAX)
- return false;
- const int fd = fd_long;
-
- // Before entering the sandbox, "prime" any systems that need to open
- // files and cache the results or the descriptors.
+// This function triggers the static and lazy construction of objects that need
+// to be created before imposing the sandbox.
+static void PreSandboxInit() {
base::RandUint64();
base::SysInfo::MaxSharedMemorySize();
@@ -382,6 +380,23 @@ static bool MaybeEnterChroot() {
FilePath module_path;
if (PathService::Get(base::DIR_MODULE, &module_path))
media::InitializeMediaLibrary(module_path);
+}
+
+#if !defined(CHROMIUM_SELINUX)
+static bool EnterSandbox() {
+ const char* const sandbox_fd_string = getenv("SBX_D");
+ if (sandbox_fd_string) {
+ // The SUID sandbox sets this environment variable to a file descriptor
+ // over which we can signal that we have completed our startup and can be
+ // chrooted.
+
+ char* endptr;
+ const long fd_long = strtol(sandbox_fd_string, &endptr, 10);
+ if (!*sandbox_fd_string || *endptr || fd_long < 0 || fd_long > INT_MAX)
+ return false;
+ const int fd = fd_long;
+
+ PreSandboxInit();
static const char kChrootMe = 'C';
static const char kChrootMeSuccess = 'O';
@@ -438,11 +453,42 @@ static bool MaybeEnterChroot() {
return true;
}
+#else // CHROMIUM_SELINUX
+
+static bool EnterSandbox() {
+ PreSandboxInit();
+ SkiaFontConfigUseIPCImplementation(kMagicSandboxIPCDescriptor);
+
+ security_context_t security_context;
+ if (getcon(&security_context)) {
+ LOG(ERROR) << "Cannot get SELinux context";
+ return false;
+ }
+
+ context_t context = context_new(security_context);
+ context_type_set(context, "chromium_renderer_t");
+ const int r = setcon(context_str(context));
+ context_free(context);
+ freecon(security_context);
+
+ if (r) {
+ LOG(ERROR) << "dynamic transition to type 'chromium_renderer_t' failed. "
+ "(this binary has been built with SELinux support, but maybe "
+ "the policies haven't been loaded into the kernel?";
+ return false;
+ }
+
+ return true;
+}
+
+#endif // CHROMIUM_SELINUX
bool ZygoteMain(const MainFunctionParams& params) {
+#if !defined(CHROMIUM_SELINUX)
g_am_zygote_or_renderer = true;
+#endif
- if (!MaybeEnterChroot()) {
+ if (!EnterSandbox()) {
LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: "
<< errno << ")";
return false;
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index f84f6a2..c45a581 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -648,6 +648,11 @@
'third_party/xdg_user_dirs/xdg_user_dir_lookup.cc',
],
}],
+ ['OS=="linux" and selinux==1', {
+ 'dependencies': [
+ '../build/linux/system.gyp:selinux',
+ ],
+ }],
['OS=="win"', {
'include_dirs': [
'third_party/wtl/include',
@@ -3393,9 +3398,11 @@
'installer/installer.gyp:installer_util',
],
}],
- ],
- 'dependencies': [
- '../sandbox/sandbox.gyp:sandbox',
+ ['selinux==0', {
+ 'dependencies': [
+ '../sandbox/sandbox.gyp:sandbox',
+ ],
+ }],
],
}],
['OS=="mac" or OS=="win"', {
@@ -4247,11 +4254,15 @@
['exclude', '^browser/chromeos'],
],
}],
+ ['OS=="linux" and selinux==0', {
+ 'dependencies': [
+ '../sandbox/sandbox.gyp:*',
+ ],
+ }],
['OS=="linux"', {
'dependencies': [
'../build/linux/system.gyp:gtk',
'../build/linux/system.gyp:nss',
- '../sandbox/sandbox.gyp:*',
],
'sources': [
'browser/renderer_host/gtk_key_bindings_handler_unittest.cc',
diff --git a/chrome/renderer/renderer_main_platform_delegate_linux.cc b/chrome/renderer/renderer_main_platform_delegate_linux.cc
index d93f1a5..56bdcf5 100644
--- a/chrome/renderer/renderer_main_platform_delegate_linux.cc
+++ b/chrome/renderer/renderer_main_platform_delegate_linux.cc
@@ -36,7 +36,7 @@ bool RendererMainPlatformDelegate::EnableSandbox() {
//
// The seccomp sandbox is started in the renderer.
// http://code.google.com/p/seccompsandbox/
-#if defined(ARCH_CPU_X86_FAMILY)
+#if defined(ARCH_CPU_X86_FAMILY) && !defined(CHROMIUM_SELINUX)
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableSeccompSandbox)) {
StartSeccompSandbox();
diff --git a/sandbox/sandbox.gyp b/sandbox/sandbox.gyp
index 186625f..5d5ebc5 100644
--- a/sandbox/sandbox.gyp
+++ b/sandbox/sandbox.gyp
@@ -7,7 +7,7 @@
'../build/common.gypi',
],
'conditions': [
- [ 'OS=="linux"', {
+ [ 'OS=="linux" and selinux==0', {
'targets': [
{
'target_name': 'chrome_sandbox',
@@ -69,6 +69,15 @@
]},
],
}],
+ [ 'OS=="linux" and selinux==1', {
+ # GYP requires that each file have at least one target defined.
+ 'targets': [
+ {
+ 'target_name': 'sandbox',
+ 'type': 'settings',
+ },
+ ],
+ }],
[ 'OS=="win"', {
'targets': [
{