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

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

Issue 1040193004: Add utility functions for forking new PID namespaces. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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/syscall.h> 10 #include <sys/syscall.h>
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 // CHECK() that an attempt to move to a new user namespace raised an expected 103 // CHECK() that an attempt to move to a new user namespace raised an expected
104 // errno. 104 // errno.
105 void CheckCloneNewUserErrno(int error) { 105 void CheckCloneNewUserErrno(int error) {
106 // EPERM can happen if already in a chroot. EUSERS if too many nested 106 // EPERM can happen if already in a chroot. EUSERS if too many nested
107 // namespaces are used. EINVAL for kernels that don't support the feature. 107 // namespaces are used. EINVAL for kernels that don't support the feature.
108 // Valgrind will ENOSYS unshare(). 108 // Valgrind will ENOSYS unshare().
109 PCHECK(error == EPERM || error == EUSERS || error == EINVAL || 109 PCHECK(error == EPERM || error == EUSERS || error == EINVAL ||
110 error == ENOSYS); 110 error == ENOSYS);
111 } 111 }
112 112
113 // Converts a LinuxCapability to the corresponding Linux CAP_XXX value. 113 // Converts a Capability to the corresponding Linux CAP_XXX value.
114 int LinuxCapabilityToKernelValue(LinuxCapability cap) { 114 int CapabilityToKernelValue(Credentials::Capability cap) {
115 switch (cap) { 115 switch (cap) {
116 case LinuxCapability::kCapSysChroot: 116 case Credentials::Capability::SYS_CHROOT:
117 return CAP_SYS_CHROOT; 117 return CAP_SYS_CHROOT;
118 case LinuxCapability::kCapSysAdmin: 118 case Credentials::Capability::SYS_ADMIN:
119 return CAP_SYS_ADMIN; 119 return CAP_SYS_ADMIN;
120 } 120 }
121 121
122 LOG(FATAL) << "Invalid LinuxCapability: " << static_cast<int>(cap); 122 LOG(FATAL) << "Invalid Capability: " << static_cast<int>(cap);
123 return 0; 123 return 0;
124 } 124 }
125 125
126 } // namespace. 126 } // namespace.
127 127
128 // static
128 bool Credentials::DropAllCapabilities(int proc_fd) { 129 bool Credentials::DropAllCapabilities(int proc_fd) {
129 if (!SetCapabilities(proc_fd, std::vector<LinuxCapability>())) { 130 if (!SetCapabilities(proc_fd, std::vector<Capability>())) {
130 return false; 131 return false;
131 } 132 }
132 133
133 CHECK(!HasAnyCapability()); 134 CHECK(!HasAnyCapability());
134 return true; 135 return true;
135 } 136 }
136 137
138 // static
137 bool Credentials::DropAllCapabilities() { 139 bool Credentials::DropAllCapabilities() {
138 base::ScopedFD proc_fd(ProcUtil::OpenProc()); 140 base::ScopedFD proc_fd(ProcUtil::OpenProc());
139 return Credentials::DropAllCapabilities(proc_fd.get()); 141 return Credentials::DropAllCapabilities(proc_fd.get());
140 } 142 }
141 143
142 // static 144 // static
143 bool Credentials::SetCapabilities(int proc_fd, 145 bool Credentials::DropAllCapabilitiesOnCurrentThread() {
144 const std::vector<LinuxCapability>& caps) { 146 return SetCapabilitiesOnCurrentThread(std::vector<Capability>());
145 DCHECK_LE(0, proc_fd); 147 }
146 148
147 #if !defined(THREAD_SANITIZER) 149 // static
148 // With TSAN, accept to break the security model as it is a testing 150 bool Credentials::SetCapabilitiesOnCurrentThread(
149 // configuration. 151 const std::vector<Capability>& caps) {
150 CHECK(ThreadHelpers::IsSingleThreaded(proc_fd));
151 #endif
152
153 struct cap_hdr hdr = {}; 152 struct cap_hdr hdr = {};
154 hdr.version = _LINUX_CAPABILITY_VERSION_3; 153 hdr.version = _LINUX_CAPABILITY_VERSION_3;
155 struct cap_data data[_LINUX_CAPABILITY_U32S_3] = {{}}; 154 struct cap_data data[_LINUX_CAPABILITY_U32S_3] = {{}};
156 155
157 // Initially, cap has no capability flags set. Enable the effective and 156 // Initially, cap has no capability flags set. Enable the effective and
158 // permitted flags only for the requested capabilities. 157 // permitted flags only for the requested capabilities.
159 for (const LinuxCapability cap : caps) { 158 for (const Capability cap : caps) {
160 const int cap_num = LinuxCapabilityToKernelValue(cap); 159 const int cap_num = CapabilityToKernelValue(cap);
161 const size_t index = CAP_TO_INDEX(cap_num); 160 const size_t index = CAP_TO_INDEX(cap_num);
162 const uint32_t mask = CAP_TO_MASK(cap_num); 161 const uint32_t mask = CAP_TO_MASK(cap_num);
163 data[index].effective |= mask; 162 data[index].effective |= mask;
164 data[index].permitted |= mask; 163 data[index].permitted |= mask;
165 } 164 }
166 165
167 return sys_capset(&hdr, data) == 0; 166 return sys_capset(&hdr, data) == 0;
168 } 167 }
169 168
169 // static
170 bool Credentials::SetCapabilities(int proc_fd,
171 const std::vector<Capability>& caps) {
172 DCHECK_LE(0, proc_fd);
173
174 #if !defined(THREAD_SANITIZER)
175 // With TSAN, accept to break the security model as it is a testing
176 // configuration.
177 CHECK(ThreadHelpers::IsSingleThreaded(proc_fd));
178 #endif
179
180 return SetCapabilitiesOnCurrentThread(caps);
181 }
182
170 bool Credentials::HasAnyCapability() { 183 bool Credentials::HasAnyCapability() {
171 struct cap_hdr hdr = {}; 184 struct cap_hdr hdr = {};
172 hdr.version = _LINUX_CAPABILITY_VERSION_3; 185 hdr.version = _LINUX_CAPABILITY_VERSION_3;
173 struct cap_data data[_LINUX_CAPABILITY_U32S_3] = {{}}; 186 struct cap_data data[_LINUX_CAPABILITY_U32S_3] = {{}};
174 187
175 PCHECK(sys_capget(&hdr, data) == 0); 188 PCHECK(sys_capget(&hdr, data) == 0);
176 189
177 for (size_t i = 0; i < arraysize(data); ++i) { 190 for (size_t i = 0; i < arraysize(data); ++i) {
178 if (data[i].effective || data[i].permitted || data[i].inheritable) { 191 if (data[i].effective || data[i].permitted || data[i].inheritable) {
179 return true; 192 return true;
180 } 193 }
181 } 194 }
182 195
183 return false; 196 return false;
184 } 197 }
185 198
186 bool Credentials::HasCapability(LinuxCapability cap) { 199 bool Credentials::HasCapability(Capability cap) {
187 struct cap_hdr hdr = {}; 200 struct cap_hdr hdr = {};
188 hdr.version = _LINUX_CAPABILITY_VERSION_3; 201 hdr.version = _LINUX_CAPABILITY_VERSION_3;
189 struct cap_data data[_LINUX_CAPABILITY_U32S_3] = {{}}; 202 struct cap_data data[_LINUX_CAPABILITY_U32S_3] = {{}};
190 203
191 PCHECK(sys_capget(&hdr, data) == 0); 204 PCHECK(sys_capget(&hdr, data) == 0);
192 205
193 const int cap_num = LinuxCapabilityToKernelValue(cap); 206 const int cap_num = CapabilityToKernelValue(cap);
194 const size_t index = CAP_TO_INDEX(cap_num); 207 const size_t index = CAP_TO_INDEX(cap_num);
195 const uint32_t mask = CAP_TO_MASK(cap_num); 208 const uint32_t mask = CAP_TO_MASK(cap_num);
196 209
197 return (data[index].effective | data[index].permitted | 210 return (data[index].effective | data[index].permitted |
198 data[index].inheritable) & 211 data[index].inheritable) &
199 mask; 212 mask;
200 } 213 }
201 214
202 // static 215 // static
203 bool Credentials::CanCreateProcessInNewUserNS() { 216 bool Credentials::CanCreateProcessInNewUserNS() {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 CHECK_LE(0, proc_fd); 288 CHECK_LE(0, proc_fd);
276 289
277 CHECK(ChrootToSafeEmptyDir()); 290 CHECK(ChrootToSafeEmptyDir());
278 CHECK(!base::DirectoryExists(base::FilePath("/proc"))); 291 CHECK(!base::DirectoryExists(base::FilePath("/proc")));
279 CHECK(!ProcUtil::HasOpenDirectory(proc_fd)); 292 CHECK(!ProcUtil::HasOpenDirectory(proc_fd));
280 // We never let this function fail. 293 // We never let this function fail.
281 return true; 294 return true;
282 } 295 }
283 296
284 } // namespace sandbox. 297 } // 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