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/seccomp-bpf-helpers/baseline_policy.h" 6 7 #include <errno.h> 8 #include <fcntl.h> 9 #include <netinet/in.h> 10 #include <sched.h> 11 #include <signal.h> 12 #include <stddef.h> 13 #include <string.h> 14 #include <sys/prctl.h> 15 #include <sys/resource.h> 16 #include <sys/socket.h> 17 #include <sys/stat.h> 18 #include <sys/syscall.h> 19 #include <sys/time.h> 20 #include <sys/types.h> 21 #include <sys/wait.h> 22 #include <time.h> 23 #include <unistd.h> 24 25 #include "base/files/scoped_file.h" 26 #include "base/macros.h" 27 #include "base/posix/eintr_wrapper.h" 28 #include "base/threading/thread.h" 29 #include "build/build_config.h" 30 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" 31 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" 32 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" 33 #include "sandbox/linux/seccomp-bpf/syscall.h" 34 #include "sandbox/linux/services/syscall_wrappers.h" 35 #include "sandbox/linux/services/thread_helpers.h" 36 #include "sandbox/linux/system_headers/linux_futex.h" 37 #include "sandbox/linux/system_headers/linux_syscalls.h" 38 #include "sandbox/linux/tests/test_utils.h" 39 #include "sandbox/linux/tests/unit_tests.h" 40 41 #if !defined(SO_PEEK_OFF) 42 #define SO_PEEK_OFF 42 43 #endif 44 45 namespace sandbox { 46 47 namespace { 48 49 // This also tests that read(), write() and fstat() are allowed. 50 void TestPipeOrSocketPair(base::ScopedFD read_end, base::ScopedFD write_end) { 51 BPF_ASSERT_LE(0, read_end.get()); 52 BPF_ASSERT_LE(0, write_end.get()); 53 struct stat stat_buf; 54 int sys_ret = fstat(read_end.get(), &stat_buf); 55 BPF_ASSERT_EQ(0, sys_ret); 56 BPF_ASSERT(S_ISFIFO(stat_buf.st_mode) || S_ISSOCK(stat_buf.st_mode)); 57 58 const ssize_t kTestTransferSize = 4; 59 static const char kTestString[kTestTransferSize] = {'T', 'E', 'S', 'T'}; 60 ssize_t transfered = 0; 61 62 transfered = 63 HANDLE_EINTR(write(write_end.get(), kTestString, kTestTransferSize)); 64 BPF_ASSERT_EQ(kTestTransferSize, transfered); 65 char read_buf[kTestTransferSize + 1] = {0}; 66 transfered = HANDLE_EINTR(read(read_end.get(), read_buf, sizeof(read_buf))); 67 BPF_ASSERT_EQ(kTestTransferSize, transfered); 68 BPF_ASSERT_EQ(0, memcmp(kTestString, read_buf, kTestTransferSize)); 69 } 70 71 // Test that a few easy-to-test system calls are allowed. 72 BPF_TEST_C(BaselinePolicy, BaselinePolicyBasicAllowed, BaselinePolicy) { 73 BPF_ASSERT_EQ(0, sched_yield()); 74 75 int pipefd[2]; 76 int sys_ret = pipe(pipefd); 77 BPF_ASSERT_EQ(0, sys_ret); 78 TestPipeOrSocketPair(base::ScopedFD(pipefd[0]), base::ScopedFD(pipefd[1])); 79 80 BPF_ASSERT_LE(1, getpid()); 81 BPF_ASSERT_LE(0, getuid()); 82 } 83 84 BPF_TEST_C(BaselinePolicy, FchmodErrno, BaselinePolicy) { 85 int ret = fchmod(-1, 07777); 86 BPF_ASSERT_EQ(-1, ret); 87 // Without the sandbox, this would EBADF instead. 88 BPF_ASSERT_EQ(EPERM, errno); 89 } 90 91 BPF_TEST_C(BaselinePolicy, ForkErrno, BaselinePolicy) { 92 errno = 0; 93 pid_t pid = fork(); 94 const int fork_errno = errno; 95 TestUtils::HandlePostForkReturn(pid); 96 97 BPF_ASSERT_EQ(-1, pid); 98 BPF_ASSERT_EQ(EPERM, fork_errno); 99 } 100 101 pid_t ForkX86Glibc() { 102 static pid_t ptid; 103 return sys_clone(CLONE_PARENT_SETTID | SIGCHLD, nullptr, &ptid, nullptr, 104 nullptr); 105 } 106 107 BPF_TEST_C(BaselinePolicy, ForkX86Eperm, BaselinePolicy) { 108 errno = 0; 109 pid_t pid = ForkX86Glibc(); 110 const int fork_errno = errno; 111 TestUtils::HandlePostForkReturn(pid); 112 113 BPF_ASSERT_EQ(-1, pid); 114 BPF_ASSERT_EQ(EPERM, fork_errno); 115 } 116 117 pid_t ForkARMGlibc() { 118 static pid_t ctid; 119 return sys_clone(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, nullptr, 120 nullptr, &ctid, nullptr); 121 } 122 123 BPF_TEST_C(BaselinePolicy, ForkArmEperm, BaselinePolicy) { 124 errno = 0; 125 pid_t pid = ForkARMGlibc(); 126 const int fork_errno = errno; 127 TestUtils::HandlePostForkReturn(pid); 128 129 BPF_ASSERT_EQ(-1, pid); 130 BPF_ASSERT_EQ(EPERM, fork_errno); 131 } 132 133 BPF_TEST_C(BaselinePolicy, CreateThread, BaselinePolicy) { 134 base::Thread thread("sandbox_tests"); 135 BPF_ASSERT(thread.Start()); 136 } 137 138 BPF_DEATH_TEST_C(BaselinePolicy, 139 DisallowedCloneFlagCrashes, 140 DEATH_SEGV_MESSAGE(GetCloneErrorMessageContentForTests()), 141 BaselinePolicy) { 142 pid_t pid = sys_clone(CLONE_THREAD | SIGCHLD); 143 TestUtils::HandlePostForkReturn(pid); 144 } 145 146 BPF_DEATH_TEST_C(BaselinePolicy, 147 DisallowedKillCrashes, 148 DEATH_SEGV_MESSAGE(GetKillErrorMessageContentForTests()), 149 BaselinePolicy) { 150 BPF_ASSERT_NE(1, getpid()); 151 kill(1, 0); 152 _exit(0); 153 } 154 155 BPF_TEST_C(BaselinePolicy, CanKillSelf, BaselinePolicy) { 156 int sys_ret = kill(getpid(), 0); 157 BPF_ASSERT_EQ(0, sys_ret); 158 } 159 160 BPF_TEST_C(BaselinePolicy, Socketpair, BaselinePolicy) { 161 int sv[2]; 162 int sys_ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sv); 163 BPF_ASSERT_EQ(0, sys_ret); 164 TestPipeOrSocketPair(base::ScopedFD(sv[0]), base::ScopedFD(sv[1])); 165 166 sys_ret = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sv); 167 BPF_ASSERT_EQ(0, sys_ret); 168 TestPipeOrSocketPair(base::ScopedFD(sv[0]), base::ScopedFD(sv[1])); 169 } 170 171 // Not all architectures can restrict the domain for socketpair(). 172 #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) 173 BPF_DEATH_TEST_C(BaselinePolicy, 174 SocketpairWrongDomain, 175 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()), 176 BaselinePolicy) { 177 int sv[2]; 178 ignore_result(socketpair(AF_INET, SOCK_STREAM, 0, sv)); 179 _exit(1); 180 } 181 #endif // defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) 182 183 BPF_TEST_C(BaselinePolicy, EPERM_open, BaselinePolicy) { 184 errno = 0; 185 int sys_ret = open("/proc/cpuinfo", O_RDONLY); 186 BPF_ASSERT_EQ(-1, sys_ret); 187 BPF_ASSERT_EQ(EPERM, errno); 188 } 189 190 BPF_TEST_C(BaselinePolicy, EPERM_access, BaselinePolicy) { 191 errno = 0; 192 int sys_ret = access("/proc/cpuinfo", R_OK); 193 BPF_ASSERT_EQ(-1, sys_ret); 194 BPF_ASSERT_EQ(EPERM, errno); 195 } 196 197 BPF_TEST_C(BaselinePolicy, EPERM_getcwd, BaselinePolicy) { 198 errno = 0; 199 char buf[1024]; 200 char* cwd = getcwd(buf, sizeof(buf)); 201 BPF_ASSERT_EQ(NULL, cwd); 202 BPF_ASSERT_EQ(EPERM, errno); 203 } 204 205 BPF_DEATH_TEST_C(BaselinePolicy, 206 SIGSYS_InvalidSyscall, 207 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()), 208 BaselinePolicy) { 209 Syscall::InvalidCall(); 210 } 211 212 // A failing test using this macro could be problematic since we perform 213 // system calls by passing "0" as every argument. 214 // The kernel could SIGSEGV the process or the system call itself could reboot 215 // the machine. Some thoughts have been given when hand-picking the system 216 // calls below to limit any potential side effects outside of the current 217 // process. 218 #define TEST_BASELINE_SIGSYS(sysno) \ 219 BPF_DEATH_TEST_C(BaselinePolicy, \ 220 SIGSYS_##sysno, \ 221 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()), \ 222 BaselinePolicy) { \ 223 syscall(sysno, 0, 0, 0, 0, 0, 0); \ 224 _exit(1); \ 225 } 226 227 TEST_BASELINE_SIGSYS(__NR_acct); 228 TEST_BASELINE_SIGSYS(__NR_chroot); 229 TEST_BASELINE_SIGSYS(__NR_fanotify_init); 230 TEST_BASELINE_SIGSYS(__NR_fgetxattr); 231 TEST_BASELINE_SIGSYS(__NR_getcpu); 232 TEST_BASELINE_SIGSYS(__NR_getitimer); 233 TEST_BASELINE_SIGSYS(__NR_init_module); 234 TEST_BASELINE_SIGSYS(__NR_io_cancel); 235 TEST_BASELINE_SIGSYS(__NR_keyctl); 236 TEST_BASELINE_SIGSYS(__NR_mq_open); 237 TEST_BASELINE_SIGSYS(__NR_ptrace); 238 TEST_BASELINE_SIGSYS(__NR_sched_setaffinity); 239 TEST_BASELINE_SIGSYS(__NR_setpgid); 240 TEST_BASELINE_SIGSYS(__NR_swapon); 241 TEST_BASELINE_SIGSYS(__NR_sysinfo); 242 TEST_BASELINE_SIGSYS(__NR_syslog); 243 TEST_BASELINE_SIGSYS(__NR_timer_create); 244 245 #if !defined(__aarch64__) 246 TEST_BASELINE_SIGSYS(__NR_eventfd); 247 TEST_BASELINE_SIGSYS(__NR_inotify_init); 248 TEST_BASELINE_SIGSYS(__NR_vserver); 249 #endif 250 251 BPF_DEATH_TEST_C(BaselinePolicy, 252 FutexWithRequeuePriorityInheritence, 253 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()), 254 BaselinePolicy) { 255 syscall(__NR_futex, NULL, FUTEX_CMP_REQUEUE_PI, 0, NULL, NULL, 0); 256 _exit(1); 257 } 258 259 BPF_DEATH_TEST_C(BaselinePolicy, 260 FutexWithRequeuePriorityInheritencePrivate, 261 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()), 262 BaselinePolicy) { 263 syscall(__NR_futex, NULL, FUTEX_CMP_REQUEUE_PI_PRIVATE, 0, NULL, NULL, 0); 264 _exit(1); 265 } 266 267 BPF_DEATH_TEST_C(BaselinePolicy, 268 FutexWithUnlockPIPrivate, 269 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()), 270 BaselinePolicy) { 271 syscall(__NR_futex, NULL, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); 272 _exit(1); 273 } 274 275 BPF_TEST_C(BaselinePolicy, PrctlDumpable, BaselinePolicy) { 276 const int is_dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0); 277 BPF_ASSERT(is_dumpable == 1 || is_dumpable == 0); 278 const int prctl_ret = prctl(PR_SET_DUMPABLE, is_dumpable, 0, 0, 0, 0); 279 BPF_ASSERT_EQ(0, prctl_ret); 280 } 281 282 // Workaround incomplete Android headers. 283 #if !defined(PR_CAPBSET_READ) 284 #define PR_CAPBSET_READ 23 285 #endif 286 287 BPF_DEATH_TEST_C(BaselinePolicy, 288 PrctlSigsys, 289 DEATH_SEGV_MESSAGE(GetPrctlErrorMessageContentForTests()), 290 BaselinePolicy) { 291 prctl(PR_CAPBSET_READ, 0, 0, 0, 0); 292 _exit(1); 293 } 294 295 BPF_TEST_C(BaselinePolicy, GetOrSetPriority, BaselinePolicy) { 296 errno = 0; 297 const int original_prio = getpriority(PRIO_PROCESS, 0); 298 // Check errno instead of the return value since this system call can return 299 // -1 as a valid value. 300 BPF_ASSERT_EQ(0, errno); 301 302 errno = 0; 303 int rc = getpriority(PRIO_PROCESS, getpid()); 304 BPF_ASSERT_EQ(0, errno); 305 306 rc = getpriority(PRIO_PROCESS, getpid() + 1); 307 BPF_ASSERT_EQ(-1, rc); 308 BPF_ASSERT_EQ(EPERM, errno); 309 310 rc = setpriority(PRIO_PROCESS, 0, original_prio); 311 BPF_ASSERT_EQ(0, rc); 312 313 rc = setpriority(PRIO_PROCESS, getpid(), original_prio); 314 BPF_ASSERT_EQ(0, rc); 315 316 errno = 0; 317 rc = setpriority(PRIO_PROCESS, getpid() + 1, original_prio); 318 BPF_ASSERT_EQ(-1, rc); 319 BPF_ASSERT_EQ(EPERM, errno); 320 } 321 322 BPF_DEATH_TEST_C(BaselinePolicy, 323 GetPrioritySigsys, 324 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()), 325 BaselinePolicy) { 326 getpriority(PRIO_USER, 0); 327 _exit(1); 328 } 329 330 BPF_DEATH_TEST_C(BaselinePolicy, 331 ClockGettimeWithDisallowedClockCrashes, 332 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), 333 BaselinePolicy) { 334 struct timespec ts; 335 clock_gettime(CLOCK_MONOTONIC_RAW, &ts); 336 } 337 338 #if !defined(__i386__) 339 BPF_DEATH_TEST_C(BaselinePolicy, 340 GetSockOptWrongLevelSigsys, 341 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), 342 BaselinePolicy) { 343 int fds[2]; 344 PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); 345 int id; 346 socklen_t peek_off_size = sizeof(id); 347 getsockopt(fds[0], IPPROTO_TCP, SO_PEEK_OFF, &id, &peek_off_size); 348 } 349 350 BPF_DEATH_TEST_C(BaselinePolicy, 351 GetSockOptWrongOptionSigsys, 352 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), 353 BaselinePolicy) { 354 int fds[2]; 355 PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); 356 int id; 357 socklen_t peek_off_size = sizeof(id); 358 getsockopt(fds[0], SOL_SOCKET, SO_DEBUG, &id, &peek_off_size); 359 } 360 361 BPF_DEATH_TEST_C(BaselinePolicy, 362 SetSockOptWrongLevelSigsys, 363 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), 364 BaselinePolicy) { 365 int fds[2]; 366 PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); 367 int id; 368 setsockopt(fds[0], IPPROTO_TCP, SO_PEEK_OFF, &id, sizeof(id)); 369 } 370 371 372 BPF_DEATH_TEST_C(BaselinePolicy, 373 SetSockOptWrongOptionSigsys, 374 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), 375 BaselinePolicy) { 376 int fds[2]; 377 PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); 378 int id; 379 setsockopt(fds[0], SOL_SOCKET, SO_DEBUG, &id, sizeof(id)); 380 } 381 #endif 382 383 } // namespace 384 385 } // namespace sandbox 386