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/seccomp-bpf-helpers/syscall_parameters_restrictions.h" | 5 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <fcntl.h> | 9 #include <fcntl.h> |
10 #include <linux/futex.h> | 10 #include <linux/futex.h> |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 return Switch(request).CASES((TCGETS, FIONREAD), Allow()).Default( | 135 return Switch(request).CASES((TCGETS, FIONREAD), Allow()).Default( |
136 CrashSIGSYSIoctl()); | 136 CrashSIGSYSIoctl()); |
137 } | 137 } |
138 | 138 |
139 ResultExpr RestrictMmapFlags() { | 139 ResultExpr RestrictMmapFlags() { |
140 // The flags you see are actually the allowed ones, and the variable is a | 140 // The flags you see are actually the allowed ones, and the variable is a |
141 // "denied" mask because of the negation operator. | 141 // "denied" mask because of the negation operator. |
142 // Significantly, we don't permit MAP_HUGETLB, or the newer flags such as | 142 // Significantly, we don't permit MAP_HUGETLB, or the newer flags such as |
143 // MAP_POPULATE. | 143 // MAP_POPULATE. |
144 // TODO(davidung), remove MAP_DENYWRITE with updated Tegra libraries. | 144 // TODO(davidung), remove MAP_DENYWRITE with updated Tegra libraries. |
145 const uint32_t denied_mask = | 145 const uint64_t kAllowedMask = MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS | |
146 ~(MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK | MAP_NORESERVE | | 146 MAP_STACK | MAP_NORESERVE | MAP_FIXED | |
147 MAP_FIXED | MAP_DENYWRITE); | 147 MAP_DENYWRITE; |
148 const Arg<int> flags(3); | 148 const Arg<int> flags(3); |
149 return If((flags & denied_mask) == 0, Allow()).Else(CrashSIGSYS()); | 149 return If((flags & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS()); |
150 } | 150 } |
151 | 151 |
152 ResultExpr RestrictMprotectFlags() { | 152 ResultExpr RestrictMprotectFlags() { |
153 // The flags you see are actually the allowed ones, and the variable is a | 153 // The flags you see are actually the allowed ones, and the variable is a |
154 // "denied" mask because of the negation operator. | 154 // "denied" mask because of the negation operator. |
155 // Significantly, we don't permit weird undocumented flags such as | 155 // Significantly, we don't permit weird undocumented flags such as |
156 // PROT_GROWSDOWN. | 156 // PROT_GROWSDOWN. |
157 const uint32_t denied_mask = ~(PROT_READ | PROT_WRITE | PROT_EXEC); | 157 const uint64_t kAllowedMask = PROT_READ | PROT_WRITE | PROT_EXEC; |
158 const Arg<int> prot(2); | 158 const Arg<int> prot(2); |
159 return If((prot & denied_mask) == 0, Allow()).Else(CrashSIGSYS()); | 159 return If((prot & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS()); |
160 } | 160 } |
161 | 161 |
162 ResultExpr RestrictFcntlCommands() { | 162 ResultExpr RestrictFcntlCommands() { |
163 // We also restrict the flags in F_SETFL. We don't want to permit flags with | 163 // We also restrict the flags in F_SETFL. We don't want to permit flags with |
164 // a history of trouble such as O_DIRECT. The flags you see are actually the | 164 // a history of trouble such as O_DIRECT. The flags you see are actually the |
165 // allowed ones, and the variable is a "denied" mask because of the negation | 165 // allowed ones, and the variable is a "denied" mask because of the negation |
166 // operator. | 166 // operator. |
167 // Glibc overrides the kernel's O_LARGEFILE value. Account for this. | 167 // Glibc overrides the kernel's O_LARGEFILE value. Account for this. |
168 int kOLargeFileFlag = O_LARGEFILE; | 168 uint64_t kOLargeFileFlag = O_LARGEFILE; |
169 if (IsArchitectureX86_64() || IsArchitectureI386() || IsArchitectureMips()) | 169 if (IsArchitectureX86_64() || IsArchitectureI386() || IsArchitectureMips()) |
170 kOLargeFileFlag = 0100000; | 170 kOLargeFileFlag = 0100000; |
171 | 171 |
172 const Arg<int> cmd(1); | 172 const Arg<int> cmd(1); |
173 const Arg<long> long_arg(2); | 173 const Arg<long> long_arg(2); |
174 | 174 |
175 unsigned long denied_mask = ~(O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC | | 175 const uint64_t kAllowedMask = O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC | |
176 kOLargeFileFlag | O_CLOEXEC | O_NOATIME); | 176 kOLargeFileFlag | O_CLOEXEC | O_NOATIME; |
177 return Switch(cmd) | 177 return Switch(cmd) |
178 .CASES((F_GETFL, | 178 .CASES((F_GETFL, |
179 F_GETFD, | 179 F_GETFD, |
180 F_SETFD, | 180 F_SETFD, |
181 F_SETLK, | 181 F_SETLK, |
182 F_SETLKW, | 182 F_SETLKW, |
183 F_GETLK, | 183 F_GETLK, |
184 F_DUPFD, | 184 F_DUPFD, |
185 F_DUPFD_CLOEXEC), | 185 F_DUPFD_CLOEXEC), |
186 Allow()) | 186 Allow()) |
187 .Case(F_SETFL, | 187 .Case(F_SETFL, |
188 If((long_arg & denied_mask) == 0, Allow()).Else(CrashSIGSYS())) | 188 If((long_arg & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS())) |
189 .Default(CrashSIGSYS()); | 189 .Default(CrashSIGSYS()); |
190 } | 190 } |
191 | 191 |
192 #if defined(__i386__) || defined(__mips__) | 192 #if defined(__i386__) || defined(__mips__) |
193 ResultExpr RestrictSocketcallCommand() { | 193 ResultExpr RestrictSocketcallCommand() { |
194 // Unfortunately, we are unable to restrict the first parameter to | 194 // Unfortunately, we are unable to restrict the first parameter to |
195 // socketpair(2). Whilst initially sounding bad, it's noteworthy that very | 195 // socketpair(2). Whilst initially sounding bad, it's noteworthy that very |
196 // few protocols actually support socketpair(2). The scary call that we're | 196 // few protocols actually support socketpair(2). The scary call that we're |
197 // worried about, socket(2), remains blocked. | 197 // worried about, socket(2), remains blocked. |
198 const Arg<int> call(0); | 198 const Arg<int> call(0); |
(...skipping 20 matching lines...) Expand all Loading... |
219 } | 219 } |
220 case __NR_tkill: | 220 case __NR_tkill: |
221 return CrashSIGSYSKill(); | 221 return CrashSIGSYSKill(); |
222 default: | 222 default: |
223 NOTREACHED(); | 223 NOTREACHED(); |
224 return CrashSIGSYS(); | 224 return CrashSIGSYS(); |
225 } | 225 } |
226 } | 226 } |
227 | 227 |
228 ResultExpr RestrictFutex() { | 228 ResultExpr RestrictFutex() { |
229 const int kAllowedFutexFlags = FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME; | 229 const uint64_t kAllowedFutexFlags = FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME; |
230 const int kOperationMask = ~kAllowedFutexFlags; | |
231 const Arg<int> op(1); | 230 const Arg<int> op(1); |
232 return Switch(op & kOperationMask) | 231 return Switch(op & ~kAllowedFutexFlags) |
233 .CASES((FUTEX_WAIT, | 232 .CASES((FUTEX_WAIT, |
234 FUTEX_WAKE, | 233 FUTEX_WAKE, |
235 FUTEX_REQUEUE, | 234 FUTEX_REQUEUE, |
236 FUTEX_CMP_REQUEUE, | 235 FUTEX_CMP_REQUEUE, |
237 FUTEX_WAKE_OP, | 236 FUTEX_WAKE_OP, |
238 FUTEX_WAIT_BITSET, | 237 FUTEX_WAIT_BITSET, |
239 FUTEX_WAKE_BITSET), | 238 FUTEX_WAKE_BITSET), |
240 Allow()) | 239 Allow()) |
241 .Default(CrashSIGSYSFutex()); | 240 .Default(CrashSIGSYSFutex()); |
242 } | 241 } |
(...skipping 15 matching lines...) Expand all Loading... |
258 clockid == base::TimeTicks::kClockSystemTrace || | 257 clockid == base::TimeTicks::kClockSystemTrace || |
259 #endif | 258 #endif |
260 clockid == CLOCK_MONOTONIC || | 259 clockid == CLOCK_MONOTONIC || |
261 clockid == CLOCK_PROCESS_CPUTIME_ID || | 260 clockid == CLOCK_PROCESS_CPUTIME_ID || |
262 clockid == CLOCK_REALTIME || | 261 clockid == CLOCK_REALTIME || |
263 clockid == CLOCK_THREAD_CPUTIME_ID, | 262 clockid == CLOCK_THREAD_CPUTIME_ID, |
264 Allow()).Else(CrashSIGSYS()); | 263 Allow()).Else(CrashSIGSYS()); |
265 } | 264 } |
266 | 265 |
267 } // namespace sandbox. | 266 } // namespace sandbox. |
OLD | NEW |