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

Side by Side Diff: sandbox/linux/services/credentials.cc

Issue 997463002: Add SetCapabilities for setting capabilities to an exact set. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Respond to comments. Created 5 years, 9 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
« no previous file with comments | « sandbox/linux/services/credentials.h ('k') | sandbox/linux/services/credentials_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sandbox/linux/services/credentials.h" 5 #include "sandbox/linux/services/credentials.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <signal.h> 8 #include <signal.h>
9 #include <stdio.h> 9 #include <stdio.h>
10 #include <sys/capability.h> 10 #include <sys/capability.h>
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 // EPERM can happen if already in a chroot. EUSERS if too many nested 126 // EPERM can happen if already in a chroot. EUSERS if too many nested
127 // namespaces are used. EINVAL for kernels that don't support the feature. 127 // namespaces are used. EINVAL for kernels that don't support the feature.
128 // Valgrind will ENOSYS unshare(). 128 // Valgrind will ENOSYS unshare().
129 PCHECK(error == EPERM || error == EUSERS || error == EINVAL || 129 PCHECK(error == EPERM || error == EUSERS || error == EINVAL ||
130 error == ENOSYS); 130 error == ENOSYS);
131 } 131 }
132 132
133 } // namespace. 133 } // namespace.
134 134
135 bool Credentials::DropAllCapabilities(int proc_fd) { 135 bool Credentials::DropAllCapabilities(int proc_fd) {
136 DCHECK_LE(0, proc_fd); 136 if (!SetCapabilities(proc_fd, std::vector<cap_value_t>())) {
137 #if !defined(THREAD_SANITIZER) 137 return false;
jln (very slow on Chromium) 2015/03/10 22:32:29 n.b. We used to never let this function fail and t
138 // With TSAN, accept to break the security model as it is a testing 138 }
139 // configuration.
140 CHECK(ThreadHelpers::IsSingleThreaded(proc_fd));
141 #endif
142 139
143 ScopedCap cap(cap_init());
144 CHECK(cap);
145 PCHECK(0 == cap_set_proc(cap.get()));
146 CHECK(!HasAnyCapability()); 140 CHECK(!HasAnyCapability());
147 // We never let this function fail.
148 return true; 141 return true;
149 } 142 }
150 143
151 bool Credentials::DropAllCapabilities() { 144 bool Credentials::DropAllCapabilities() {
152 base::ScopedFD proc_fd(ProcUtil::OpenProc()); 145 base::ScopedFD proc_fd(ProcUtil::OpenProc());
153 return Credentials::DropAllCapabilities(proc_fd.get()); 146 return Credentials::DropAllCapabilities(proc_fd.get());
154 } 147 }
155 148
149 // static
150 bool Credentials::SetCapabilities(int proc_fd,
151 const std::vector<cap_value_t>& caps) {
152 DCHECK_LE(0, proc_fd);
153 #if !defined(THREAD_SANITIZER)
154 // With TSAN, accept to break the security model as it is a testing
155 // configuration.
156 CHECK(ThreadHelpers::IsSingleThreaded(proc_fd));
157 #endif
158
159 sandbox::ScopedCap cap(cap_init());
160 PCHECK(cap != nullptr);
161
162 if (!caps.empty()) {
163 // Initially, cap has no capability flags set. Enable CAP_EFFECTIVE and
164 // CAP_PERMITTED only for the requested capabilities.
165 const cap_flag_t flags[] = {CAP_EFFECTIVE, CAP_PERMITTED};
166 for (const cap_flag_t flag : flags) {
167 PCHECK(cap_set_flag(cap.get(), flag, caps.size(), &caps.at(0), CAP_SET) ==
168 0);
169 }
170 }
171
172 return cap_set_proc(cap.get()) == 0;
173 }
174
156 bool Credentials::HasAnyCapability() { 175 bool Credentials::HasAnyCapability() {
157 ScopedCap current_cap(cap_get_proc()); 176 ScopedCap current_cap(cap_get_proc());
158 CHECK(current_cap); 177 CHECK(current_cap);
159 ScopedCap empty_cap(cap_init()); 178 ScopedCap empty_cap(cap_init());
160 CHECK(empty_cap); 179 CHECK(empty_cap);
161 return cap_compare(current_cap.get(), empty_cap.get()) != 0; 180 return cap_compare(current_cap.get(), empty_cap.get()) != 0;
162 } 181 }
163 182
183 bool Credentials::HasCapability(cap_value_t cap) {
184 ScopedCap current_cap(cap_get_proc());
185 PCHECK(current_cap);
186
187 cap_flag_value_t value;
188 const cap_flag_t flags[] = {CAP_EFFECTIVE, CAP_PERMITTED};
189 for (const cap_flag_t flag : flags) {
190 PCHECK(cap_get_flag(current_cap.get(), cap, flag, &value) == 0);
191 if (value == CAP_SET) {
192 return true;
193 }
194 }
195 return false;
196 }
197
164 scoped_ptr<std::string> Credentials::GetCurrentCapString() { 198 scoped_ptr<std::string> Credentials::GetCurrentCapString() {
165 ScopedCap current_cap(cap_get_proc()); 199 ScopedCap current_cap(cap_get_proc());
166 CHECK(current_cap); 200 CHECK(current_cap);
167 ScopedCapText cap_text(cap_to_text(current_cap.get(), NULL)); 201 ScopedCapText cap_text(cap_to_text(current_cap.get(), NULL));
168 CHECK(cap_text); 202 CHECK(cap_text);
169 return scoped_ptr<std::string> (new std::string(cap_text.get())); 203 return scoped_ptr<std::string> (new std::string(cap_text.get()));
170 } 204 }
171 205
172 // static 206 // static
173 bool Credentials::CanCreateProcessInNewUserNS() { 207 bool Credentials::CanCreateProcessInNewUserNS() {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 CHECK_LE(0, proc_fd); 279 CHECK_LE(0, proc_fd);
246 280
247 CHECK(ChrootToSafeEmptyDir()); 281 CHECK(ChrootToSafeEmptyDir());
248 CHECK(!base::DirectoryExists(base::FilePath("/proc"))); 282 CHECK(!base::DirectoryExists(base::FilePath("/proc")));
249 CHECK(!ProcUtil::HasOpenDirectory(proc_fd)); 283 CHECK(!ProcUtil::HasOpenDirectory(proc_fd));
250 // We never let this function fail. 284 // We never let this function fail.
251 return true; 285 return true;
252 } 286 }
253 287
254 } // namespace sandbox. 288 } // namespace sandbox.
OLDNEW
« no previous file with comments | « sandbox/linux/services/credentials.h ('k') | sandbox/linux/services/credentials_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698