OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/bpf_dsl/bpf_dsl.h" | 5 #include "sandbox/linux/bpf_dsl/bpf_dsl.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <netinet/in.h> | 8 #include <netinet/in.h> |
9 #include <sys/socket.h> | 9 #include <sys/socket.h> |
10 #include <sys/utsname.h> | 10 #include <sys/utsname.h> |
11 | 11 |
| 12 #include "base/files/scoped_file.h" |
12 #include "base/macros.h" | 13 #include "base/macros.h" |
13 #include "build/build_config.h" | 14 #include "build/build_config.h" |
14 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" | 15 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" |
15 #include "sandbox/linux/seccomp-bpf/errorcode.h" | 16 #include "sandbox/linux/seccomp-bpf/errorcode.h" |
16 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" | 17 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" |
17 #include "sandbox/linux/seccomp-bpf/syscall.h" | 18 #include "sandbox/linux/seccomp-bpf/syscall.h" |
18 | 19 |
| 20 #define CASES SANDBOX_BPF_DSL_CASES |
| 21 |
19 // Helper macro to assert that invoking system call |sys| directly via | 22 // Helper macro to assert that invoking system call |sys| directly via |
20 // Syscall::Call with arguments |...| returns |res|. | 23 // Syscall::Call with arguments |...| returns |res|. |
21 // Errors can be asserted by specifying a value like "-EINVAL". | 24 // Errors can be asserted by specifying a value like "-EINVAL". |
22 #define ASSERT_SYSCALL_RESULT(res, sys, ...) \ | 25 #define ASSERT_SYSCALL_RESULT(res, sys, ...) \ |
23 BPF_ASSERT_EQ(res, Stubs::sys(__VA_ARGS__)) | 26 BPF_ASSERT_EQ(res, Stubs::sys(__VA_ARGS__)) |
24 | 27 |
25 namespace sandbox { | 28 namespace sandbox { |
26 namespace bpf_dsl { | 29 namespace bpf_dsl { |
27 namespace { | 30 namespace { |
28 | 31 |
29 // Type safe stubs for tested system calls. | 32 // Type safe stubs for tested system calls. |
30 class Stubs { | 33 class Stubs { |
31 public: | 34 public: |
32 static int getpgid(pid_t pid) { return Syscall::Call(__NR_getpgid, pid); } | 35 static int getpgid(pid_t pid) { return Syscall::Call(__NR_getpgid, pid); } |
33 static int setuid(uid_t uid) { return Syscall::Call(__NR_setuid, uid); } | 36 static int setuid(uid_t uid) { return Syscall::Call(__NR_setuid, uid); } |
34 static int setgid(gid_t gid) { return Syscall::Call(__NR_setgid, gid); } | 37 static int setgid(gid_t gid) { return Syscall::Call(__NR_setgid, gid); } |
35 static int setpgid(pid_t pid, pid_t pgid) { | 38 static int setpgid(pid_t pid, pid_t pgid) { |
36 return Syscall::Call(__NR_setpgid, pid, pgid); | 39 return Syscall::Call(__NR_setpgid, pid, pgid); |
37 } | 40 } |
38 | 41 |
| 42 static int fcntl(int fd, int cmd, unsigned long arg = 0) { |
| 43 return Syscall::Call(__NR_fcntl, fd, cmd, arg); |
| 44 } |
| 45 |
39 static int uname(struct utsname* buf) { | 46 static int uname(struct utsname* buf) { |
40 return Syscall::Call(__NR_uname, buf); | 47 return Syscall::Call(__NR_uname, buf); |
41 } | 48 } |
42 | 49 |
43 static int setresuid(uid_t ruid, uid_t euid, uid_t suid) { | 50 static int setresuid(uid_t ruid, uid_t euid, uid_t suid) { |
44 return Syscall::Call(__NR_setresuid, ruid, euid, suid); | 51 return Syscall::Call(__NR_setresuid, ruid, euid, suid); |
45 } | 52 } |
46 | 53 |
47 #if !defined(ARCH_CPU_X86) | 54 #if !defined(ARCH_CPU_X86) |
48 static int socketpair(int domain, int type, int protocol, int sv[2]) { | 55 static int socketpair(int domain, int type, int protocol, int sv[2]) { |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 ASSERT_SYSCALL_RESULT(-EINVAL, setuid, 0x0001); | 275 ASSERT_SYSCALL_RESULT(-EINVAL, setuid, 0x0001); |
269 ASSERT_SYSCALL_RESULT(-EINVAL, setuid, 0x0002); | 276 ASSERT_SYSCALL_RESULT(-EINVAL, setuid, 0x0002); |
270 | 277 |
271 ASSERT_SYSCALL_RESULT(-EEXIST, setuid, 0x0011); | 278 ASSERT_SYSCALL_RESULT(-EEXIST, setuid, 0x0011); |
272 ASSERT_SYSCALL_RESULT(-EEXIST, setuid, 0x0022); | 279 ASSERT_SYSCALL_RESULT(-EEXIST, setuid, 0x0022); |
273 | 280 |
274 ASSERT_SYSCALL_RESULT(-EACCES, setuid, 0x0111); | 281 ASSERT_SYSCALL_RESULT(-EACCES, setuid, 0x0111); |
275 ASSERT_SYSCALL_RESULT(-EACCES, setuid, 0x0222); | 282 ASSERT_SYSCALL_RESULT(-EACCES, setuid, 0x0222); |
276 } | 283 } |
277 | 284 |
| 285 class SwitchPolicy : public SandboxBPFDSLPolicy { |
| 286 public: |
| 287 SwitchPolicy() {} |
| 288 virtual ~SwitchPolicy() {} |
| 289 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { |
| 290 if (sysno == __NR_fcntl) { |
| 291 const Arg<int> cmd(1); |
| 292 const Arg<unsigned long> long_arg(2); |
| 293 return Switch(cmd) |
| 294 .CASES((F_GETFL, F_GETFD), Error(ENOENT)) |
| 295 .Case(F_SETFD, If(long_arg == O_CLOEXEC, Allow()).Else(Error(EINVAL))) |
| 296 .Case(F_SETFL, Error(EPERM)) |
| 297 .Default(Error(EACCES)); |
| 298 } |
| 299 return Allow(); |
| 300 } |
| 301 |
| 302 private: |
| 303 DISALLOW_COPY_AND_ASSIGN(SwitchPolicy); |
| 304 }; |
| 305 |
| 306 BPF_TEST_C(BPFDSL, SwitchTest, SwitchPolicy) { |
| 307 base::ScopedFD sock_fd(socket(AF_UNIX, SOCK_STREAM, 0)); |
| 308 BPF_ASSERT(sock_fd.is_valid()); |
| 309 |
| 310 ASSERT_SYSCALL_RESULT(-ENOENT, fcntl, sock_fd.get(), F_GETFD); |
| 311 ASSERT_SYSCALL_RESULT(-ENOENT, fcntl, sock_fd.get(), F_GETFL); |
| 312 |
| 313 ASSERT_SYSCALL_RESULT(0, fcntl, sock_fd.get(), F_SETFD, O_CLOEXEC); |
| 314 ASSERT_SYSCALL_RESULT(-EINVAL, fcntl, sock_fd.get(), F_SETFD, 0); |
| 315 |
| 316 ASSERT_SYSCALL_RESULT(-EPERM, fcntl, sock_fd.get(), F_SETFL, O_RDONLY); |
| 317 |
| 318 ASSERT_SYSCALL_RESULT(-EACCES, fcntl, sock_fd.get(), F_DUPFD, 0); |
| 319 } |
| 320 |
278 } // namespace | 321 } // namespace |
279 } // namespace bpf_dsl | 322 } // namespace bpf_dsl |
280 } // namespace sandbox | 323 } // namespace sandbox |
OLD | NEW |