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

Side by Side Diff: content/common/sandbox_linux.cc

Issue 10826093: Create a LinuxSandbox class (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Jorge's comments. Created 8 years, 4 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <fcntl.h>
6 #include <sys/stat.h>
7 #include <sys/types.h>
8
9 #include "base/command_line.h"
10 #include "base/eintr_wrapper.h"
11 #include "base/logging.h"
12 #include "base/memory/singleton.h"
13 #include "content/common/sandbox_linux.h"
14 #include "content/common/seccomp_sandbox.h"
15 #include "content/public/common/content_switches.h"
16 #include "content/public/common/sandbox_linux.h"
17 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
18 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
19
20 namespace {
21
22 // Implement the command line enabling logic for seccomp-legacy.
23 bool IsSeccompLegacyDesired() {
24 #if defined(SECCOMP_SANDBOX)
25 #if defined(NDEBUG)
26 // Off by default; allow turning on with a switch.
27 return CommandLine::ForCurrentProcess()->HasSwitch(
28 switches::kEnableSeccompSandbox);
29 #else
30 // On by default; allow turning off with a switch.
31 return !CommandLine::ForCurrentProcess()->HasSwitch(
32 switches::kDisableSeccompSandbox);
33 #endif // NDEBUG
34 #endif // SECCOMP_SANDBOX
35 return false;
36 }
37
38 } // namespace
39
40 namespace content {
41
42 LinuxSandbox::LinuxSandbox()
43 : proc_fd_(-1),
44 pre_initialized_(false),
45 seccomp_legacy_supported_(false),
46 setuid_sandbox_(NULL) {
47 }
48
49 LinuxSandbox::~LinuxSandbox() {
50 if (setuid_sandbox_)
51 delete setuid_sandbox_;
piman 2012/08/02 17:31:20 That calls for scoped_ptr
jln (very slow on Chromium) 2012/08/02 18:25:22 Done.
52 }
53
54 LinuxSandbox* LinuxSandbox::GetInstance() {
55 LinuxSandbox* instance = Singleton<LinuxSandbox>::get();
56 CHECK(instance);
57 instance->setuid_sandbox_ = sandbox::SetuidSandboxClient::Create();
piman 2012/08/02 17:31:20 Arguably, that part could go to the constructor. E
58 if (!instance->setuid_sandbox_) {
59 LOG(FATAL) << "Failed to instantiate the setuid sandbox client.";
60 }
61 return instance;
62 }
63
64 void LinuxSandbox::PreinitializeSandbox() {
65 CHECK(!pre_initialized_);
66 seccomp_legacy_supported_ = false;
67 #if defined(SECCOMP_SANDBOX)
68 if (IsSeccompLegacyDesired()) {
69 proc_fd_ = open("/proc", O_DIRECTORY | O_RDONLY);
70 if (proc_fd_ < 0) {
71 LOG(ERROR) << "Cannot access \"/proc\". Disabling seccomp-legacy "
72 "sandboxing.";
73 // Now is a good time to figure out if we can support seccomp sandboxing at
piman 2012/08/02 17:31:20 The comment seems indented wrong.
jln (very slow on Chromium) 2012/08/02 18:25:22 Done.
74 // all. We will call SupportsSeccompSandbox again later, when actually
75 // enabling it, but we allow the implementation to cache some information.
76 // This is the only place where we will log full lack of seccomp-legacy
77 // support.
78 } else if (!SupportsSeccompSandbox(proc_fd_)) {
79 VLOG(1) << "Lacking support for seccomp-legacy sandbox.";
80 CHECK_EQ(HANDLE_EINTR(close(proc_fd_)), 0);
81 proc_fd_ = -1;
82 } else {
83 seccomp_legacy_supported_ = true;
84 }
85 }
86 #endif // SECCOMP_SANDBOX
87 #if defined(SECCOMP_BPF_SANDBOX)
88 // Similarly, we "pre-warm" the code that detects supports for seccomp BPF.
89 // TODO(jln): Use proc_fd_ here too once we're comfortable it does not create
90 // an additional security risk.
91 if (playground2::Sandbox::supportsSeccompSandbox(-1) !=
92 playground2::Sandbox::STATUS_AVAILABLE) {
93 VLOG(1) << "Lacking support for seccomp-bpf sandbox.";
94 }
95 #endif // SECCOMP_BPF_SANDBOX
96 pre_initialized_ = true;
97 }
98
99 // Once we finally know our process type, we can cleanup proc_fd_
100 // or pass it to seccomp-legacy.
101 void LinuxSandbox::PreinitializeSandboxFinish(
102 const std::string& process_type) {
103 CHECK(pre_initialized_);
104 if (proc_fd_ >= 0) {
105 if (ShouldEnableSeccompLegacy(process_type)) {
106 #if defined(SECCOMP_SANDBOX)
107 SeccompSandboxSetProcFd(proc_fd_);
108 #endif
109 } else {
110 DCHECK_GE(proc_fd_, 0);
111 CHECK_EQ(HANDLE_EINTR(close(proc_fd_)), 0);
112 }
113 proc_fd_ = -1;
114 }
115 }
116
117 // Simplify the life of the caller if they know their process type.
piman 2012/08/02 17:31:20 I don't think that comment helps anything, you can
jln (very slow on Chromium) 2012/08/02 18:25:22 Done.
118 void LinuxSandbox::PreinitializeSandbox(const std::string& process_type) {
119 PreinitializeSandbox();
120 PreinitializeSandboxFinish(process_type);
121 }
122
123 int LinuxSandbox::GetStatus() {
124 CHECK(pre_initialized_);
125 int sandbox_flags = 0;
126 if (setuid_sandbox_->IsSandboxed()) {
127 sandbox_flags |= kSandboxLinuxSUID;
128 if (setuid_sandbox_->IsInNewPIDNamespace())
129 sandbox_flags |= kSandboxLinuxPIDNS;
130 if (setuid_sandbox_->IsInNewNETNamespace())
131 sandbox_flags |= kSandboxLinuxNetNS;
132 }
133 if (seccomp_legacy_supported_) {
134 // Note: The current mechanism does not report if the sandbox is activated
135 // but only if it can be attempted.
piman 2012/08/02 17:31:20 It sounds like the comment would be more useful on
jln (very slow on Chromium) 2012/08/02 18:25:22 Done.
136 sandbox_flags |= kSandboxLinuxSeccomp;
137 }
138 return sandbox_flags;
139 }
140
141 sandbox::SetuidSandboxClient* LinuxSandbox::setuid_sandbox() {
142 return setuid_sandbox_;
143 }
144
145 // For seccomp-legacy, we implement the policy inline, here.
146 bool LinuxSandbox::StartSeccompLegacy(const std::string& process_type) {
147 CHECK(pre_initialized_);
148 if (ShouldEnableSeccompLegacy(process_type)) {
149 // SupportsSeccompSandbox() returns a cached result, as we already
150 // called it earlier in the PreinitializeSandbox(). Thus, it is OK for us
151 // to not pass in a file descriptor for "/proc".
152 #if defined(SECCOMP_SANDBOX)
153 if (SupportsSeccompSandbox(-1)) {
154 StartSeccompSandbox();
155 return true;
156 }
157 #endif
158 }
159 return false;
160 }
161
162 // For seccomp-bpf, we will use the seccomp-bpf policy class.
163 // TODO(jln): implement this.
164 bool LinuxSandbox::StartSeccompBpf(const std::string& process_type) {
165 CHECK(pre_initialized_);
166 NOTREACHED();
167 return false;
168 }
169
170 // Our "policy" on whether or not to enable seccomp-legacy. Only renderers are
171 // supported.
172 bool LinuxSandbox::ShouldEnableSeccompLegacy(
173 const std::string& process_type) {
174 CHECK(pre_initialized_);
175 if (IsSeccompLegacyDesired() &&
176 seccomp_legacy_supported_ &&
177 process_type == switches::kRendererProcess) {
178 return true;
179 } else {
180 return false;
181 }
182 }
183
184 } // namespace content
185
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698