Chromium Code Reviews| OLD | NEW |
|---|---|
| 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> |
| 11 #include <sys/types.h> | 11 #include <sys/types.h> |
| 12 #include <sys/wait.h> | 12 #include <sys/wait.h> |
| 13 #include <unistd.h> | 13 #include <unistd.h> |
| 14 | 14 |
| 15 #include "base/basictypes.h" | 15 #include "base/basictypes.h" |
| 16 #include "base/bind.h" | 16 #include "base/bind.h" |
| 17 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
|
jln (very slow on Chromium)
2015/03/25 23:47:50
#include "build/build_config.h"
rickyz (no longer on Chrome)
2015/03/26 00:09:37
Is this actually needed? I think THREAD_SANITIZER
| |
| 18 #include "base/files/file_util.h" | 18 #include "base/files/file_util.h" |
| 19 #include "base/logging.h" | 19 #include "base/logging.h" |
| 20 #include "base/posix/eintr_wrapper.h" | 20 #include "base/posix/eintr_wrapper.h" |
| 21 #include "base/process/launch.h" | 21 #include "base/process/launch.h" |
| 22 #include "base/template_util.h" | 22 #include "base/template_util.h" |
| 23 #include "base/third_party/valgrind/valgrind.h" | 23 #include "base/third_party/valgrind/valgrind.h" |
| 24 #include "build/build_config.h" | 24 #include "build/build_config.h" |
| 25 #include "sandbox/linux/services/namespace_utils.h" | 25 #include "sandbox/linux/services/namespace_utils.h" |
| 26 #include "sandbox/linux/services/proc_util.h" | 26 #include "sandbox/linux/services/proc_util.h" |
| 27 #include "sandbox/linux/services/syscall_wrappers.h" | 27 #include "sandbox/linux/services/syscall_wrappers.h" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 case LinuxCapability::kCapSysAdmin: | 118 case LinuxCapability::kCapSysAdmin: |
| 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 LinuxCapability: " << 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<LinuxCapability>())) { |
| 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<LinuxCapability>()); |
| 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<LinuxCapability>& 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 LinuxCapability cap : caps) { |
| 160 const int cap_num = LinuxCapabilityToKernelValue(cap); | 159 const int cap_num = LinuxCapabilityToKernelValue(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<LinuxCapability>& 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; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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. |
| OLD | NEW |