OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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 "sandbox/linux/services/yama.h" | |
6 | |
7 #include <fcntl.h> | |
8 #include <sys/prctl.h> | |
9 #include <sys/stat.h> | |
10 #include <sys/types.h> | |
11 #include <unistd.h> | |
12 | |
13 #include "base/basictypes.h" | |
14 #include "base/file_util.h" | |
15 #include "base/logging.h" | |
16 #include "base/posix/eintr_wrapper.h" | |
17 | |
18 #if !defined(PR_SET_PTRACER_ANY) | |
19 #define PR_SET_PTRACER_ANY ((unsigned long)-1) | |
20 #endif | |
21 | |
22 #if !defined(PR_SET_PTRACER) | |
23 #define PR_SET_PTRACER 0x59616d61 | |
24 #endif | |
25 | |
26 namespace sandbox { | |
27 | |
28 namespace { | |
29 | |
30 // Enable or disable the Yama ptracers restrictions. | |
31 // Return false if Yama is not present on this kernel. | |
32 bool SetYamaPtracersRestriction(bool enabled) { | |
33 unsigned long set_ptracer_arg; | |
34 if (enabled) { | |
35 set_ptracer_arg = 0; | |
36 } else { | |
37 set_ptracer_arg = PR_SET_PTRACER_ANY; | |
38 } | |
39 | |
40 const int ret = prctl(PR_SET_PTRACER, set_ptracer_arg); | |
41 const int prctl_errno = errno; | |
42 | |
43 if (0 == ret) { | |
44 return true; | |
45 } else { | |
46 // ENOSYS or EINVAL means Yama is not in the current kernel. | |
47 CHECK(ENOSYS == prctl_errno || EINVAL == prctl_errno); | |
48 return false; | |
49 } | |
50 } | |
51 | |
52 bool CanAccessProcFS() { | |
53 static const char kProcfsKernelSysPath[] = "/proc/sys/kernel/"; | |
54 int ret = access(kProcfsKernelSysPath, F_OK); | |
55 if (ret) { | |
56 return false; | |
57 } | |
58 return true; | |
59 } | |
60 | |
61 } // namespace | |
62 | |
63 // static | |
64 bool Yama::RestrictPtracersToAncestors() { | |
65 return SetYamaPtracersRestriction(true /* enabled */); | |
66 } | |
67 | |
68 // static | |
69 bool Yama::DisableYamaRestrictions() { | |
70 return SetYamaPtracersRestriction(false /* enabled */); | |
Jorge Lucangeli Obes
2014/03/06 15:42:09
/* disabled */
jln (very slow on Chromium)
2014/03/06 21:43:46
I meant to document the variable name. I've made i
| |
71 } | |
72 | |
73 // static | |
74 int Yama::GetStatus() { | |
75 if (!CanAccessProcFS()) { | |
76 return 0; | |
77 } | |
78 | |
79 static const char kPtraceScopePath[] = "/proc/sys/kernel/yama/ptrace_scope"; | |
80 | |
81 int yama_scope = open(kPtraceScopePath, O_RDONLY); | |
82 | |
83 if (yama_scope < 0) { | |
84 const int open_errno = errno; | |
85 DCHECK(ENOENT == open_errno); | |
86 // The status is known, yama is not present. | |
87 return STATUS_KNOWN; | |
88 } | |
89 | |
90 file_util::ScopedFDCloser yama_scope_closer(&yama_scope); | |
91 char yama_scope_value = 0; | |
92 ssize_t num_read = read(yama_scope, &yama_scope_value, 1); | |
93 PCHECK(1 == num_read); | |
94 | |
95 switch (yama_scope_value) { | |
96 case '0': | |
97 return STATUS_KNOWN | STATUS_PRESENT; | |
98 case '1': | |
99 return STATUS_KNOWN | STATUS_PRESENT | STATUS_ENFORCING; | |
100 case '2': | |
101 case '3': | |
102 return STATUS_KNOWN | STATUS_PRESENT | STATUS_ENFORCING | | |
103 STATUS_STRICT_ENFORCING; | |
104 default: | |
105 NOTREACHED(); | |
106 return 0; | |
107 } | |
108 } | |
109 | |
110 // static | |
111 bool Yama::IsPresent() { return GetStatus() & STATUS_PRESENT; } | |
112 | |
113 // static | |
114 bool Yama::IsEnforcing() { return GetStatus() & STATUS_ENFORCING; } | |
115 | |
116 } // namespace sandbox | |
OLD | NEW |