1 // Copyright 2015 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.
5 #include "sandbox/linux/services/namespace_utils.h"
15 #include "base/files/file_path.h"
16 #include "base/files/file_util.h"
17 #include "base/files/scoped_file.h"
18 #include "base/logging.h"
19 #include "base/posix/eintr_wrapper.h"
20 #include "base/process/launch.h"
21 #include "base/strings/safe_sprintf.h"
22 #include "base/third_party/valgrind/valgrind.h"
27 bool IsRunningOnValgrind() {
28 return RUNNING_ON_VALGRIND
;
31 const char kProcSelfSetgroups
[] = "/proc/self/setgroups";
35 bool NamespaceUtils::WriteToIdMapFile(const char* map_file
, generic_id_t id
) {
36 // This function needs to be async-signal-safe, as it may be called in between
39 int fd
= HANDLE_EINTR(open(map_file
, O_WRONLY
));
44 const generic_id_t inside_id
= id
;
45 const generic_id_t outside_id
= id
;
49 base::strings::SafeSPrintf(mapping
, "%d %d 1\n", inside_id
, outside_id
);
50 const ssize_t rc
= HANDLE_EINTR(write(fd
, mapping
, len
));
51 RAW_CHECK(IGNORE_EINTR(close(fd
)) == 0);
56 bool NamespaceUtils::KernelSupportsUnprivilegedNamespace(int type
) {
57 // Valgrind will let clone(2) pass-through, but doesn't support unshare(),
58 // so always consider namespaces unsupported there.
59 if (IsRunningOnValgrind()) {
63 // As of Linux 3.8, /proc/self/ns/* files exist for all namespace types. Since
64 // user namespaces were added in 3.8, it is OK to rely on the existence of
66 if (!base::PathExists(base::FilePath("/proc/self/ns/user"))) {
75 path
= "/proc/self/ns/ipc";
78 path
= "/proc/self/ns/net";
81 path
= "/proc/self/ns/mnt";
84 path
= "/proc/self/ns/pid";
87 path
= "/proc/self/ns/uts";
94 return base::PathExists(base::FilePath(path
));
98 bool NamespaceUtils::KernelSupportsDenySetgroups() {
99 return base::PathExists(base::FilePath(kProcSelfSetgroups
));
103 bool NamespaceUtils::DenySetgroups() {
104 // This function needs to be async-signal-safe.
105 int fd
= HANDLE_EINTR(open(kProcSelfSetgroups
, O_WRONLY
));
110 static const char kDeny
[] = "deny";
111 const ssize_t len
= sizeof(kDeny
) - 1;
112 const ssize_t rc
= HANDLE_EINTR(write(fd
, kDeny
, len
));
113 RAW_CHECK(IGNORE_EINTR(close(fd
)) == 0);
117 } // namespace sandbox