diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-15 20:13:38 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-15 20:13:38 +0000 |
commit | ad6d2c4304320a300009682901199278fabd3148 (patch) | |
tree | a85ecca65867c1a5696c7075a3def08525a496e2 | |
parent | 2f4e8134c2a1d868eb4264dfb110cab5a94f43d7 (diff) | |
download | chromium_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.gypi | 6 | ||||
-rw-r--r-- | build/linux/system.gyp | 9 | ||||
-rw-r--r-- | chrome/browser/zygote_main_linux.cc | 78 | ||||
-rw-r--r-- | chrome/chrome.gyp | 19 | ||||
-rw-r--r-- | chrome/renderer/renderer_main_platform_delegate_linux.cc | 2 | ||||
-rw-r--r-- | sandbox/sandbox.gyp | 11 |
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': [ { |