1 // Test routines to make sure a variety of system calls are or are not
2 // available in capability mode. The goal is not to see if they work, just
3 // whether or not they return the expected ECAPMODE.
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <sys/stat.h>
7 #include <sys/mount.h>
8 #include <sys/mman.h>
9 #include <sys/wait.h>
10 #include <sys/time.h>
11 #include <sys/resource.h>
12 #include <sys/ptrace.h>
13 #include <dirent.h>
14 #include <netinet/in.h>
15 #include <fcntl.h>
16 #include <sched.h>
17 #include <time.h>
18 #include <unistd.h>
19 #include <pthread.h>
20
21 #include "capsicum.h"
22 #include "syscalls.h"
23 #include "capsicum-test.h"
24
25 // Test fixture that opens (and closes) a bunch of files.
26 class WithFiles : public ::testing::Test {
27 public:
WithFiles()28 WithFiles() :
29 fd_file_(open(TmpFile("cap_capmode"), O_RDWR|O_CREAT, 0644)),
30 fd_close_(open("/dev/null", O_RDWR)),
31 fd_dir_(open(tmpdir.c_str(), O_RDONLY)),
32 fd_socket_(socket(PF_INET, SOCK_DGRAM, 0)),
33 fd_tcp_socket_(socket(PF_INET, SOCK_STREAM, 0)) {
34 EXPECT_OK(fd_file_);
35 EXPECT_OK(fd_close_);
36 EXPECT_OK(fd_dir_);
37 EXPECT_OK(fd_socket_);
38 EXPECT_OK(fd_tcp_socket_);
39 }
~WithFiles()40 ~WithFiles() {
41 if (fd_tcp_socket_ >= 0) close(fd_tcp_socket_);
42 if (fd_socket_ >= 0) close(fd_socket_);
43 if (fd_dir_ >= 0) close(fd_dir_);
44 if (fd_close_ >= 0) close(fd_close_);
45 if (fd_file_ >= 0) close(fd_file_);
46 unlink(TmpFile("cap_capmode"));
47 }
48 protected:
49 int fd_file_;
50 int fd_close_;
51 int fd_dir_;
52 int fd_socket_;
53 int fd_tcp_socket_;
54 };
55
FORK_TEST_F(WithFiles,DisallowedFileSyscalls)56 FORK_TEST_F(WithFiles, DisallowedFileSyscalls) {
57 unsigned int mode = -1;
58 EXPECT_OK(cap_getmode(&mode));
59 EXPECT_EQ(0, (int)mode);
60 EXPECT_OK(cap_enter()); // Enter capability mode.
61 EXPECT_OK(cap_getmode(&mode));
62 EXPECT_EQ(1, (int)mode);
63
64 // System calls that are not permitted in capability mode.
65 EXPECT_CAPMODE(access(TmpFile("cap_capmode_access"), F_OK));
66 EXPECT_CAPMODE(acct(TmpFile("cap_capmode_acct")));
67 EXPECT_CAPMODE(chdir(TmpFile("cap_capmode_chdir")));
68 #ifdef HAVE_CHFLAGS
69 EXPECT_CAPMODE(chflags(TmpFile("cap_capmode_chflags"), UF_NODUMP));
70 #endif
71 EXPECT_CAPMODE(chmod(TmpFile("cap_capmode_chmod"), 0644));
72 EXPECT_CAPMODE(chown(TmpFile("cap_capmode_chown"), -1, -1));
73 EXPECT_CAPMODE(chroot(TmpFile("cap_capmode_chroot")));
74 EXPECT_CAPMODE(creat(TmpFile("cap_capmode_creat"), 0644));
75 EXPECT_CAPMODE(fchdir(fd_dir_));
76 #ifdef HAVE_GETFSSTAT
77 struct statfs statfs;
78 EXPECT_CAPMODE(getfsstat(&statfs, sizeof(statfs), MNT_NOWAIT));
79 #endif
80 EXPECT_CAPMODE(link(TmpFile("foo"), TmpFile("bar")));
81 struct stat sb;
82 EXPECT_CAPMODE(lstat(TmpFile("cap_capmode_lstat"), &sb));
83 EXPECT_CAPMODE(mknod(TmpFile("capmode_mknod"), 0644 | S_IFIFO, 0));
84 EXPECT_CAPMODE(bogus_mount_());
85 EXPECT_CAPMODE(open("/dev/null", O_RDWR));
86 char buf[64];
87 EXPECT_CAPMODE(readlink(TmpFile("cap_capmode_readlink"), buf, sizeof(buf)));
88 #ifdef HAVE_REVOKE
89 EXPECT_CAPMODE(revoke(TmpFile("cap_capmode_revoke")));
90 #endif
91 EXPECT_CAPMODE(stat(TmpFile("cap_capmode_stat"), &sb));
92 EXPECT_CAPMODE(symlink(TmpFile("cap_capmode_symlink_from"), TmpFile("cap_capmode_symlink_to")));
93 EXPECT_CAPMODE(unlink(TmpFile("cap_capmode_unlink")));
94 EXPECT_CAPMODE(umount2("/not_mounted", 0));
95 }
96
FORK_TEST_F(WithFiles,DisallowedSocketSyscalls)97 FORK_TEST_F(WithFiles, DisallowedSocketSyscalls) {
98 EXPECT_OK(cap_enter()); // Enter capability mode.
99
100 // System calls that are not permitted in capability mode.
101 struct sockaddr_in addr;
102 addr.sin_family = AF_INET;
103 addr.sin_port = 0;
104 addr.sin_addr.s_addr = htonl(INADDR_ANY);
105 EXPECT_CAPMODE(bind_(fd_socket_, (sockaddr*)&addr, sizeof(addr)));
106 addr.sin_family = AF_INET;
107 addr.sin_port = 53;
108 addr.sin_addr.s_addr = htonl(0x08080808);
109 EXPECT_CAPMODE(connect_(fd_tcp_socket_, (sockaddr*)&addr, sizeof(addr)));
110 }
111
FORK_TEST_F(WithFiles,AllowedFileSyscalls)112 FORK_TEST_F(WithFiles, AllowedFileSyscalls) {
113 int rc;
114 EXPECT_OK(cap_enter()); // Enter capability mode.
115
116 EXPECT_OK(close(fd_close_));
117 fd_close_ = -1;
118 int fd_dup = dup(fd_file_);
119 EXPECT_OK(fd_dup);
120 EXPECT_OK(dup2(fd_file_, fd_dup));
121 #ifdef HAVE_DUP3
122 EXPECT_OK(dup3(fd_file_, fd_dup, 0));
123 #endif
124 if (fd_dup >= 0) close(fd_dup);
125
126 struct stat sb;
127 EXPECT_OK(fstat(fd_file_, &sb));
128 EXPECT_OK(lseek(fd_file_, 0, SEEK_SET));
129 char ch;
130 EXPECT_OK(read(fd_file_, &ch, sizeof(ch)));
131 EXPECT_OK(write(fd_file_, &ch, sizeof(ch)));
132
133 #ifdef HAVE_CHFLAGS
134 rc = fchflags(fd_file_, UF_NODUMP);
135 if (rc < 0) {
136 EXPECT_NE(ECAPMODE, errno);
137 }
138 #endif
139
140 char buf[1024];
141 rc = getdents_(fd_dir_, (void*)buf, sizeof(buf));
142 EXPECT_OK(rc);
143
144 char data[] = "123";
145 EXPECT_OK(pwrite(fd_file_, data, 1, 0));
146 EXPECT_OK(pread(fd_file_, data, 1, 0));
147
148 struct iovec io;
149 io.iov_base = data;
150 io.iov_len = 2;
151 #if !defined(__i386__) && !defined(__linux__)
152 // TODO(drysdale): reinstate these tests for 32-bit runs when possible
153 // libc bug is fixed.
154 EXPECT_OK(pwritev(fd_file_, &io, 1, 0));
155 EXPECT_OK(preadv(fd_file_, &io, 1, 0));
156 #endif
157 EXPECT_OK(writev(fd_file_, &io, 1));
158 EXPECT_OK(readv(fd_file_, &io, 1));
159
160 #ifdef HAVE_SYNCFS
161 EXPECT_OK(syncfs(fd_file_));
162 #endif
163 #ifdef HAVE_SYNC_FILE_RANGE
164 EXPECT_OK(sync_file_range(fd_file_, 0, 1, 0));
165 #endif
166 #ifdef HAVE_READAHEAD
167 if (!tmpdir_on_tmpfs) { // tmpfs doesn't support readahead(2)
168 EXPECT_OK(readahead(fd_file_, 0, 1));
169 }
170 #endif
171 }
172
FORK_TEST_F(WithFiles,AllowedSocketSyscalls)173 FORK_TEST_F(WithFiles, AllowedSocketSyscalls) {
174 EXPECT_OK(cap_enter()); // Enter capability mode.
175
176 // recvfrom() either returns -1 with EAGAIN, or 0.
177 int rc = recvfrom(fd_socket_, NULL, 0, MSG_DONTWAIT, NULL, NULL);
178 if (rc < 0) {
179 EXPECT_EQ(EAGAIN, errno);
180 }
181 char ch;
182 EXPECT_OK(write(fd_file_, &ch, sizeof(ch)));
183
184 // These calls will fail for lack of e.g. a proper name to send to,
185 // but they are allowed in capability mode, so errno != ECAPMODE.
186 EXPECT_FAIL_NOT_CAPMODE(accept(fd_socket_, NULL, NULL));
187 EXPECT_FAIL_NOT_CAPMODE(getpeername(fd_socket_, NULL, NULL));
188 EXPECT_FAIL_NOT_CAPMODE(getsockname(fd_socket_, NULL, NULL));
189 EXPECT_FAIL_NOT_CAPMODE(recvmsg(fd_socket_, NULL, 0));
190 EXPECT_FAIL_NOT_CAPMODE(sendmsg(fd_socket_, NULL, 0));
191 EXPECT_FAIL_NOT_CAPMODE(sendto(fd_socket_, NULL, 0, 0, NULL, 0));
192 off_t offset = 0;
193 EXPECT_FAIL_NOT_CAPMODE(sendfile_(fd_socket_, fd_file_, &offset, 1));
194
195 // The socket/socketpair syscalls are allowed, but they don't give
196 // anything externally useful (can't call bind/connect on them).
197 int fd_socket2 = socket(PF_INET, SOCK_DGRAM, 0);
198 EXPECT_OK(fd_socket2);
199 if (fd_socket2 >= 0) close(fd_socket2);
200 int fd_pair[2] = {-1, -1};
201 EXPECT_OK(socketpair(AF_UNIX, SOCK_STREAM, 0, fd_pair));
202 if (fd_pair[0] >= 0) close(fd_pair[0]);
203 if (fd_pair[1] >= 0) close(fd_pair[1]);
204 }
205
206 #ifdef HAVE_SEND_RECV_MMSG
FORK_TEST(Capmode,AllowedMmsgSendRecv)207 FORK_TEST(Capmode, AllowedMmsgSendRecv) {
208 int fd_socket = socket(PF_INET, SOCK_DGRAM, 0);
209
210 struct sockaddr_in addr;
211 addr.sin_family = AF_INET;
212 addr.sin_port = htons(0);
213 addr.sin_addr.s_addr = htonl(INADDR_ANY);
214 EXPECT_OK(bind(fd_socket, (sockaddr*)&addr, sizeof(addr)));
215
216 EXPECT_OK(cap_enter()); // Enter capability mode.
217
218 char buffer[256] = {0};
219 struct iovec iov;
220 iov.iov_base = buffer;
221 iov.iov_len = sizeof(buffer);
222 struct mmsghdr mm;
223 memset(&mm, 0, sizeof(mm));
224 mm.msg_hdr.msg_iov = &iov;
225 mm.msg_hdr.msg_iovlen = 1;
226 struct timespec ts;
227 ts.tv_sec = 1;
228 ts.tv_nsec = 100;
229 EXPECT_FAIL_NOT_CAPMODE(recvmmsg(fd_socket, &mm, 1, MSG_DONTWAIT, &ts));
230 EXPECT_FAIL_NOT_CAPMODE(sendmmsg(fd_socket, &mm, 1, 0));
231 close(fd_socket);
232 }
233 #endif
234
FORK_TEST(Capmode,AllowedIdentifierSyscalls)235 FORK_TEST(Capmode, AllowedIdentifierSyscalls) {
236 // Record some identifiers
237 gid_t my_gid = getgid();
238 pid_t my_pid = getpid();
239 pid_t my_ppid = getppid();
240 uid_t my_uid = getuid();
241 pid_t my_sid = getsid(my_pid);
242
243 EXPECT_OK(cap_enter()); // Enter capability mode.
244
245 EXPECT_EQ(my_gid, getegid_());
246 EXPECT_EQ(my_uid, geteuid_());
247 EXPECT_EQ(my_gid, getgid_());
248 EXPECT_EQ(my_pid, getpid());
249 EXPECT_EQ(my_ppid, getppid());
250 EXPECT_EQ(my_uid, getuid_());
251 EXPECT_EQ(my_sid, getsid(my_pid));
252 gid_t grps[128];
253 EXPECT_OK(getgroups_(128, grps));
254 uid_t ruid;
255 uid_t euid;
256 uid_t suid;
257 EXPECT_OK(getresuid(&ruid, &euid, &suid));
258 gid_t rgid;
259 gid_t egid;
260 gid_t sgid;
261 EXPECT_OK(getresgid(&rgid, &egid, &sgid));
262 #ifdef HAVE_GETLOGIN
263 EXPECT_TRUE(getlogin() != NULL);
264 #endif
265
266 // Set various identifiers (to their existing values).
267 EXPECT_OK(setgid(my_gid));
268 #ifdef HAVE_SETFSGID
269 EXPECT_OK(setfsgid(my_gid));
270 #endif
271 EXPECT_OK(setuid(my_uid));
272 #ifdef HAVE_SETFSUID
273 EXPECT_OK(setfsuid(my_uid));
274 #endif
275 EXPECT_OK(setregid(my_gid, my_gid));
276 EXPECT_OK(setresgid(my_gid, my_gid, my_gid));
277 EXPECT_OK(setreuid(my_uid, my_uid));
278 EXPECT_OK(setresuid(my_uid, my_uid, my_uid));
279 EXPECT_OK(setsid());
280 }
281
FORK_TEST(Capmode,AllowedSchedSyscalls)282 FORK_TEST(Capmode, AllowedSchedSyscalls) {
283 EXPECT_OK(cap_enter()); // Enter capability mode.
284 int policy = sched_getscheduler(0);
285 EXPECT_OK(policy);
286 struct sched_param sp;
287 EXPECT_OK(sched_getparam(0, &sp));
288 if (policy >= 0 && (!SCHED_SETSCHEDULER_REQUIRES_ROOT || getuid() == 0)) {
289 EXPECT_OK(sched_setscheduler(0, policy, &sp));
290 }
291 EXPECT_OK(sched_setparam(0, &sp));
292 EXPECT_OK(sched_get_priority_max(policy));
293 EXPECT_OK(sched_get_priority_min(policy));
294 struct timespec ts;
295 EXPECT_OK(sched_rr_get_interval(0, &ts));
296 EXPECT_OK(sched_yield());
297 }
298
299
FORK_TEST(Capmode,AllowedTimerSyscalls)300 FORK_TEST(Capmode, AllowedTimerSyscalls) {
301 EXPECT_OK(cap_enter()); // Enter capability mode.
302 struct timespec ts;
303 EXPECT_OK(clock_getres(CLOCK_REALTIME, &ts));
304 EXPECT_OK(clock_gettime(CLOCK_REALTIME, &ts));
305 struct itimerval itv;
306 EXPECT_OK(getitimer(ITIMER_REAL, &itv));
307 EXPECT_OK(setitimer(ITIMER_REAL, &itv, NULL));
308 struct timeval tv;
309 struct timezone tz;
310 EXPECT_OK(gettimeofday(&tv, &tz));
311 ts.tv_sec = 0;
312 ts.tv_nsec = 1;
313 EXPECT_OK(nanosleep(&ts, NULL));
314 }
315
316
FORK_TEST(Capmode,AllowedProfilSyscall)317 FORK_TEST(Capmode, AllowedProfilSyscall) {
318 EXPECT_OK(cap_enter()); // Enter capability mode.
319 char sbuf[32];
320 EXPECT_OK(profil((profil_arg1_t*)sbuf, sizeof(sbuf), 0, 1));
321 }
322
323
FORK_TEST(Capmode,AllowedResourceSyscalls)324 FORK_TEST(Capmode, AllowedResourceSyscalls) {
325 EXPECT_OK(cap_enter()); // Enter capability mode.
326 errno = 0;
327 int rc = getpriority(PRIO_PROCESS, 0);
328 EXPECT_EQ(0, errno);
329 EXPECT_OK(setpriority(PRIO_PROCESS, 0, rc));
330 struct rlimit rlim;
331 EXPECT_OK(getrlimit_(RLIMIT_CORE, &rlim));
332 EXPECT_OK(setrlimit(RLIMIT_CORE, &rlim));
333 struct rusage ruse;
334 EXPECT_OK(getrusage(RUSAGE_SELF, &ruse));
335 }
336
FORK_TEST(CapMode,AllowedMmapSyscalls)337 FORK_TEST(CapMode, AllowedMmapSyscalls) {
338 // mmap() some memory.
339 size_t mem_size = getpagesize();
340 void *mem = mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
341 EXPECT_TRUE(mem != NULL);
342 EXPECT_OK(cap_enter()); // Enter capability mode.
343
344 EXPECT_OK(msync(mem, mem_size, MS_ASYNC));
345 EXPECT_OK(madvise(mem, mem_size, MADV_NORMAL));
346 unsigned char vec[2];
347 EXPECT_OK(mincore_(mem, mem_size, vec));
348 EXPECT_OK(mprotect(mem, mem_size, PROT_READ|PROT_WRITE));
349
350 if (!MLOCK_REQUIRES_ROOT || getuid() == 0) {
351 EXPECT_OK(mlock(mem, mem_size));
352 EXPECT_OK(munlock(mem, mem_size));
353 int rc = mlockall(MCL_CURRENT);
354 if (rc != 0) {
355 // mlockall may well fail with ENOMEM for non-root users, as the
356 // default RLIMIT_MEMLOCK value isn't that big.
357 EXPECT_NE(ECAPMODE, errno);
358 }
359 EXPECT_OK(munlockall());
360 }
361 // Unmap the memory.
362 EXPECT_OK(munmap(mem, mem_size));
363 }
364
FORK_TEST(Capmode,AllowedPipeSyscalls)365 FORK_TEST(Capmode, AllowedPipeSyscalls) {
366 EXPECT_OK(cap_enter()); // Enter capability mode
367 int fd2[2];
368 int rc = pipe(fd2);
369 EXPECT_EQ(0, rc);
370
371 #ifdef HAVE_VMSPLICE
372 char buf[11] = "0123456789";
373 struct iovec iov;
374 iov.iov_base = buf;
375 iov.iov_len = sizeof(buf);
376 EXPECT_FAIL_NOT_CAPMODE(vmsplice(fd2[0], &iov, 1, SPLICE_F_NONBLOCK));
377 #endif
378
379 if (rc == 0) {
380 close(fd2[0]);
381 close(fd2[1]);
382 };
383 #ifdef HAVE_PIPE2
384 rc = pipe2(fd2, 0);
385 EXPECT_EQ(0, rc);
386 if (rc == 0) {
387 close(fd2[0]);
388 close(fd2[1]);
389 };
390 #endif
391 }
392
TEST(Capmode,AllowedAtSyscalls)393 TEST(Capmode, AllowedAtSyscalls) {
394 int rc = mkdir(TmpFile("cap_at_syscalls"), 0755);
395 EXPECT_OK(rc);
396 if (rc < 0 && errno != EEXIST) return;
397 int dfd = open(TmpFile("cap_at_syscalls"), O_RDONLY);
398 EXPECT_OK(dfd);
399
400 int file = openat(dfd, "testfile", O_RDONLY|O_CREAT, 0644);
401 EXPECT_OK(file);
402 EXPECT_OK(close(file));
403
404
405 pid_t child = fork();
406 if (child == 0) {
407 // Child: enter cap mode and run tests
408 EXPECT_OK(cap_enter()); // Enter capability mode
409
410 struct stat fs;
411 EXPECT_OK(fstatat(dfd, "testfile", &fs, 0));
412 EXPECT_OK(mkdirat(dfd, "subdir", 0600));
413 EXPECT_OK(fchmodat(dfd, "subdir", 0644, 0));
414 EXPECT_OK(faccessat(dfd, "subdir", F_OK, 0));
415 EXPECT_OK(renameat(dfd, "subdir", dfd, "subdir2"));
416 EXPECT_OK(renameat(dfd, "subdir2", dfd, "subdir"));
417 struct timeval tv[2];
418 struct timezone tz;
419 EXPECT_OK(gettimeofday(&tv[0], &tz));
420 EXPECT_OK(gettimeofday(&tv[1], &tz));
421 EXPECT_OK(futimesat(dfd, "testfile", tv));
422
423 EXPECT_OK(fchownat(dfd, "testfile", fs.st_uid, fs.st_gid, 0));
424 EXPECT_OK(linkat(dfd, "testfile", dfd, "linky", 0));
425 EXPECT_OK(symlinkat("testfile", dfd, "symlink"));
426 char buffer[256];
427 EXPECT_OK(readlinkat(dfd, "symlink", buffer, sizeof(buffer)));
428 EXPECT_OK(unlinkat(dfd, "linky", 0));
429 EXPECT_OK(unlinkat(dfd, "subdir", AT_REMOVEDIR));
430
431 // Check that invalid requests get a non-Capsicum errno.
432 errno = 0;
433 rc = readlinkat(-1, "symlink", buffer, sizeof(buffer));
434 EXPECT_GE(0, rc);
435 EXPECT_NE(ECAPMODE, errno);
436
437 exit(HasFailure());
438 }
439
440 // Wait for the child.
441 int status;
442 EXPECT_EQ(child, waitpid(child, &status, 0));
443 rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
444 EXPECT_EQ(0, rc);
445
446 // Tidy up.
447 close(dfd);
448 rmdir(TmpFile("cap_at_syscalls/subdir"));
449 unlink(TmpFile("cap_at_syscalls/symlink"));
450 unlink(TmpFile("cap_at_syscalls/linky"));
451 unlink(TmpFile("cap_at_syscalls/testfile"));
452 rmdir(TmpFile("cap_at_syscalls"));
453 }
454
TEST(Capmode,AllowedAtSyscallsCwd)455 TEST(Capmode, AllowedAtSyscallsCwd) {
456 int rc = mkdir(TmpFile("cap_at_syscalls_cwd"), 0755);
457 EXPECT_OK(rc);
458 if (rc < 0 && errno != EEXIST) return;
459 int dfd = open(TmpFile("cap_at_syscalls_cwd"), O_RDONLY);
460 EXPECT_OK(dfd);
461
462 int file = openat(dfd, "testfile", O_RDONLY|O_CREAT, 0644);
463 EXPECT_OK(file);
464 EXPECT_OK(close(file));
465
466 pid_t child = fork();
467 if (child == 0) {
468 // Child: move into temp dir, enter cap mode and run tests
469 EXPECT_OK(fchdir(dfd));
470 EXPECT_OK(cap_enter()); // Enter capability mode
471
472 // Test that *at(AT_FDCWD, path,...) is policed with ECAPMODE.
473 EXPECT_CAPMODE(openat(AT_FDCWD, "testfile", O_RDONLY));
474 struct stat fs;
475 EXPECT_CAPMODE(fstatat(AT_FDCWD, "testfile", &fs, 0));
476 EXPECT_CAPMODE(mkdirat(AT_FDCWD, "subdir", 0600));
477 EXPECT_CAPMODE(fchmodat(AT_FDCWD, "subdir", 0644, 0));
478 EXPECT_CAPMODE(faccessat(AT_FDCWD, "subdir", F_OK, 0));
479 EXPECT_CAPMODE(renameat(AT_FDCWD, "subdir", AT_FDCWD, "subdir2"));
480 EXPECT_CAPMODE(renameat(AT_FDCWD, "subdir2", AT_FDCWD, "subdir"));
481 struct timeval tv[2];
482 struct timezone tz;
483 EXPECT_OK(gettimeofday(&tv[0], &tz));
484 EXPECT_OK(gettimeofday(&tv[1], &tz));
485 EXPECT_CAPMODE(futimesat(AT_FDCWD, "testfile", tv));
486
487 EXPECT_CAPMODE(fchownat(AT_FDCWD, "testfile", fs.st_uid, fs.st_gid, 0));
488 EXPECT_CAPMODE(linkat(AT_FDCWD, "testfile", AT_FDCWD, "linky", 0));
489 EXPECT_CAPMODE(symlinkat("testfile", AT_FDCWD, "symlink"));
490 char buffer[256];
491 EXPECT_CAPMODE(readlinkat(AT_FDCWD, "symlink", buffer, sizeof(buffer)));
492 EXPECT_CAPMODE(unlinkat(AT_FDCWD, "linky", 0));
493
494 exit(HasFailure());
495 }
496
497 // Wait for the child.
498 int status;
499 EXPECT_EQ(child, waitpid(child, &status, 0));
500 rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
501 EXPECT_EQ(0, rc);
502
503 // Tidy up.
504 close(dfd);
505 rmdir(TmpFile("cap_at_syscalls_cwd/subdir"));
506 unlink(TmpFile("cap_at_syscalls_cwd/symlink"));
507 unlink(TmpFile("cap_at_syscalls_cwd/linky"));
508 unlink(TmpFile("cap_at_syscalls_cwd/testfile"));
509 rmdir(TmpFile("cap_at_syscalls_cwd"));
510 }
511
TEST(Capmode,Abort)512 TEST(Capmode, Abort) {
513 // Check that abort(3) works even in capability mode.
514 pid_t child = fork();
515 if (child == 0) {
516 // Child: enter capability mode and call abort(3).
517 // Triggers something like kill(getpid(), SIGABRT).
518 cap_enter(); // Enter capability mode.
519 abort();
520 exit(99);
521 }
522 int status;
523 EXPECT_EQ(child, waitpid(child, &status, 0));
524 EXPECT_TRUE(WIFSIGNALED(status)) << " status = " << std::hex << status;
525 EXPECT_EQ(SIGABRT, WTERMSIG(status)) << " status = " << std::hex << status;
526 }
527
FORK_TEST_F(WithFiles,AllowedMiscSyscalls)528 FORK_TEST_F(WithFiles, AllowedMiscSyscalls) {
529 umask(022);
530 mode_t um_before = umask(022);
531 int pipefds[2];
532 EXPECT_OK(pipe(pipefds));
533 EXPECT_OK(cap_enter()); // Enter capability mode.
534
535 mode_t um = umask(022);
536 EXPECT_NE(-ECAPMODE, (int)um);
537 EXPECT_EQ(um_before, um);
538 stack_t ss;
539 EXPECT_OK(sigaltstack(NULL, &ss));
540
541 // Finally, tests for system calls that don't fit the pattern very well.
542 pid_t pid = fork();
543 EXPECT_OK(pid);
544 if (pid == 0) {
545 // Child: wait for an exit message from parent (so we can test waitpid).
546 EXPECT_OK(close(pipefds[0]));
547 SEND_INT_MESSAGE(pipefds[1], MSG_CHILD_STARTED);
548 AWAIT_INT_MESSAGE(pipefds[1], MSG_PARENT_REQUEST_CHILD_EXIT);
549 exit(0);
550 } else if (pid > 0) {
551 EXPECT_OK(close(pipefds[1]));
552 AWAIT_INT_MESSAGE(pipefds[0], MSG_CHILD_STARTED);
553 errno = 0;
554 EXPECT_CAPMODE(ptrace_(PTRACE_PEEKDATA_, pid, &pid, NULL));
555 EXPECT_CAPMODE(waitpid(pid, NULL, WNOHANG));
556 SEND_INT_MESSAGE(pipefds[0], MSG_PARENT_REQUEST_CHILD_EXIT);
557 if (verbose) fprintf(stderr, " child finished\n");
558 }
559
560 // No error return from sync(2) to test, but check errno remains unset.
561 errno = 0;
562 sync();
563 EXPECT_EQ(0, errno);
564
565 // TODO(FreeBSD): ktrace
566
567 #ifdef HAVE_SYSARCH
568 // sysarch() is, by definition, architecture-dependent
569 #if defined (__amd64__) || defined (__i386__)
570 long sysarch_arg = 0;
571 EXPECT_CAPMODE(sysarch(I386_SET_IOPERM, &sysarch_arg));
572 #else
573 // TOOD(jra): write a test for other architectures, like arm
574 #endif
575 #endif
576 }
577
thread_fn(void * p)578 void *thread_fn(void *p) {
579 int fd = (int)(intptr_t)p;
580 if (verbose) fprintf(stderr, " thread waiting to run\n");
581 AWAIT_INT_MESSAGE(fd, MSG_PARENT_CHILD_SHOULD_RUN);
582 EXPECT_OK(getpid_());
583 EXPECT_CAPMODE(open("/dev/null", O_RDWR));
584 // Return whether there have been any failures to the main thread.
585 void *rval = (void *)(intptr_t)testing::Test::HasFailure();
586 if (verbose) fprintf(stderr, " thread finished: %p\n", rval);
587 return rval;
588 }
589
590 // Check that restrictions are the same in subprocesses and threads
FORK_TEST(Capmode,NewThread)591 FORK_TEST(Capmode, NewThread) {
592 // Fire off a new thread before entering capability mode
593 pthread_t early_thread;
594 void *thread_rval;
595 // Create two pipes, one for synchronization with the threads, the other to
596 // synchronize with the children (since we can't use waitpid after cap_enter).
597 // Note: Could use pdfork+pdwait instead, but that is tested in procdesc.cc.
598 int thread_pipe[2];
599 EXPECT_OK(pipe(thread_pipe));
600 int proc_pipe[2];
601 EXPECT_OK(pipe(proc_pipe));
602 EXPECT_OK(pthread_create(&early_thread, NULL, thread_fn,
603 (void *)(intptr_t)thread_pipe[1]));
604
605 // Fire off a new process before entering capability mode.
606 if (verbose) fprintf(stderr, " starting second child (non-capability mode)\n");
607 int early_child = fork();
608 EXPECT_OK(early_child);
609 if (early_child == 0) {
610 if (verbose) fprintf(stderr, " first child started\n");
611 EXPECT_OK(close(proc_pipe[0]));
612 // Child: wait and then confirm this process is unaffected by capability mode in the parent.
613 AWAIT_INT_MESSAGE(proc_pipe[1], MSG_PARENT_CHILD_SHOULD_RUN);
614 int fd = open("/dev/null", O_RDWR);
615 EXPECT_OK(fd);
616 close(fd);
617 // Notify the parent of success/failure.
618 int rval = (int)testing::Test::HasFailure();
619 SEND_INT_MESSAGE(proc_pipe[1], rval);
620 if (verbose) fprintf(stderr, " first child finished: %d\n", rval);
621 exit(rval);
622 }
623
624 EXPECT_OK(cap_enter()); // Enter capability mode.
625 // At this point the current process has both a child process and a
626 // child thread that were created before entering capability mode.
627 // - The child process is unaffected by capability mode.
628 // - The child thread is affected by capability mode.
629 SEND_INT_MESSAGE(proc_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
630
631 // Do an allowed syscall.
632 EXPECT_OK(getpid_());
633 // Wait for the first child to exit (should get a zero exit code message).
634 AWAIT_INT_MESSAGE(proc_pipe[0], 0);
635
636 // The child processes/threads return HasFailure(), so we depend on no prior errors.
637 ASSERT_FALSE(testing::Test::HasFailure())
638 << "Cannot continue test with pre-existing failures.";
639 // Now that we're in capability mode, if we create a second child process
640 // it will be affected by capability mode.
641 if (verbose) fprintf(stderr, " starting second child (in capability mode)\n");
642 int child = fork();
643 EXPECT_OK(child);
644 if (child == 0) {
645 if (verbose) fprintf(stderr, " second child started\n");
646 EXPECT_OK(close(proc_pipe[0]));
647 // Child: do an allowed and a disallowed syscall.
648 EXPECT_OK(getpid_());
649 EXPECT_CAPMODE(open("/dev/null", O_RDWR));
650 // Notify the parent of success/failure.
651 int rval = (int)testing::Test::HasFailure();
652 SEND_INT_MESSAGE(proc_pipe[1], rval);
653 if (verbose) fprintf(stderr, " second child finished: %d\n", rval);
654 exit(rval);
655 }
656 // Now tell the early_started thread that it can run. We expect it to also
657 // be affected by capability mode since it's per-process not per-thread.
658 // Note: it is important that we don't allow the thread to run before fork(),
659 // since that could result in fork() being called while the thread holds one
660 // of the gtest-internal mutexes, so the child process deadlocks.
661 SEND_INT_MESSAGE(thread_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
662 // Wait for the early-started thread.
663 EXPECT_OK(pthread_join(early_thread, &thread_rval));
664 EXPECT_FALSE((bool)(intptr_t)thread_rval) << "thread returned failure";
665
666 // Wait for the second child to exit (should get a zero exit code message).
667 AWAIT_INT_MESSAGE(proc_pipe[0], 0);
668
669 // Fire off a new (second) child thread, which is also affected by capability mode.
670 ASSERT_FALSE(testing::Test::HasFailure())
671 << "Cannot continue test with pre-existing failures.";
672 pthread_t child_thread;
673 EXPECT_OK(pthread_create(&child_thread, NULL, thread_fn,
674 (void *)(intptr_t)thread_pipe[1]));
675 SEND_INT_MESSAGE(thread_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
676 EXPECT_OK(pthread_join(child_thread, &thread_rval));
677 EXPECT_FALSE((bool)(intptr_t)thread_rval) << "thread returned failure";
678
679 // Fork a subprocess which fires off a new thread.
680 ASSERT_FALSE(testing::Test::HasFailure())
681 << "Cannot continue test with pre-existing failures.";
682 if (verbose) fprintf(stderr, " starting third child (in capability mode)\n");
683 child = fork();
684 EXPECT_OK(child);
685 if (child == 0) {
686 if (verbose) fprintf(stderr, " third child started\n");
687 EXPECT_OK(close(proc_pipe[0]));
688 pthread_t child_thread2;
689 EXPECT_OK(pthread_create(&child_thread2, NULL, thread_fn,
690 (void *)(intptr_t)thread_pipe[1]));
691 SEND_INT_MESSAGE(thread_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
692 EXPECT_OK(pthread_join(child_thread2, &thread_rval));
693 EXPECT_FALSE((bool)(intptr_t)thread_rval) << "thread returned failure";
694 // Notify the parent of success/failure.
695 int rval = (int)testing::Test::HasFailure();
696 SEND_INT_MESSAGE(proc_pipe[1], rval);
697 if (verbose) fprintf(stderr, " third child finished: %d\n", rval);
698 exit(rval);
699 }
700 // Wait for the third child to exit (should get a zero exit code message).
701 AWAIT_INT_MESSAGE(proc_pipe[0], 0);
702 close(proc_pipe[0]);
703 close(proc_pipe[1]);
704 close(thread_pipe[0]);
705 close(thread_pipe[1]);
706 }
707
708 static volatile sig_atomic_t had_signal = 0;
handle_signal(int)709 static void handle_signal(int) { had_signal = 1; }
710
FORK_TEST(Capmode,SelfKill)711 FORK_TEST(Capmode, SelfKill) {
712 pid_t me = getpid();
713 sighandler_t original = signal(SIGUSR1, handle_signal);
714
715 pid_t child = fork();
716 if (child == 0) {
717 // Child: sleep and exit
718 sleep(1);
719 exit(0);
720 }
721
722 EXPECT_OK(cap_enter()); // Enter capability mode.
723
724 // Can only kill(2) to own pid.
725 EXPECT_CAPMODE(kill(child, SIGUSR1));
726 EXPECT_OK(kill(me, SIGUSR1));
727 EXPECT_EQ(1, had_signal);
728
729 signal(SIGUSR1, original);
730 }
731