1 // Test that fcntl works in capability mode. 2 #include <sys/types.h> 3 #include <sys/stat.h> 4 #include <fcntl.h> 5 #include <sys/types.h> 6 #include <sys/socket.h> 7 #include <sys/mman.h> 8 #include <sys/stat.h> 9 #include <fcntl.h> 10 #include <unistd.h> 11 #include <stdint.h> 12 13 #include <string> 14 #include <map> 15 16 #include "capsicum.h" 17 #include "capsicum-test.h" 18 #include "syscalls.h" 19 20 // Ensure that fcntl() works consistently for both regular file descriptors and 21 // capability-wrapped ones. 22 FORK_TEST(Fcntl, Basic) { 23 cap_rights_t rights; 24 cap_rights_init(&rights, CAP_READ, CAP_FCNTL); 25 26 typedef std::map<std::string, int> FileMap; 27 28 // Open some files of different types, and wrap them in capabilities. 29 FileMap files; 30 files["file"] = open("/etc/passwd", O_RDONLY); 31 EXPECT_OK(files["file"]); 32 files["socket"] = socket(PF_LOCAL, SOCK_STREAM, 0); 33 EXPECT_OK(files["socket"]); 34 char shm_name[128]; 35 sprintf(shm_name, "/capsicum-test-%d", getuid()); 36 files["SHM"] = shm_open(shm_name, (O_CREAT|O_RDWR), 0600); 37 if ((files["SHM"] == -1) && errno == ENOSYS) { 38 // shm_open() is not implemented in user-mode Linux. 39 files.erase("SHM"); 40 } else { 41 EXPECT_OK(files["SHM"]); 42 } 43 44 FileMap caps; 45 for (FileMap::iterator ii = files.begin(); ii != files.end(); ++ii) { 46 std::string key = ii->first + " cap"; 47 caps[key] = dup(ii->second); 48 EXPECT_OK(cap_rights_limit(caps[key], &rights)); 49 EXPECT_OK(caps[key]) << " on " << ii->first; 50 } 51 52 FileMap all(files); 53 all.insert(files.begin(), files.end()); 54 55 EXPECT_OK(cap_enter()); // Enter capability mode. 56 57 // Ensure that we can fcntl() all the files that we opened above. 58 cap_rights_t r_ro; 59 cap_rights_init(&r_ro, CAP_READ); 60 for (FileMap::iterator ii = all.begin(); ii != all.end(); ++ii) { 61 EXPECT_OK(fcntl(ii->second, F_GETFL, 0)) << " on " << ii->first; 62 int cap = dup(ii->second); 63 EXPECT_OK(cap) << " on " << ii->first; 64 EXPECT_OK(cap_rights_limit(cap, &r_ro)) << " on " << ii->first; 65 EXPECT_EQ(-1, fcntl(cap, F_GETFL, 0)) << " on " << ii->first; 66 EXPECT_EQ(ENOTCAPABLE, errno) << " on " << ii->first; 67 close(cap); 68 } 69 for (FileMap::iterator ii = all.begin(); ii != all.end(); ++ii) { 70 close(ii->second); 71 } 72 shm_unlink(shm_name); 73 } 74 75 // Supported fcntl(2) operations: 76 // FreeBSD10 FreeBSD9.1: Linux: Rights: Summary: 77 // F_DUPFD F_DUPFD F_DUPFD NONE as dup(2) 78 // F_DUPFD_CLOEXEC F_DUPFD_CLOEXEC NONE as dup(2) with close-on-exec 79 // F_DUP2FD F_DUP2FD NONE as dup2(2) 80 // F_DUP2FD_CLOEXEC NONE as dup2(2) with close-on-exec 81 // F_GETFD F_GETFD F_GETFD NONE get close-on-exec flag 82 // F_SETFD F_SETFD F_SETFD NONE set close-on-exec flag 83 // * F_GETFL F_GETFL F_GETFL FCNTL get file status flag 84 // * F_SETFL F_SETFL F_SETFL FCNTL set file status flag 85 // * F_GETOWN F_GETOWN F_GETOWN FCNTL get pid receiving SIGIO/SIGURG 86 // * F_SETOWN F_SETOWN F_SETOWN FCNTL set pid receiving SIGIO/SIGURG 87 // * F_GETOWN_EX FCNTL get pid/thread receiving SIGIO/SIGURG 88 // * F_SETOWN_EX FCNTL set pid/thread receiving SIGIO/SIGURG 89 // F_GETLK F_GETLK F_GETLK FLOCK get lock info 90 // F_SETLK F_SETLK F_SETLK FLOCK set lock info 91 // F_SETLK_REMOTE FLOCK set lock info 92 // F_SETLKW F_SETLKW F_SETLKW FLOCK set lock info (blocking) 93 // F_READAHEAD F_READAHEAD NONE set or clear readahead amount 94 // F_RDAHEAD F_RDAHEAD NONE set or clear readahead amount to 128KB 95 // F_GETSIG POLL_EVENT+FSIGNAL get signal sent when I/O possible 96 // F_SETSIG POLL_EVENT+FSIGNAL set signal sent when I/O possible 97 // F_GETLEASE FLOCK+FSIGNAL get lease on file descriptor 98 // F_SETLEASE FLOCK+FSIGNAL set new lease on file descriptor 99 // F_NOTIFY NOTIFY generate signal on changes (dnotify) 100 // F_GETPIPE_SZ GETSOCKOPT get pipe size 101 // F_SETPIPE_SZ SETSOCKOPT set pipe size 102 // F_GET_SEAL FSTAT get memfd seals 103 // F_ADD_SEAL FCHMOD set memfd seal 104 // If HAVE_CAP_FCNTLS_LIMIT is defined, then fcntl(2) operations that require 105 // CAP_FCNTL (marked with * above) can be further limited with cap_fcntls_limit(2). 106 namespace { 107 #define FCNTL_NUM_RIGHTS 9 108 cap_rights_t fcntl_rights[FCNTL_NUM_RIGHTS]; 109 void InitRights() { 110 cap_rights_init(&(fcntl_rights[0]), 0); // Later code assumes this is at [0] 111 cap_rights_init(&(fcntl_rights[1]), CAP_READ, CAP_WRITE); 112 cap_rights_init(&(fcntl_rights[2]), CAP_FCNTL); 113 cap_rights_init(&(fcntl_rights[3]), CAP_FLOCK); 114 #ifdef CAP_FSIGNAL 115 cap_rights_init(&(fcntl_rights[4]), CAP_EVENT, CAP_FSIGNAL); 116 cap_rights_init(&(fcntl_rights[5]), CAP_FLOCK, CAP_FSIGNAL); 117 #else 118 cap_rights_init(&(fcntl_rights[4]), 0); 119 cap_rights_init(&(fcntl_rights[5]), 0); 120 #endif 121 #ifdef CAP_NOTIFY 122 cap_rights_init(&(fcntl_rights[6]), CAP_NOTIFY); 123 #else 124 cap_rights_init(&(fcntl_rights[6]), 0); 125 #endif 126 cap_rights_init(&(fcntl_rights[7]), CAP_SETSOCKOPT); 127 cap_rights_init(&(fcntl_rights[8]), CAP_GETSOCKOPT); 128 } 129 130 int CheckFcntl(unsigned long long right, int caps[FCNTL_NUM_RIGHTS], int cmd, long arg, const char* context) { 131 SCOPED_TRACE(context); 132 cap_rights_t rights; 133 cap_rights_init(&rights, right); 134 int ok_index = -1; 135 for (int ii = 0; ii < FCNTL_NUM_RIGHTS; ++ii) { 136 if (cap_rights_contains(&(fcntl_rights[ii]), &rights)) { 137 if (ok_index == -1) ok_index = ii; 138 continue; 139 } 140 EXPECT_NOTCAPABLE(fcntl(caps[ii], cmd, arg)); 141 } 142 EXPECT_NE(-1, ok_index); 143 int rc = fcntl(caps[ok_index], cmd, arg); 144 EXPECT_OK(rc); 145 return rc; 146 } 147 } // namespace 148 149 #define CHECK_FCNTL(right, caps, cmd, arg) \ 150 CheckFcntl(right, caps, cmd, arg, "fcntl(" #cmd ") expect " #right) 151 152 TEST(Fcntl, Commands) { 153 InitRights(); 154 int fd = open(TmpFile("cap_fcntl_cmds"), O_RDWR|O_CREAT, 0644); 155 EXPECT_OK(fd); 156 write(fd, "TEST", 4); 157 int sock = socket(PF_LOCAL, SOCK_STREAM, 0); 158 EXPECT_OK(sock); 159 int caps[FCNTL_NUM_RIGHTS]; 160 int sock_caps[FCNTL_NUM_RIGHTS]; 161 for (int ii = 0; ii < FCNTL_NUM_RIGHTS; ++ii) { 162 caps[ii] = dup(fd); 163 EXPECT_OK(caps[ii]); 164 EXPECT_OK(cap_rights_limit(caps[ii], &(fcntl_rights[ii]))); 165 sock_caps[ii] = dup(sock); 166 EXPECT_OK(sock_caps[ii]); 167 EXPECT_OK(cap_rights_limit(sock_caps[ii], &(fcntl_rights[ii]))); 168 } 169 170 // Check the things that need no rights against caps[0]. 171 int newfd = fcntl(caps[0], F_DUPFD, 0); 172 EXPECT_OK(newfd); 173 // dup()'ed FD should have same rights. 174 cap_rights_t rights; 175 cap_rights_init(&rights, 0); 176 EXPECT_OK(cap_rights_get(newfd, &rights)); 177 EXPECT_RIGHTS_EQ(&(fcntl_rights[0]), &rights); 178 close(newfd); 179 #ifdef HAVE_F_DUP2FD 180 EXPECT_OK(fcntl(caps[0], F_DUP2FD, newfd)); 181 // dup2()'ed FD should have same rights. 182 EXPECT_OK(cap_rights_get(newfd, &rights)); 183 EXPECT_RIGHTS_EQ(&(fcntl_rights[0]), &rights); 184 close(newfd); 185 #endif 186 187 EXPECT_OK(fcntl(caps[0], F_GETFD, 0)); 188 EXPECT_OK(fcntl(caps[0], F_SETFD, 0)); 189 190 // Check operations that need CAP_FCNTL. 191 int fd_flag = CHECK_FCNTL(CAP_FCNTL, caps, F_GETFL, 0); 192 EXPECT_EQ(0, CHECK_FCNTL(CAP_FCNTL, caps, F_SETFL, fd_flag)); 193 int owner = CHECK_FCNTL(CAP_FCNTL, sock_caps, F_GETOWN, 0); 194 EXPECT_EQ(0, CHECK_FCNTL(CAP_FCNTL, sock_caps, F_SETOWN, owner)); 195 196 // Check an operation needing CAP_FLOCK. 197 struct flock fl; 198 memset(&fl, 0, sizeof(fl)); 199 fl.l_type = F_RDLCK; 200 fl.l_whence = SEEK_SET; 201 fl.l_start = 0; 202 fl.l_len = 1; 203 EXPECT_EQ(0, CHECK_FCNTL(CAP_FLOCK, caps, F_GETLK, (long)&fl)); 204 205 for (int ii = 0; ii < FCNTL_NUM_RIGHTS; ++ii) { 206 close(sock_caps[ii]); 207 close(caps[ii]); 208 } 209 close(sock); 210 close(fd); 211 unlink(TmpFile("cap_fcntl_cmds")); 212 } 213 214 TEST(Fcntl, WriteLock) { 215 int fd = open(TmpFile("cap_fcntl_readlock"), O_RDWR|O_CREAT, 0644); 216 EXPECT_OK(fd); 217 write(fd, "TEST", 4); 218 219 int cap = dup(fd); 220 cap_rights_t rights; 221 cap_rights_init(&rights, CAP_FCNTL, CAP_READ, CAP_WRITE, CAP_FLOCK); 222 EXPECT_OK(cap_rights_limit(cap, &rights)); 223 224 struct flock fl; 225 memset(&fl, 0, sizeof(fl)); 226 fl.l_type = F_WRLCK; 227 fl.l_whence = SEEK_SET; 228 fl.l_start = 0; 229 fl.l_len = 1; 230 // Write-Lock 231 EXPECT_OK(fcntl(cap, F_SETLK, (long)&fl)); 232 233 // Check write-locked (from another process). 234 pid_t child = fork(); 235 if (child == 0) { 236 fl.l_type = F_WRLCK; 237 fl.l_whence = SEEK_SET; 238 fl.l_start = 0; 239 fl.l_len = 1; 240 EXPECT_OK(fcntl(fd, F_GETLK, (long)&fl)); 241 EXPECT_NE(F_UNLCK, fl.l_type); 242 exit(HasFailure()); 243 } 244 int status; 245 EXPECT_EQ(child, waitpid(child, &status, 0)); 246 int rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1; 247 EXPECT_EQ(0, rc); 248 249 // Unlock 250 fl.l_type = F_UNLCK; 251 fl.l_whence = SEEK_SET; 252 fl.l_start = 0; 253 fl.l_len = 1; 254 EXPECT_OK(fcntl(cap, F_SETLK, (long)&fl)); 255 256 close(cap); 257 close(fd); 258 unlink(TmpFile("cap_fcntl_readlock")); 259 } 260 261 #ifdef HAVE_CAP_FCNTLS_LIMIT 262 TEST(Fcntl, SubRightNormalFD) { 263 int fd = open(TmpFile("cap_fcntl_subrightnorm"), O_RDWR|O_CREAT, 0644); 264 EXPECT_OK(fd); 265 266 // Restrict the fcntl(2) subrights of a normal FD. 267 EXPECT_OK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL)); 268 int fd_flag = fcntl(fd, F_GETFL, 0); 269 EXPECT_OK(fd_flag); 270 EXPECT_NOTCAPABLE(fcntl(fd, F_SETFL, fd_flag)); 271 272 // Expect to have all capabilities. 273 cap_rights_t rights; 274 EXPECT_OK(cap_rights_get(fd, &rights)); 275 cap_rights_t all; 276 CAP_SET_ALL(&all); 277 EXPECT_RIGHTS_EQ(&all, &rights); 278 cap_fcntl_t fcntls; 279 EXPECT_OK(cap_fcntls_get(fd, &fcntls)); 280 EXPECT_EQ((cap_fcntl_t)CAP_FCNTL_GETFL, fcntls); 281 282 // Can't widen the subrights. 283 EXPECT_NOTCAPABLE(cap_fcntls_limit(fd, CAP_FCNTL_GETFL|CAP_FCNTL_SETFL)); 284 285 close(fd); 286 unlink(TmpFile("cap_fcntl_subrightnorm")); 287 } 288 289 TEST(Fcntl, PreserveSubRights) { 290 int fd = open(TmpFile("cap_fcntl_subrightpreserve"), O_RDWR|O_CREAT, 0644); 291 EXPECT_OK(fd); 292 293 cap_rights_t rights; 294 cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_SEEK, CAP_FCNTL); 295 EXPECT_OK(cap_rights_limit(fd, &rights)); 296 EXPECT_OK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL)); 297 298 cap_rights_t cur_rights; 299 cap_fcntl_t fcntls; 300 EXPECT_OK(cap_rights_get(fd, &cur_rights)); 301 EXPECT_RIGHTS_EQ(&rights, &cur_rights); 302 EXPECT_OK(cap_fcntls_get(fd, &fcntls)); 303 EXPECT_EQ((cap_fcntl_t)CAP_FCNTL_GETFL, fcntls); 304 305 // Limiting the top-level rights leaves the subrights unaffected... 306 cap_rights_clear(&rights, CAP_READ); 307 EXPECT_OK(cap_rights_limit(fd, &rights)); 308 EXPECT_OK(cap_fcntls_get(fd, &fcntls)); 309 EXPECT_EQ((cap_fcntl_t)CAP_FCNTL_GETFL, fcntls); 310 311 // ... until we remove CAP_FCNTL. 312 cap_rights_clear(&rights, CAP_FCNTL); 313 EXPECT_OK(cap_rights_limit(fd, &rights)); 314 EXPECT_OK(cap_fcntls_get(fd, &fcntls)); 315 EXPECT_EQ((cap_fcntl_t)0, fcntls); 316 EXPECT_EQ(-1, cap_fcntls_limit(fd, CAP_FCNTL_GETFL)); 317 318 close(fd); 319 unlink(TmpFile("cap_fcntl_subrightpreserve")); 320 } 321 322 TEST(Fcntl, FLSubRights) { 323 int fd = open(TmpFile("cap_fcntl_subrights"), O_RDWR|O_CREAT, 0644); 324 EXPECT_OK(fd); 325 write(fd, "TEST", 4); 326 cap_rights_t rights; 327 cap_rights_init(&rights, CAP_FCNTL); 328 EXPECT_OK(cap_rights_limit(fd, &rights)); 329 330 // Check operations that need CAP_FCNTL with subrights pristine => OK. 331 int fd_flag = fcntl(fd, F_GETFL, 0); 332 EXPECT_OK(fd_flag); 333 EXPECT_OK(fcntl(fd, F_SETFL, fd_flag)); 334 335 // Check operations that need CAP_FCNTL with all subrights => OK. 336 EXPECT_OK(cap_fcntls_limit(fd, CAP_FCNTL_ALL)); 337 fd_flag = fcntl(fd, F_GETFL, 0); 338 EXPECT_OK(fd_flag); 339 EXPECT_OK(fcntl(fd, F_SETFL, fd_flag)); 340 341 // Check operations that need CAP_FCNTL with specific subrights. 342 int fd_get = dup(fd); 343 int fd_set = dup(fd); 344 EXPECT_OK(cap_fcntls_limit(fd_get, CAP_FCNTL_GETFL)); 345 EXPECT_OK(cap_fcntls_limit(fd_set, CAP_FCNTL_SETFL)); 346 347 fd_flag = fcntl(fd_get, F_GETFL, 0); 348 EXPECT_OK(fd_flag); 349 EXPECT_NOTCAPABLE(fcntl(fd_set, F_GETFL, 0)); 350 EXPECT_OK(fcntl(fd_set, F_SETFL, fd_flag)); 351 EXPECT_NOTCAPABLE(fcntl(fd_get, F_SETFL, fd_flag)); 352 close(fd_get); 353 close(fd_set); 354 355 // Check operations that need CAP_FCNTL with no subrights => ENOTCAPABLE. 356 EXPECT_OK(cap_fcntls_limit(fd, 0)); 357 EXPECT_NOTCAPABLE(fcntl(fd, F_GETFL, 0)); 358 EXPECT_NOTCAPABLE(fcntl(fd, F_SETFL, fd_flag)); 359 360 close(fd); 361 unlink(TmpFile("cap_fcntl_subrights")); 362 } 363 364 TEST(Fcntl, OWNSubRights) { 365 int sock = socket(PF_LOCAL, SOCK_STREAM, 0); 366 EXPECT_OK(sock); 367 cap_rights_t rights; 368 cap_rights_init(&rights, CAP_FCNTL); 369 EXPECT_OK(cap_rights_limit(sock, &rights)); 370 371 // Check operations that need CAP_FCNTL with no subrights => OK. 372 int owner = fcntl(sock, F_GETOWN, 0); 373 EXPECT_OK(owner); 374 EXPECT_OK(fcntl(sock, F_SETOWN, owner)); 375 376 // Check operations that need CAP_FCNTL with all subrights => OK. 377 EXPECT_OK(cap_fcntls_limit(sock, CAP_FCNTL_ALL)); 378 owner = fcntl(sock, F_GETOWN, 0); 379 EXPECT_OK(owner); 380 EXPECT_OK(fcntl(sock, F_SETOWN, owner)); 381 382 // Check operations that need CAP_FCNTL with specific subrights. 383 int sock_get = dup(sock); 384 int sock_set = dup(sock); 385 EXPECT_OK(cap_fcntls_limit(sock_get, CAP_FCNTL_GETOWN)); 386 EXPECT_OK(cap_fcntls_limit(sock_set, CAP_FCNTL_SETOWN)); 387 owner = fcntl(sock_get, F_GETOWN, 0); 388 EXPECT_OK(owner); 389 EXPECT_NOTCAPABLE(fcntl(sock_set, F_GETOWN, 0)); 390 EXPECT_OK(fcntl(sock_set, F_SETOWN, owner)); 391 EXPECT_NOTCAPABLE(fcntl(sock_get, F_SETOWN, owner)); 392 // Also check we can retrieve the subrights. 393 cap_fcntl_t fcntls; 394 EXPECT_OK(cap_fcntls_get(sock_get, &fcntls)); 395 EXPECT_EQ((cap_fcntl_t)CAP_FCNTL_GETOWN, fcntls); 396 EXPECT_OK(cap_fcntls_get(sock_set, &fcntls)); 397 EXPECT_EQ((cap_fcntl_t)CAP_FCNTL_SETOWN, fcntls); 398 // And that we can't widen the subrights. 399 EXPECT_NOTCAPABLE(cap_fcntls_limit(sock_get, CAP_FCNTL_GETOWN|CAP_FCNTL_SETOWN)); 400 EXPECT_NOTCAPABLE(cap_fcntls_limit(sock_set, CAP_FCNTL_GETOWN|CAP_FCNTL_SETOWN)); 401 close(sock_get); 402 close(sock_set); 403 404 // Check operations that need CAP_FCNTL with no subrights => ENOTCAPABLE. 405 EXPECT_OK(cap_fcntls_limit(sock, 0)); 406 EXPECT_NOTCAPABLE(fcntl(sock, F_GETOWN, 0)); 407 EXPECT_NOTCAPABLE(fcntl(sock, F_SETOWN, owner)); 408 409 close(sock); 410 } 411 #endif 412