1 /* Tests for System V IPC semaphores - by D.C. van Moolenbroek */ 2 /* This test must be run as root, as it includes permission checking tests. */ 3 #include <stdlib.h> 4 #include <limits.h> 5 #include <pwd.h> 6 #include <grp.h> 7 #include <sys/ipc.h> 8 #include <sys/sem.h> 9 #include <sys/wait.h> 10 #include <sys/mman.h> 11 #include <signal.h> 12 13 #include "common.h" 14 15 #define ITERATIONS 3 16 17 #define WAIT_USECS 100000 /* time for processes to get ready */ 18 19 #define KEY_A 0x73570001 20 #define KEY_B (KEY_A + 1) 21 #define KEY_C (KEY_A + 2) 22 23 #define ROOT_USER "root" /* name of root */ 24 #define ROOT_GROUP "operator" /* name of root's group */ 25 #define NONROOT_USER "bin" /* name of any unprivileged user */ 26 #define NONROOT_GROUP "bin" /* name of any unprivileged group */ 27 28 enum { 29 DROP_NONE, 30 DROP_USER, 31 DROP_ALL, 32 }; 33 34 enum { 35 SUGID_NONE, 36 SUGID_ROOT_USER, 37 SUGID_NONROOT_USER, 38 SUGID_ROOT_GROUP, 39 SUGID_NONROOT_GROUP, 40 }; 41 42 struct link { 43 pid_t pid; 44 int sndfd; 45 int rcvfd; 46 }; 47 48 /* 49 * Test semaphore properties. This is a macro, so that it prints useful line 50 * information if an error occurs. 51 */ 52 #define TEST_SEM(id, num, val, pid, ncnt, zcnt) do { \ 53 if (semctl(id, num, GETVAL) != val) e(0); \ 54 if (pid != -1 && semctl(id, num, GETPID) != pid) e(1); \ 55 if (ncnt != -1 && semctl(id, num, GETNCNT) != ncnt) e(2); \ 56 if (zcnt != -1 && semctl(id, num, GETZCNT) != zcnt) e(3); \ 57 } while (0); 58 59 static int nr_signals = 0; 60 61 static size_t page_size; 62 static char *page_ptr; 63 static void *bad_ptr; 64 65 /* 66 * Spawn a child process, with a pair of pipes to talk to it bidirectionally. 67 * Drop user and group privileges in the child process if requested. 68 */ 69 static void 70 spawn(struct link * link, void (* proc)(), int drop) 71 { 72 struct passwd *pw; 73 struct group *gr; 74 int up[2], dn[2]; 75 76 fflush(stdout); 77 fflush(stderr); 78 79 if (pipe(up) != 0) e(0); 80 if (pipe(dn) != 0) e(0); 81 82 link->pid = fork(); 83 84 switch (link->pid) { 85 case 0: 86 close(up[1]); 87 close(dn[0]); 88 89 link->pid = getppid(); 90 link->rcvfd = up[0]; 91 link->sndfd = dn[1]; 92 93 errct = 0; 94 95 switch (drop) { 96 case DROP_ALL: 97 if (setgroups(0, NULL) != 0) e(0); 98 99 if ((gr = getgrnam(NONROOT_GROUP)) == NULL) e(0); 100 101 if (setgid(gr->gr_gid) != 0) e(0); 102 if (setegid(gr->gr_gid) != 0) e(0); 103 104 /* FALLTHROUGH */ 105 case DROP_USER: 106 if ((pw = getpwnam(NONROOT_USER)) == NULL) e(0); 107 108 /* FIXME: this may rely on a MINIXism. */ 109 if (setuid(pw->pw_uid) != 0) e(0); 110 if (seteuid(pw->pw_uid) != 0) e(0); 111 } 112 113 proc(link); 114 115 /* Close our pipe FDs on exit, so that we can make zombies. */ 116 exit(errct); 117 case -1: 118 e(0); 119 break; 120 } 121 122 close(up[0]); 123 close(dn[1]); 124 125 link->sndfd = up[1]; 126 link->rcvfd = dn[0]; 127 } 128 129 /* 130 * Wait for a child process to terminate, and clean up. 131 */ 132 static void 133 collect(struct link * link) 134 { 135 int status; 136 137 close(link->sndfd); 138 close(link->rcvfd); 139 140 if (waitpid(link->pid, &status, 0) != link->pid) e(0); 141 142 if (!WIFEXITED(status)) e(0); 143 else errct += WEXITSTATUS(status); 144 } 145 146 /* 147 * Forcibly terminate a child process, and clean up. 148 */ 149 static void 150 terminate(struct link * link) 151 { 152 int status; 153 154 if (kill(link->pid, SIGKILL) != 0) e(0); 155 156 close(link->sndfd); 157 close(link->rcvfd); 158 159 if (waitpid(link->pid, &status, 0) <= 0) e(0); 160 161 if (WIFSIGNALED(status)) { 162 if (WTERMSIG(status) != SIGKILL) e(0); 163 } else { 164 if (!WIFEXITED(status)) e(0); 165 else errct += WEXITSTATUS(status); 166 } 167 } 168 169 /* 170 * Send an integer value to the child or parent. 171 */ 172 static void 173 snd(struct link * link, int val) 174 { 175 176 if (write(link->sndfd, (void *)&val, sizeof(val)) != sizeof(val)) e(0); 177 } 178 179 /* 180 * Receive an integer value from the child or parent, or -1 on EOF. 181 */ 182 static int 183 rcv(struct link * link) 184 { 185 int r, val; 186 187 if ((r = read(link->rcvfd, (void *)&val, sizeof(val))) == 0) 188 return -1; 189 190 if (r != sizeof(val)) e(0); 191 192 return val; 193 } 194 195 /* 196 * Child procedure that creates semaphore sets. 197 */ 198 static void 199 test_perm_child(struct link * parent) 200 { 201 struct passwd *pw; 202 struct group *gr; 203 struct semid_ds semds; 204 uid_t uid; 205 gid_t gid; 206 int mask, rmask, sugid, id[3]; 207 208 /* 209 * Repeatedly create a number of semaphores with the masks provided by 210 * the parent process. 211 */ 212 while ((mask = rcv(parent)) != -1) { 213 rmask = rcv(parent); 214 sugid = rcv(parent); 215 216 /* 217 * Create the semaphores. For KEY_A, if we are going to set 218 * the mode through IPC_SET anyway, start with a zero mask to 219 * check that the replaced mode is used (thus testing IPC_SET). 220 */ 221 if ((id[0] = semget(KEY_A, 3, 222 IPC_CREAT | IPC_EXCL | 223 ((sugid == SUGID_NONE) ? mask : 0))) == -1) e(0); 224 if ((id[1] = semget(KEY_B, 3, 225 IPC_CREAT | IPC_EXCL | mask | rmask)) == -1) e(0); 226 if ((id[2] = semget(KEY_C, 3, 227 IPC_CREAT | IPC_EXCL | rmask)) == -1) e(0); 228 229 uid = geteuid(); 230 gid = getegid(); 231 if (sugid != SUGID_NONE) { 232 switch (sugid) { 233 case SUGID_ROOT_USER: 234 if ((pw = getpwnam(ROOT_USER)) == NULL) e(0); 235 uid = pw->pw_uid; 236 break; 237 case SUGID_NONROOT_USER: 238 if ((pw = getpwnam(NONROOT_USER)) == NULL) 239 e(0); 240 uid = pw->pw_uid; 241 break; 242 case SUGID_ROOT_GROUP: 243 if ((gr = getgrnam(ROOT_GROUP)) == NULL) e(0); 244 gid = gr->gr_gid; 245 break; 246 case SUGID_NONROOT_GROUP: 247 if ((gr = getgrnam(NONROOT_GROUP)) == NULL) 248 e(0); 249 gid = gr->gr_gid; 250 break; 251 } 252 253 semds.sem_perm.uid = uid; 254 semds.sem_perm.gid = gid; 255 semds.sem_perm.mode = mask; 256 if (semctl(id[0], 0, IPC_SET, &semds) != 0) e(0); 257 semds.sem_perm.mode = mask | rmask; 258 if (semctl(id[1], 0, IPC_SET, &semds) != 0) e(0); 259 semds.sem_perm.mode = rmask; 260 if (semctl(id[2], 0, IPC_SET, &semds) != 0) e(0); 261 } 262 263 /* Do a quick test to confirm the right privileges. */ 264 if (mask & IPC_R) { 265 if (semctl(id[0], 0, IPC_STAT, &semds) != 0) e(0); 266 if (semds.sem_perm.mode != (SEM_ALLOC | mask)) e(0); 267 if (semds.sem_perm.uid != uid) e(0); 268 if (semds.sem_perm.gid != gid) e(0); 269 if (semds.sem_perm.cuid != geteuid()) e(0); 270 if (semds.sem_perm.cgid != getegid()) e(0); 271 } 272 273 snd(parent, id[0]); 274 snd(parent, id[1]); 275 snd(parent, id[2]); 276 277 /* The other child process runs here. */ 278 279 if (rcv(parent) != 0) e(0); 280 281 /* 282 * For owner tests, the other child may already have removed 283 * the semaphore sets, so ignore return values here. 284 */ 285 (void)semctl(id[0], 0, IPC_RMID); 286 (void)semctl(id[1], 0, IPC_RMID); 287 (void)semctl(id[2], 0, IPC_RMID); 288 } 289 } 290 291 /* 292 * Perform a permission test. The given procedure will be called for various 293 * access masks, which it can use to determine whether operations on three 294 * created semaphore sets should succeed or fail. The first two semaphore sets 295 * are created with appropriate privileges, the third one is not. If the 296 * 'owner_test' variable is set, the test will change slightly so as to allow 297 * testing of operations that require a matching uid/cuid. 298 */ 299 static void 300 test_perm(void (* proc)(struct link *), int owner_test) 301 { 302 struct link child1, child2; 303 int n, shift, bit, mask, rmask, drop1, drop2, sugid, id[3]; 304 305 for (n = 0; n < 7; n++) { 306 /* 307 * Child 1 creates the semaphores, and child 2 opens them. 308 * For shift 6 (0700), child 1 drops its privileges to match 309 * child 2's (n=0). For shift 3 (0070), child 2 drops its user 310 * privileges (n=3). For shift 0 (0007), child 2 drops its 311 * group in addition to its user privileges (n=6). Also try 312 * with differing uid/cuid (n=1,2) and gid/cgid (n=4,5), where 313 * the current ownership (n=1,4) or the creator's ownership 314 * (n=2,5) is tested. 315 */ 316 switch (n) { 317 case 0: 318 shift = 6; 319 drop1 = DROP_ALL; 320 drop2 = DROP_ALL; 321 sugid = SUGID_NONE; 322 break; 323 case 1: 324 shift = 6; 325 drop1 = DROP_NONE; 326 drop2 = DROP_ALL; 327 sugid = SUGID_NONROOT_USER; 328 break; 329 case 2: 330 shift = 6; 331 drop1 = DROP_USER; 332 drop2 = DROP_ALL; 333 sugid = SUGID_ROOT_USER; 334 break; 335 case 3: 336 shift = 3; 337 drop1 = DROP_NONE; 338 drop2 = DROP_USER; 339 sugid = SUGID_NONE; 340 break; 341 case 4: 342 shift = 3; 343 drop1 = DROP_NONE; 344 drop2 = DROP_ALL; 345 sugid = SUGID_NONROOT_GROUP; 346 break; 347 case 5: 348 /* The root group has no special privileges. */ 349 shift = 3; 350 drop1 = DROP_NONE; 351 drop2 = DROP_USER; 352 sugid = SUGID_NONROOT_GROUP; 353 break; 354 case 6: 355 shift = 0; 356 drop1 = DROP_NONE; 357 drop2 = DROP_ALL; 358 sugid = SUGID_NONE; 359 break; 360 } 361 362 spawn(&child1, test_perm_child, drop1); 363 spawn(&child2, proc, drop2); 364 365 for (bit = 0; bit <= 7; bit++) { 366 mask = bit << shift; 367 rmask = 0777 & ~(7 << shift); 368 369 snd(&child1, mask); 370 snd(&child1, rmask); 371 snd(&child1, sugid); 372 id[0] = rcv(&child1); 373 id[1] = rcv(&child1); 374 id[2] = rcv(&child1); 375 376 snd(&child2, (owner_test) ? shift : bit); 377 snd(&child2, id[0]); 378 snd(&child2, id[1]); 379 snd(&child2, id[2]); 380 if (rcv(&child2) != 0) e(0); 381 382 snd(&child1, 0); 383 } 384 385 /* We use a bitmask of -1 to terminate the children. */ 386 snd(&child1, -1); 387 snd(&child2, -1); 388 389 collect(&child1); 390 collect(&child2); 391 } 392 } 393 394 /* 395 * Test semget(2) permission checks. Please note that the checks are advisory: 396 * nothing keeps a process from opening a semaphore set with fewer privileges 397 * than required by the operations the process subsequently issues on the set. 398 */ 399 static void 400 test88a_perm(struct link * parent) 401 { 402 int r, tbit, bit, mask, id[3]; 403 404 while ((tbit = rcv(parent)) != -1) { 405 id[0] = rcv(parent); 406 id[1] = rcv(parent); 407 id[2] = rcv(parent); 408 409 /* 410 * We skip setting lower bits, as it is not clear what effect 411 * that should have. We assume that zero bits should result in 412 * failure. 413 */ 414 for (bit = 0; bit <= 7; bit++) { 415 mask = bit << 6; 416 417 /* 418 * Opening semaphore set A must succeed iff the given 419 * bits are all set in the relevant three-bit section 420 * of the creation mask. 421 */ 422 r = semget(KEY_A, 0, mask); 423 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 424 if ((bit != 0 && (bit & tbit) == bit) != (r != -1)) 425 e(0); 426 if (r != -1 && r != id[0]) e(0); 427 428 /* 429 * Same for semaphore set B, which was created with all 430 * irrelevant mode bits inverted. 431 */ 432 r = semget(KEY_B, 0, mask); 433 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 434 if ((bit != 0 && (bit & tbit) == bit) != (r != -1)) 435 e(0); 436 if (r != -1 && r != id[1]) e(0); 437 438 /* 439 * Semaphore set C was created with only irrelevant 440 * mode bits set, so opening it must always fail. 441 */ 442 if (semget(KEY_C, 0, mask) != -1) e(0); 443 if (errno != EACCES) e(0); 444 } 445 446 snd(parent, 0); 447 } 448 } 449 450 /* 451 * Test the basic semget(2) functionality. 452 */ 453 static void 454 test88a(void) 455 { 456 struct seminfo seminfo; 457 struct semid_ds semds; 458 time_t now; 459 unsigned int i, j; 460 int id[3], *idp; 461 462 subtest = 0; 463 464 /* 465 * The key IPC_PRIVATE must always yield a new semaphore set identifier 466 * regardless of whether IPC_CREAT and IPC_EXCL are supplied. 467 */ 468 if ((id[0] = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600)) < 0) e(0); 469 470 if ((id[1] = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0600)) < 0) 471 e(0); 472 473 if ((id[2] = semget(IPC_PRIVATE, 1, 0600)) < 0) e(0); 474 475 if (id[0] == id[1]) e(0); 476 if (id[1] == id[2]) e(0); 477 if (id[0] == id[2]) e(0); 478 479 if (semctl(id[0], 0, IPC_RMID) != 0) e(0); 480 if (semctl(id[1], 0, IPC_RMID) != 0) e(0); 481 if (semctl(id[2], 0, IPC_RMID) != 0) e(0); 482 483 /* Remove any leftovers from previous test runs. */ 484 if ((id[0] = semget(KEY_A, 0, 0600)) >= 0 && 485 semctl(id[0], 0, IPC_RMID) == -1) e(0); 486 if ((id[0] = semget(KEY_B, 0, 0600)) >= 0 && 487 semctl(id[0], 0, IPC_RMID) == -1) e(0); 488 489 /* 490 * For non-IPC_PRIVATE keys, open(2)-like semantics apply with respect 491 * to IPC_CREAT and IPC_EXCL flags. The behavior of supplying IPC_EXCL 492 * without IPC_CREAT is undefined, so we do not test for that here. 493 */ 494 if (semget(KEY_A, 1, 0600) != -1) e(0); 495 if (errno != ENOENT); 496 497 if ((id[0] = semget(KEY_A, 1, IPC_CREAT | IPC_EXCL | 0600)) < 0) e(0); 498 499 if (semget(KEY_B, 1, 0600) != -1) e(0); 500 if (errno != ENOENT); 501 502 if ((id[1] = semget(KEY_B, 1, IPC_CREAT | 0600)) < 0) e(0); 503 504 if (id[0] == id[1]) e(0); 505 506 if ((id[2] = semget(KEY_A, 1, 0600)) < 0) e(0); 507 if (id[2] != id[0]) e(0); 508 509 if ((id[2] = semget(KEY_B, 1, IPC_CREAT | 0600)) < 0) e(0); 510 if (id[2] != id[2]) e(0); 511 512 if (semget(KEY_A, 1, IPC_CREAT | IPC_EXCL | 0600) != -1) e(0); 513 if (errno != EEXIST) e(0); 514 515 if (semctl(id[0], 0, IPC_RMID) != 0) e(0); 516 if (semctl(id[1], 0, IPC_RMID) != 0) e(0); 517 518 /* 519 * Check that we get the right error when we run out of semaphore sets. 520 * It is possible that other processes in the system are using sets 521 * right now, so see if we can anywhere from three (the number we had 522 * already) to SEMMNI semaphore sets, and check for ENOSPC after that. 523 */ 524 if (semctl(0, 0, IPC_INFO, &seminfo) == -1) e(0); 525 if (seminfo.semmni < 3 || seminfo.semmni > USHRT_MAX) e(0); 526 527 if ((idp = malloc(sizeof(int) * (seminfo.semmni + 1))) == NULL) e(0); 528 529 for (i = 0; i < seminfo.semmni + 1; i++) { 530 if ((idp[i] = semget(KEY_A + i, 1, IPC_CREAT | 0600)) < 0) 531 break; 532 533 /* Ensure that there are no ID collisions. O(n**2). */ 534 for (j = 0; j < i; j++) 535 if (idp[i] == idp[j]) e(0); 536 } 537 538 if (errno != ENOSPC) e(0); 539 if (i < 3) e(0); 540 if (i == seminfo.semmni + 1) e(0); 541 542 while (i-- > 0) 543 if (semctl(idp[i], 0, IPC_RMID) != 0) e(0); 544 545 free(idp); 546 547 /* 548 * The given number of semaphores must be within bounds. 549 */ 550 if (semget(KEY_A, -1, IPC_CREAT | 0600) != -1) e(0); 551 if (errno != EINVAL) e(0); 552 553 if (semget(KEY_A, 0, IPC_CREAT | 0600) != -1) e(0); 554 if (errno != EINVAL) e(0); 555 556 if (seminfo.semmsl < 3 || seminfo.semmsl > USHRT_MAX) e(0); 557 if (semget(KEY_A, seminfo.semmsl + 1, IPC_CREAT | 0600) != -1) e(0); 558 if (errno != EINVAL) e(0); 559 560 if ((id[0] = semget(KEY_A, seminfo.semmsl, IPC_CREAT | 0600)) < 0) 561 e(0); 562 if (semctl(id[0], 0, IPC_RMID) != 0) e(0); 563 564 if ((id[0] = semget(KEY_A, 2, IPC_CREAT | 0600)) < 0) e(0); 565 566 if ((id[1] = semget(KEY_A, 0, 0600)) < 0) e(0); 567 if (id[0] != id[1]) e(0); 568 569 if ((id[1] = semget(KEY_A, 1, 0600)) < 0) e(0); 570 if (id[0] != id[1]) e(0); 571 572 if ((id[1] = semget(KEY_A, 2, 0600)) < 0) e(0); 573 if (id[0] != id[1]) e(0); 574 575 if ((id[1] = semget(KEY_A, 3, 0600)) != -1) e(0); 576 if (errno != EINVAL) e(0); 577 578 if ((id[1] = semget(KEY_A, seminfo.semmsl + 1, 0600)) != -1) e(0); 579 if (errno != EINVAL) e(0); 580 581 if (semctl(id[0], 0, IPC_RMID) != 0) e(0); 582 583 /* 584 * Verify that the initial values for the semaphore set are as 585 * expected. 586 */ 587 time(&now); 588 if (seminfo.semmns < 3 + seminfo.semmsl) e(0); 589 if ((id[0] = semget(IPC_PRIVATE, 3, IPC_CREAT | IPC_EXCL | 0642)) < 0) 590 e(0); 591 if ((id[1] = semget(KEY_A, seminfo.semmsl, IPC_CREAT | 0613)) < 0) 592 e(0); 593 594 if (semctl(id[0], 0, IPC_STAT, &semds) != 0) e(0); 595 if (semds.sem_perm.uid != geteuid()) e(0); 596 if (semds.sem_perm.gid != getegid()) e(0); 597 if (semds.sem_perm.cuid != geteuid()) e(0); 598 if (semds.sem_perm.cgid != getegid()) e(0); 599 if (semds.sem_perm.mode != (SEM_ALLOC | 0642)) e(0); 600 if (semds.sem_perm._key != IPC_PRIVATE) e(0); 601 if (semds.sem_nsems != 3) e(0); 602 if (semds.sem_otime != 0) e(0); 603 if (semds.sem_ctime < now || semds.sem_ctime >= now + 10) e(0); 604 605 for (i = 0; i < semds.sem_nsems; i++) 606 TEST_SEM(id[0], i, 0, 0, 0, 0); 607 608 if (semctl(id[1], 0, IPC_STAT, &semds) != 0) e(0); 609 if (semds.sem_perm.uid != geteuid()) e(0); 610 if (semds.sem_perm.gid != getegid()) e(0); 611 if (semds.sem_perm.cuid != geteuid()) e(0); 612 if (semds.sem_perm.cgid != getegid()) e(0); 613 if (semds.sem_perm.mode != (SEM_ALLOC | 0613)) e(0); 614 if (semds.sem_perm._key != KEY_A) e(0); 615 if (semds.sem_nsems != seminfo.semmsl) e(0); 616 if (semds.sem_otime != 0) e(0); 617 if (semds.sem_ctime < now || semds.sem_ctime >= now + 10) e(0); 618 619 for (i = 0; i < semds.sem_nsems; i++) 620 TEST_SEM(id[1], i, 0, 0, 0, 0); 621 622 if (semctl(id[1], 0, IPC_RMID) != 0) e(0); 623 if (semctl(id[0], 0, IPC_RMID) != 0) e(0); 624 625 /* 626 * Finally, perform a number of permission-related checks. Since the 627 * main test program is running with superuser privileges, most of the 628 * permission tests use an unprivileged child process. 629 */ 630 /* The superuser can always open and destroy a semaphore set. */ 631 if ((id[0] = semget(KEY_A, 1, IPC_CREAT | IPC_EXCL | 0000)) < 0) e(0); 632 633 if ((id[1] = semget(KEY_A, 0, 0600)) < 0) e(0); 634 if (id[0] != id[1]) e(0); 635 636 if ((id[1] = semget(KEY_A, 0, 0000)) < 0) e(0); 637 if (id[0] != id[1]) e(0); 638 639 if (semctl(id[0], 0, IPC_RMID) != 0) e(0); 640 641 /* 642 * When an unprivileged process tries to open a semaphore set, the 643 * given upper three permission bits from the mode (0700) are tested 644 * against the appropriate permission bits from the semaphore set. 645 */ 646 test_perm(test88a_perm, 0 /*owner_test*/); 647 } 648 649 /* 650 * Test semop(2) permission checks. 651 */ 652 static void 653 test88b_perm(struct link * parent) 654 { 655 struct sembuf sops[2]; 656 size_t nsops; 657 int i, r, tbit, bit, id[3]; 658 659 while ((tbit = rcv(parent)) != -1) { 660 id[0] = rcv(parent); 661 id[1] = rcv(parent); 662 id[2] = rcv(parent); 663 664 /* 665 * This loop is designed such that failure of any bit-based 666 * subset will not result in subsequent operations blocking. 667 */ 668 for (i = 0; i < 8; i++) { 669 memset(sops, 0, sizeof(sops)); 670 671 switch (i) { 672 case 0: 673 nsops = 1; 674 bit = 4; 675 break; 676 case 1: 677 sops[0].sem_op = 1; 678 nsops = 1; 679 bit = 2; 680 break; 681 case 2: 682 sops[0].sem_op = -1; 683 nsops = 1; 684 bit = 2; 685 break; 686 case 3: 687 sops[1].sem_op = 1; 688 nsops = 2; 689 bit = 6; 690 break; 691 case 4: 692 sops[0].sem_num = 1; 693 sops[1].sem_op = -1; 694 nsops = 2; 695 bit = 6; 696 break; 697 case 5: 698 sops[1].sem_num = 1; 699 nsops = 2; 700 bit = 4; 701 break; 702 case 6: 703 /* 704 * Two operations on the same semaphore. As 705 * such, this verifies that operations are 706 * processed in array order. 707 */ 708 sops[0].sem_op = 1; 709 sops[1].sem_op = -1; 710 nsops = 2; 711 bit = 2; 712 break; 713 case 7: 714 /* 715 * Test the order of checks. Since IPC_STAT 716 * requires read permission, it is reasonable 717 * that the check against sem_nsems be done 718 * only after the permission check as well. 719 * For this test we rewrite EFBIG to OK below. 720 */ 721 sops[0].sem_num = USHRT_MAX; 722 nsops = 2; 723 bit = 4; 724 break; 725 } 726 727 r = semop(id[0], sops, nsops); 728 if (i == 7 && r == -1 && errno == EFBIG) r = 0; 729 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 730 if (((bit & tbit) == bit) != (r != -1)) e(0); 731 732 r = semop(id[1], sops, nsops); 733 if (i == 7 && r == -1 && errno == EFBIG) r = 0; 734 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 735 if (((bit & tbit) == bit) != (r != -1)) e(0); 736 737 if (semop(id[2], sops, nsops) != -1) e(0); 738 if (errno != EACCES) e(0); 739 } 740 741 snd(parent, 0); 742 } 743 } 744 745 /* 746 * Signal handler. 747 */ 748 static void 749 got_signal(int sig) 750 { 751 752 if (sig != SIGHUP) e(0); 753 if (nr_signals != 0) e(0); 754 nr_signals++; 755 } 756 757 /* 758 * Child process for semop(2) tests, mainly testing blocking operations. 759 */ 760 static void 761 test88b_child(struct link * parent) 762 { 763 struct sembuf sops[5]; 764 struct sigaction act; 765 int id; 766 767 id = rcv(parent); 768 769 memset(sops, 0, sizeof(sops)); 770 if (semop(id, sops, 1) != 0) e(0); 771 772 if (rcv(parent) != 1) e(0); 773 774 sops[0].sem_op = -3; 775 if (semop(id, sops, 1) != 0) e(0); 776 777 if (rcv(parent) != 2) e(0); 778 779 sops[0].sem_num = 2; 780 sops[0].sem_op = 2; 781 sops[1].sem_num = 1; 782 sops[1].sem_op = -1; 783 sops[2].sem_num = 0; 784 sops[2].sem_op = 1; 785 if (semop(id, sops, 3) != 0) e(0); 786 787 if (rcv(parent) != 3) e(0); 788 789 sops[0].sem_num = 1; 790 sops[0].sem_op = 0; 791 sops[1].sem_num = 1; 792 sops[1].sem_op = 1; 793 sops[2].sem_num = 0; 794 sops[2].sem_op = 0; 795 sops[3].sem_num = 2; 796 sops[3].sem_op = 0; 797 sops[4].sem_num = 2; 798 sops[4].sem_op = 1; 799 if (semop(id, sops, 5) != 0) e(0); 800 801 if (rcv(parent) != 4) e(0); 802 803 sops[0].sem_num = 1; 804 sops[0].sem_op = -2; 805 sops[1].sem_num = 2; 806 sops[1].sem_op = 0; 807 if (semop(id, sops, 2) != 0) e(0); 808 809 if (rcv(parent) != 5) e(0); 810 811 sops[0].sem_num = 0; 812 sops[0].sem_op = -1; 813 sops[1].sem_num = 1; 814 sops[1].sem_op = -1; 815 sops[1].sem_flg = IPC_NOWAIT; 816 if (semop(id, sops, 2) != 0) e(0); 817 818 if (rcv(parent) != 6) e(0); 819 820 sops[0].sem_num = 1; 821 sops[0].sem_op = 0; 822 sops[1].sem_num = 0; 823 sops[1].sem_op = 0; 824 sops[1].sem_flg = IPC_NOWAIT; 825 if (semop(id, sops, 2) != -1) e(0); 826 if (errno != EAGAIN) e(0); 827 828 if (rcv(parent) != 7) e(0); 829 830 sops[0].sem_num = 0; 831 sops[0].sem_op = 0; 832 sops[1].sem_num = 1; 833 sops[1].sem_op = 1; 834 sops[1].sem_flg = 0; 835 if (semop(id, sops, 2) != 0) e(0); 836 837 if (rcv(parent) != 8) e(0); 838 839 sops[0].sem_num = 0; 840 sops[0].sem_op = -1; 841 sops[1].sem_num = 1; 842 sops[1].sem_op = 2; 843 if (semop(id, sops, 2) != -1) e(0); 844 if (errno != ERANGE) e(0); 845 846 memset(&act, 0, sizeof(act)); 847 act.sa_handler = got_signal; 848 sigfillset(&act.sa_mask); 849 if (sigaction(SIGHUP, &act, NULL) != 0) e(0); 850 851 if (rcv(parent) != 9) e(0); 852 853 memset(sops, 0, sizeof(sops)); 854 sops[0].sem_num = 0; 855 sops[0].sem_op = 0; 856 sops[1].sem_num = 0; 857 sops[1].sem_op = 1; 858 sops[2].sem_num = 1; 859 sops[2].sem_op = 0; 860 if (semop(id, sops, 3) != -1) 861 if (errno != EINTR) e(0); 862 if (nr_signals != 1) e(0); 863 864 TEST_SEM(id, 0, 0, parent->pid, 0, 0); 865 TEST_SEM(id, 1, 1, parent->pid, 0, 0); 866 867 if (rcv(parent) != 10) e(0); 868 869 memset(sops, 0, sizeof(sops)); 870 sops[0].sem_op = -3; 871 if (semop(id, sops, 1) != -1) e(0); 872 if (errno != EIDRM) e(0); 873 874 id = rcv(parent); 875 876 sops[0].sem_num = 0; 877 sops[0].sem_op = -1; 878 sops[1].sem_num = 1; 879 sops[1].sem_op = 1; 880 if (semop(id, sops, 2) != -1) e(0); 881 if (errno != ERANGE) e(0); 882 883 if (rcv(parent) != 11) e(0); 884 885 sops[0].sem_num = 1; 886 sops[0].sem_op = 0; 887 sops[1].sem_num = 0; 888 sops[1].sem_op = -1; 889 if (semop(id, sops, 2) != 0) e(0); 890 891 id = rcv(parent); 892 893 sops[0].sem_num = 0; 894 sops[0].sem_op = -1; 895 sops[1].sem_num = 1; 896 sops[1].sem_op = 0; 897 if (semop(id, sops, 2) != 0) e(0); 898 899 snd(parent, errct); 900 if (rcv(parent) != 12) e(0); 901 902 /* The child will be killed during this call. It should not return. */ 903 sops[0].sem_num = 1; 904 sops[0].sem_op = -1; 905 sops[1].sem_num = 0; 906 sops[1].sem_op = 3; 907 (void)semop(id, sops, 2); 908 909 e(0); 910 } 911 912 /* 913 * Test the basic semop(2) functionality. 914 */ 915 static void 916 test88b(void) 917 { 918 struct seminfo seminfo; 919 struct semid_ds semds; 920 struct sembuf *sops, *sops2; 921 size_t size; 922 struct link child; 923 time_t now; 924 unsigned short val[2]; 925 int id; 926 927 subtest = 1; 928 929 /* Allocate a buffer for operations. */ 930 if (semctl(0, 0, IPC_INFO, &seminfo) == -1) e(0); 931 932 if (seminfo.semopm < 3 || seminfo.semopm > USHRT_MAX) e(0); 933 934 size = sizeof(sops[0]) * (seminfo.semopm + 1); 935 if ((sops = malloc(size)) == NULL) e(0); 936 memset(sops, 0, size); 937 938 /* Do a few first tests with a set containing one semaphore. */ 939 if ((id = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600)) == -1) e(0); 940 941 /* If no operations are given, the call should succeed. */ 942 if (semop(id, NULL, 0) != 0) e(0); 943 944 /* 945 * If any operations are given, the pointer must be valid. Moreover, 946 * partially valid buffers must never be processed partially. 947 */ 948 if (semop(id, NULL, 1) != -1) e(0); 949 if (errno != EFAULT) e(0); 950 951 if (semop(id, bad_ptr, 1) != -1) e(0); 952 if (errno != EFAULT) e(0); 953 954 memset(page_ptr, 0, page_size); 955 sops2 = ((struct sembuf *)bad_ptr) - 1; 956 sops2->sem_op = 1; 957 if (semop(id, sops2, 2) != -1) e(0); 958 if (errno != EFAULT) e(0); 959 960 TEST_SEM(id, 0, 0, 0, 0, 0); 961 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 962 if (semds.sem_otime != 0) e(0); 963 964 /* 965 * A new semaphore set is initialized to an all-zeroes state, and a 966 * zeroed operation tests for a zeroed semaphore. This should pass. 967 */ 968 time(&now); 969 if (semop(id, sops, 1) != 0) e(0); 970 971 TEST_SEM(id, 0, 0, getpid(), 0, 0); 972 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 973 if (semds.sem_otime < now || semds.sem_otime >= now + 10) e(0); 974 975 /* Test the limit on the number of operations. */ 976 if (semop(id, sops, seminfo.semopm) != 0) e(0); 977 978 if (semop(id, sops, seminfo.semopm + 1) != -1) e(0); 979 if (errno != E2BIG) e(0); 980 981 if (semop(id, sops, SIZE_MAX) != -1) e(0); 982 if (errno != E2BIG) e(0); 983 984 /* Test the range check on the semaphore numbers. */ 985 sops[1].sem_num = 1; 986 if (semop(id, sops, 2) != -1) e(0); 987 if (errno != EFBIG) e(0); 988 989 sops[1].sem_num = USHRT_MAX; 990 if (semop(id, sops, 2) != -1) e(0); 991 if (errno != EFBIG) e(0); 992 993 /* 994 * Test nonblocking operations on a single semaphore, starting with 995 * value limit and overflow cases. 996 */ 997 if (seminfo.semvmx < 3 || seminfo.semvmx > SHRT_MAX) e(0); 998 999 sops[0].sem_flg = IPC_NOWAIT; 1000 1001 /* This block does not trigger on MINIX3. */ 1002 if (seminfo.semvmx < SHRT_MAX) { 1003 sops[0].sem_op = seminfo.semvmx + 1; 1004 if (semop(id, sops, 1) != -1) e(0); 1005 if (errno != ERANGE) e(0); 1006 if (semctl(id, 0, GETVAL) != 0) e(0); 1007 } 1008 1009 sops[0].sem_op = seminfo.semvmx; 1010 if (semop(id, sops, 1) != 0) e(0); 1011 if (semctl(id, 0, GETVAL) != seminfo.semvmx) e(0); 1012 1013 /* As of writing, the proper checks for this is missing on NetBSD. */ 1014 sops[0].sem_op = 1; 1015 if (semop(id, sops, 1) != -1) e(0); 1016 if (errno != ERANGE) e(0); 1017 if (semctl(id, 0, GETVAL) != seminfo.semvmx) e(0); 1018 1019 sops[0].sem_op = seminfo.semvmx; 1020 if (semop(id, sops, 1) != -1) e(0); 1021 if (errno != ERANGE) e(0); 1022 if (semctl(id, 0, GETVAL) != seminfo.semvmx) e(0); 1023 1024 sops[0].sem_op = SHRT_MAX; 1025 if (semop(id, sops, 1) != -1) e(0); 1026 if (errno != ERANGE) e(0); 1027 if (semctl(id, 0, GETVAL) != seminfo.semvmx) e(0); 1028 1029 /* This block does trigger on MINIX3. */ 1030 if (seminfo.semvmx < -(int)SHRT_MIN) { 1031 sops[0].sem_op = -seminfo.semvmx - 1; 1032 if (semop(id, sops, 1) != -1) e(0); 1033 if (errno != EAGAIN) e(0); 1034 if (semctl(id, 0, GETVAL) != seminfo.semvmx) e(0); 1035 } 1036 1037 sops[0].sem_op = -seminfo.semvmx; 1038 if (semop(id, sops, 1) != 0) e(0); 1039 if (semctl(id, 0, GETVAL) != 0) e(0); 1040 1041 /* 1042 * Test basic nonblocking operations on a single semaphore. 1043 */ 1044 sops[0].sem_op = 0; 1045 if (semop(id, sops, 1) != 0) e(0); 1046 1047 sops[0].sem_op = 2; 1048 if (semop(id, sops, 1) != 0) e(0); 1049 if (semctl(id, 0, GETVAL) != 2) e(0); 1050 1051 sops[0].sem_op = 0; 1052 if (semop(id, sops, 1) != -1) e(0); 1053 if (errno != EAGAIN) e(0); 1054 1055 sops[0].sem_op = -3; 1056 if (semop(id, sops, 1) != -1) e(0); 1057 if (errno != EAGAIN) e(0); 1058 1059 sops[0].sem_op = 1; 1060 if (semop(id, sops, 1) != 0) e(0); 1061 if (semctl(id, 0, GETVAL) != 3) e(0); 1062 1063 sops[0].sem_op = -1; 1064 if (semop(id, sops, 1) != 0) e(0); 1065 if (semctl(id, 0, GETVAL) != 2) e(0); 1066 1067 sops[0].sem_op = 0; 1068 if (semop(id, sops, 1) != -1) e(0); 1069 if (errno != EAGAIN) e(0); 1070 1071 sops[0].sem_op = -2; 1072 if (semop(id, sops, 1) != 0) e(0); 1073 if (semctl(id, 0, GETVAL) != 0) e(0); 1074 1075 sops[0].sem_op = 0; 1076 if (semop(id, sops, 1) != 0) e(0); 1077 1078 /* Make sure that not too much data is being read in. */ 1079 sops2->sem_op = 0; 1080 sops2--; 1081 if (semop(id, sops2, 2) != 0) e(0); 1082 1083 /* Even if no operations are given, the identifier must be valid. */ 1084 if (semctl(id, 0, IPC_RMID) != 0) e(0); 1085 1086 if (semop(id, NULL, 0) != -1) e(0); 1087 if (errno != EINVAL) e(0); 1088 1089 if (semop(-1, NULL, 0) != -1) e(0); 1090 if (errno != EINVAL) e(0); 1091 1092 if (semop(INT_MIN, NULL, 0) != -1) e(0); 1093 if (errno != EINVAL) e(0); 1094 1095 memset(&semds, 0, sizeof(semds)); 1096 id = IXSEQ_TO_IPCID(seminfo.semmni, semds.sem_perm); 1097 if (semop(id, NULL, 0) != -1) e(0); 1098 if (errno != EINVAL) e(0); 1099 1100 /* 1101 * Test permission checks. As part of this, test basic nonblocking 1102 * multi-operation calls, including operation processing in array order 1103 * and the order of (permission vs other) checks. 1104 */ 1105 test_perm(test88b_perm, 0 /*owner_test*/); 1106 1107 /* 1108 * Test blocking operations, starting with a single blocking operation. 1109 */ 1110 if ((id = semget(IPC_PRIVATE, 3, 0600)) == -1) e(0); 1111 1112 memset(sops, 0, sizeof(sops[0])); 1113 sops[0].sem_op = 1; 1114 if (semop(id, sops, 1) != 0) e(0); 1115 1116 TEST_SEM(id, 0, 1, getpid(), 0, 0); 1117 1118 spawn(&child, test88b_child, DROP_NONE); 1119 1120 snd(&child, id); 1121 1122 /* 1123 * In various places, we have to sleep in order to allow the child to 1124 * get itself blocked in a semop(2) call. 1125 */ 1126 usleep(WAIT_USECS); 1127 1128 TEST_SEM(id, 0, 1, getpid(), 0, 1); 1129 1130 sops[0].sem_op = -1; 1131 if (semop(id, sops, 1) != 0) e(0); 1132 1133 usleep(WAIT_USECS); 1134 1135 TEST_SEM(id, 0, 0, child.pid, 0, 0); 1136 1137 sops[0].sem_op = 1; 1138 if (semop(id, sops, 1) != 0) e(0); 1139 1140 TEST_SEM(id, 0, 1, getpid(), 0, 0); 1141 1142 snd(&child, 1); 1143 1144 usleep(WAIT_USECS); 1145 1146 TEST_SEM(id, 0, 1, getpid(), 1, 0); 1147 1148 /* This should cause a (fruitless) retry of the blocking operation. */ 1149 sops[0].sem_op = 1; 1150 if (semop(id, sops, 1) != 0) e(0); 1151 1152 usleep(WAIT_USECS); 1153 1154 TEST_SEM(id, 0, 2, getpid(), 1, 0); 1155 1156 sops[0].sem_op = 1; 1157 if (semop(id, sops, 1) != 0) e(0); 1158 1159 usleep(WAIT_USECS); 1160 1161 TEST_SEM(id, 0, 0, child.pid, 0, 0); 1162 1163 /* 1164 * Test blocking operations, verifying the correct operation of 1165 * multiple (partially) blocking operations and atomicity. 1166 */ 1167 memset(sops, 0, sizeof(sops[0]) * 2); 1168 if (semop(id, sops, 1) != 0) e(0); 1169 1170 /* One blocking operation. */ 1171 snd(&child, 2); 1172 1173 usleep(WAIT_USECS); 1174 1175 TEST_SEM(id, 0, 0, getpid(), 0, 0); 1176 TEST_SEM(id, 1, 0, 0, 1, 0); 1177 TEST_SEM(id, 2, 0, 0, 0, 0); 1178 1179 sops[0].sem_num = 1; 1180 sops[0].sem_op = 1; 1181 if (semop(id, sops, 1) != 0) e(0); 1182 1183 usleep(WAIT_USECS); 1184 1185 TEST_SEM(id, 0, 1, child.pid, 0, 0); 1186 TEST_SEM(id, 1, 0, child.pid, 0, 0); 1187 TEST_SEM(id, 2, 2, child.pid, 0, 0); 1188 1189 /* Two blocking operations in one call, resolved at once. */ 1190 snd(&child, 3); 1191 1192 usleep(WAIT_USECS); 1193 1194 TEST_SEM(id, 0, 1, child.pid, 0, 1); 1195 TEST_SEM(id, 1, 0, child.pid, 0, 0); 1196 TEST_SEM(id, 2, 2, child.pid, 0, 0); 1197 1198 sops[0].sem_num = 0; 1199 sops[0].sem_op = -1; 1200 sops[1].sem_num = 2; 1201 sops[1].sem_op = -2; 1202 if (semop(id, sops, 2) != 0) e(0); 1203 1204 usleep(WAIT_USECS); 1205 1206 TEST_SEM(id, 0, 0, child.pid, 0, 0); 1207 TEST_SEM(id, 1, 1, child.pid, 0, 0); 1208 TEST_SEM(id, 2, 1, child.pid, 0, 0); 1209 1210 /* Two blocking operations in one call, resolved one by one. */ 1211 snd(&child, 4); 1212 1213 usleep(WAIT_USECS); 1214 1215 TEST_SEM(id, 0, 0, child.pid, 0, 0); 1216 TEST_SEM(id, 1, 1, child.pid, 1, 0); 1217 TEST_SEM(id, 2, 1, child.pid, 0, 0); 1218 1219 sops[0].sem_num = 1; 1220 sops[0].sem_op = 1; 1221 if (semop(id, sops, 1) != 0) e(0); 1222 1223 usleep(WAIT_USECS); 1224 1225 TEST_SEM(id, 0, 0, child.pid, 0, 0); 1226 TEST_SEM(id, 1, 2, getpid(), 0, 0); 1227 TEST_SEM(id, 2, 1, child.pid, 0, 1); 1228 1229 sops[0].sem_num = 2; 1230 sops[0].sem_op = -1; 1231 if (semop(id, sops, 1) != 0) e(0); 1232 1233 usleep(WAIT_USECS); 1234 1235 TEST_SEM(id, 0, 0, child.pid, 0, 0); 1236 TEST_SEM(id, 1, 0, child.pid, 0, 0); 1237 TEST_SEM(id, 2, 0, child.pid, 0, 0); 1238 1239 /* One blocking op followed by a nonblocking one, cleared at once. */ 1240 sops[0].sem_num = 0; 1241 sops[0].sem_op = 0; 1242 sops[1].sem_num = 1; 1243 sops[1].sem_op = 0; 1244 if (semop(id, sops, 2) != 0) e(0); 1245 1246 snd(&child, 5); 1247 1248 usleep(WAIT_USECS); 1249 1250 TEST_SEM(id, 0, 0, getpid(), 1, 0); 1251 TEST_SEM(id, 1, 0, getpid(), 0, 0); 1252 1253 sops[0].sem_num = 0; 1254 sops[0].sem_op = 1; 1255 sops[1].sem_num = 1; 1256 sops[1].sem_op = 1; 1257 if (semop(id, sops, 2) != 0) e(0); 1258 1259 usleep(WAIT_USECS); 1260 1261 TEST_SEM(id, 0, 0, child.pid, 0, 0); 1262 TEST_SEM(id, 1, 0, child.pid, 0, 0); 1263 1264 /* One blocking op followed by a nonblocking one, only one cleared. */ 1265 sops[0].sem_num = 0; 1266 sops[0].sem_op = 1; 1267 sops[1].sem_num = 1; 1268 sops[1].sem_op = 1; 1269 if (semop(id, sops, 2) != 0) e(0); 1270 1271 snd(&child, 6); 1272 1273 usleep(WAIT_USECS); 1274 1275 TEST_SEM(id, 0, 1, getpid(), 0, 0); 1276 TEST_SEM(id, 1, 1, getpid(), 0, 1); 1277 1278 sops[0].sem_num = 1; 1279 sops[0].sem_op = -1; 1280 if (semop(id, sops, 1) != 0) e(0); 1281 1282 usleep(WAIT_USECS); 1283 1284 TEST_SEM(id, 0, 1, getpid(), 0, 0); 1285 TEST_SEM(id, 1, 0, getpid(), 0, 0); 1286 1287 /* 1288 * Ensure that all semaphore numbers are checked immediately, which 1289 * given the earlier test results also implies that permissions are 1290 * checked immediately (so we don't have to recheck that too). We do 1291 * not check whether permissions are rechecked after a blocking 1292 * operation, because the specification does not describe the intended 1293 * behavior on this point. 1294 */ 1295 sops[0].sem_num = 0; 1296 sops[0].sem_op = 0; 1297 sops[1].sem_num = 4; 1298 sops[1].sem_op = 0; 1299 if (semop(id, sops, 2) != -1) e(0); 1300 if (errno != EFBIG) e(0); 1301 1302 /* 1303 * Ensure that semaphore value overflow is detected properly, at the 1304 * moment that the operation is actually processed. 1305 */ 1306 sops[0].sem_num = 1; 1307 sops[0].sem_op = seminfo.semvmx; 1308 if (semop(id, sops, 1) != 0) e(0); 1309 1310 snd(&child, 7); 1311 1312 usleep(WAIT_USECS); 1313 1314 TEST_SEM(id, 0, 1, getpid(), 0, 1); 1315 TEST_SEM(id, 1, seminfo.semvmx, getpid(), 0, 0); 1316 1317 sops[0].sem_num = 0; 1318 sops[0].sem_op = -1; 1319 sops[1].sem_num = 1; 1320 sops[1].sem_op = -1; 1321 if (semop(id, sops, 2) != 0) e(0); 1322 1323 TEST_SEM(id, 0, 0, child.pid, 0, 0); 1324 TEST_SEM(id, 1, seminfo.semvmx, child.pid, 0, 0); 1325 1326 sops[0].sem_num = 1; 1327 sops[0].sem_op = -2; 1328 if (semop(id, sops, 1) != 0) e(0); 1329 1330 snd(&child, 8); 1331 1332 usleep(WAIT_USECS); 1333 1334 TEST_SEM(id, 0, 0, child.pid, 1, 0); 1335 TEST_SEM(id, 1, seminfo.semvmx - 2, getpid(), 0, 0); 1336 1337 sops[0].sem_num = 0; 1338 sops[0].sem_op = 1; 1339 sops[1].sem_num = 1; 1340 sops[1].sem_op = 1; 1341 if (semop(id, sops, 2) != 0) e(0); 1342 1343 TEST_SEM(id, 0, 1, getpid(), 0, 0); 1344 TEST_SEM(id, 1, seminfo.semvmx - 1, getpid(), 0, 0); 1345 1346 sops[0].sem_num = 0; 1347 sops[0].sem_op = seminfo.semvmx - 1; 1348 sops[1].sem_num = 0; 1349 sops[1].sem_op = seminfo.semvmx - 1; 1350 sops[2].sem_num = 0; 1351 sops[2].sem_op = 2; 1352 /* 1353 * With the current SEMVMX, the sum of the values is now USHRT_MAX-1, 1354 * which if processed could result in a zero semaphore value. That 1355 * should not happen. Looking at you, NetBSD. 1356 */ 1357 if (semop(id, sops, 3) != -1) e(0); 1358 if (errno != ERANGE) e(0); 1359 1360 TEST_SEM(id, 0, 1, getpid(), 0, 0); 1361 1362 /* 1363 * Check that a blocking semop(2) call fails with EINTR if a signal is 1364 * caught by the process after the call has blocked. 1365 */ 1366 if (semctl(id, 1, SETVAL, 0) != 0) e(0); 1367 sops[0].sem_num = 0; 1368 sops[0].sem_op = -1; 1369 sops[1].sem_num = 1; 1370 sops[1].sem_op = 1; 1371 if (semop(id, sops, 2) != 0) e(0); 1372 1373 TEST_SEM(id, 0, 0, getpid(), 0, 0); 1374 TEST_SEM(id, 1, 1, getpid(), 0, 0); 1375 1376 snd(&child, 9); 1377 1378 usleep(WAIT_USECS); 1379 1380 TEST_SEM(id, 0, 0, getpid(), 0, 0); 1381 TEST_SEM(id, 1, 1, getpid(), 0, 1); 1382 1383 kill(child.pid, SIGHUP); 1384 /* 1385 * Kills are not guaranteed to be delivered immediately to processes 1386 * other than the caller of kill(2), so let the child perform checks. 1387 */ 1388 1389 /* 1390 * Check that a blocking semop(2) call fails with EIDRM if the 1391 * semaphore set is removed after the call has blocked. 1392 */ 1393 snd(&child, 10); 1394 1395 usleep(WAIT_USECS); 1396 1397 if (semctl(id, 0, IPC_RMID) != 0) e(0); 1398 1399 /* 1400 * Check if sem_otime is updated correctly. Instead of sleeping for 1401 * whole seconds so as to be able to detect differences, use SETVAL, 1402 * which does not update sem_otime at all. This doubles as a first 1403 * test to see if SETVAL correctly wakes up a blocked semop(2) call. 1404 */ 1405 if ((id = semget(IPC_PRIVATE, 2, 0600)) == -1) e(0); 1406 1407 snd(&child, id); 1408 1409 usleep(WAIT_USECS); 1410 1411 TEST_SEM(id, 0, 0, 0, 1, 0); 1412 TEST_SEM(id, 1, 0, 0, 0, 0); 1413 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 1414 if (semds.sem_otime != 0) e(0); 1415 1416 if (semctl(id, 1, SETVAL, seminfo.semvmx) != 0) e(0); 1417 1418 TEST_SEM(id, 0, 0, 0, 1, 0); 1419 TEST_SEM(id, 1, seminfo.semvmx, 0, 0, 0); 1420 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 1421 if (semds.sem_otime != 0) e(0); 1422 1423 if (semctl(id, 0, SETVAL, 1) != 0) e(0); 1424 TEST_SEM(id, 0, 1, 0, 0, 0); 1425 TEST_SEM(id, 1, seminfo.semvmx, 0, 0, 0); 1426 1427 if (semctl(id, 0, SETVAL, 0) != 0) e(0); 1428 1429 snd(&child, 11); 1430 1431 usleep(WAIT_USECS); 1432 1433 TEST_SEM(id, 0, 0, 0, 0, 0); 1434 TEST_SEM(id, 1, seminfo.semvmx, 0, 0, 1); 1435 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 1436 if (semds.sem_otime != 0) e(0); 1437 1438 if (semctl(id, 1, SETVAL, 0) != 0) e(0); 1439 1440 TEST_SEM(id, 0, 0, 0, 1, 0); 1441 TEST_SEM(id, 1, 0, 0, 0, 0); 1442 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 1443 if (semds.sem_otime != 0) e(0); 1444 1445 time(&now); 1446 if (semctl(id, 0, SETVAL, 2) != 0) e(0); 1447 1448 TEST_SEM(id, 0, 1, child.pid, 0, 0); 1449 TEST_SEM(id, 1, 0, child.pid, 0, 0); 1450 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 1451 if (semds.sem_otime < now || semds.sem_otime >= now + 10) e(0); 1452 1453 if (semctl(id, 0, IPC_RMID) != 0) e(0); 1454 1455 /* 1456 * Perform a similar test for SETALL, ensuring that it causes an 1457 * ongoing semop(2) to behave correctly. 1458 */ 1459 if ((id = semget(IPC_PRIVATE, 2, 0600)) == -1) e(0); 1460 1461 snd(&child, id); 1462 1463 usleep(WAIT_USECS); 1464 1465 TEST_SEM(id, 0, 0, 0, 1, 0); 1466 TEST_SEM(id, 1, 0, 0, 0, 0); 1467 1468 val[0] = 1; 1469 val[1] = 1; 1470 if (semctl(id, 0, SETALL, val) != 0) e(0); 1471 1472 TEST_SEM(id, 0, 1, 0, 0, 0); 1473 TEST_SEM(id, 1, 1, 0, 0, 1); 1474 1475 val[0] = 0; 1476 val[1] = 1; 1477 if (semctl(id, 0, SETALL, val) != 0) e(0); 1478 1479 TEST_SEM(id, 0, 0, 0, 1, 0); 1480 TEST_SEM(id, 1, 1, 0, 0, 0); 1481 1482 val[0] = 1; 1483 val[1] = 1; 1484 if (semctl(id, 0, SETALL, val) != 0) e(0); 1485 1486 TEST_SEM(id, 0, 1, 0, 0, 0); 1487 TEST_SEM(id, 1, 1, 0, 0, 1); 1488 1489 val[0] = 0; 1490 val[1] = 0; 1491 if (semctl(id, 0, SETALL, val) != 0) e(0); 1492 1493 TEST_SEM(id, 0, 0, 0, 1, 0); 1494 TEST_SEM(id, 1, 0, 0, 0, 0); 1495 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 1496 if (semds.sem_otime != 0) e(0); 1497 1498 time(&now); 1499 val[0] = 1; 1500 val[1] = 0; 1501 if (semctl(id, 0, SETALL, val) != 0) e(0); 1502 1503 TEST_SEM(id, 0, 0, child.pid, 0, 0); 1504 TEST_SEM(id, 1, 0, child.pid, 0, 0); 1505 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 1506 if (semds.sem_otime < now || semds.sem_otime >= now + 10) e(0); 1507 1508 /* 1509 * Finally, ensure that if the child is killed, its blocked semop(2) 1510 * call is properly cancelled. 1511 */ 1512 sops[0].sem_num = 0; 1513 sops[0].sem_op = 0; 1514 sops[1].sem_num = 1; 1515 sops[1].sem_op = 0; 1516 if (semop(id, sops, 2) != 0) e(0); 1517 1518 TEST_SEM(id, 0, 0, getpid(), 0, 0); 1519 TEST_SEM(id, 1, 0, getpid(), 0, 0); 1520 1521 /* We'll be terminating the child, so let it report its errors now. */ 1522 if (rcv(&child) != 0) e(0); 1523 1524 snd(&child, 12); 1525 1526 usleep(WAIT_USECS); 1527 1528 TEST_SEM(id, 0, 0, getpid(), 0, 0); 1529 TEST_SEM(id, 1, 0, getpid(), 1, 0); 1530 1531 terminate(&child); 1532 1533 TEST_SEM(id, 0, 0, getpid(), 0, 0); 1534 TEST_SEM(id, 1, 0, getpid(), 0, 0); 1535 1536 if (semctl(id, 0, IPC_RMID) != 0) e(0); 1537 1538 free(sops); 1539 } 1540 1541 /* 1542 * Test semctl(2) permission checks, part 1: regular commands. 1543 */ 1544 static void 1545 test88c_perm1(struct link * parent) 1546 { 1547 static const int cmds[] = { GETVAL, GETPID, GETNCNT, GETZCNT }; 1548 struct semid_ds semds; 1549 struct seminfo seminfo; 1550 unsigned short val[3]; 1551 int i, r, tbit, bit, id[3], cmd; 1552 void *ptr; 1553 1554 while ((tbit = rcv(parent)) != -1) { 1555 id[0] = rcv(parent); 1556 id[1] = rcv(parent); 1557 id[2] = rcv(parent); 1558 1559 /* First the read-only, no-argument cases. */ 1560 bit = 4; 1561 for (i = 0; i < __arraycount(cmds); i++) { 1562 r = semctl(id[0], 0, cmds[i]); 1563 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 1564 if (((bit & tbit) == bit) != (r != -1)) e(0); 1565 1566 r = semctl(id[1], 0, cmds[i]); 1567 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 1568 if (((bit & tbit) == bit) != (r != -1)) e(0); 1569 1570 if (semctl(id[2], 0, cmds[i]) != -1) e(0); 1571 if (errno != EACCES) e(0); 1572 } 1573 1574 /* 1575 * Then SETVAL, which requires write permission and is the only 1576 * one that takes an integer argument. 1577 */ 1578 bit = 2; 1579 r = semctl(id[0], 0, SETVAL, 0); 1580 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 1581 if (((bit & tbit) == bit) != (r != -1)) e(0); 1582 1583 r = semctl(id[1], 0, SETVAL, 0); 1584 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 1585 if (((bit & tbit) == bit) != (r != -1)) e(0); 1586 1587 if (semctl(id[2], 0, SETVAL, 0) != -1) e(0); 1588 if (errno != EACCES) e(0); 1589 1590 /* 1591 * Finally the commands that require read or write permission 1592 * and take a pointer as argument. 1593 */ 1594 memset(val, 0, sizeof(val)); 1595 1596 for (i = 0; i < 4; i++) { 1597 switch (i) { 1598 case 0: 1599 cmd = GETALL; 1600 ptr = val; 1601 bit = 4; 1602 break; 1603 case 1: 1604 cmd = SETALL; 1605 ptr = val; 1606 bit = 2; 1607 break; 1608 case 2: 1609 cmd = IPC_STAT; 1610 ptr = &semds; 1611 bit = 4; 1612 break; 1613 } 1614 1615 r = semctl(id[0], 0, cmd, ptr); 1616 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 1617 if (((bit & tbit) == bit) != (r != -1)) e(0); 1618 1619 r = semctl(id[1], 0, cmd, ptr); 1620 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 1621 if (((bit & tbit) == bit) != (r != -1)) e(0); 1622 1623 if (semctl(id[2], 0, cmd, ptr) != -1) e(0); 1624 if (errno != EACCES) e(0); 1625 } 1626 1627 /* 1628 * I was hoping to avoid this, but otherwise we have to make 1629 * the other child iterate through all semaphore sets to find 1630 * the right index for each of the identifiers. As noted in 1631 * the IPC server itself as well, duplicating these macros is 1632 * not a big deal since the split is firmly hardcoded through 1633 * the exposure of IXSEQ_TO_IPCID to userland. 1634 */ 1635 #ifndef IPCID_TO_IX 1636 #define IPCID_TO_IX(id) ((id) & 0xffff) 1637 #endif 1638 1639 bit = 4; 1640 1641 r = semctl(IPCID_TO_IX(id[0]), 0, SEM_STAT, &semds); 1642 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 1643 if (((bit & tbit) == bit) != (r != -1)) e(0); 1644 1645 r = semctl(IPCID_TO_IX(id[1]), 0, SEM_STAT, &semds); 1646 if (r < 0 && (r != -1 || errno != EACCES)) e(0); 1647 if (((bit & tbit) == bit) != (r != -1)) e(0); 1648 1649 if (semctl(IPCID_TO_IX(id[2]), 0, SEM_STAT, &semds) != -1) 1650 e(0); 1651 if (errno != EACCES) e(0); 1652 1653 /* 1654 * IPC_INFO and SEM_INFO should always succeed. They do not 1655 * even take a semaphore set identifier. 1656 */ 1657 if (semctl(0, 0, IPC_INFO, &seminfo) == -1) e(0); 1658 if (semctl(0, 0, SEM_INFO, &seminfo) == -1) e(0); 1659 1660 snd(parent, 0); 1661 } 1662 } 1663 1664 /* 1665 * Test semctl(2) permission checks, part 2: the IPC_SET command. 1666 */ 1667 static void 1668 test88c_perm2(struct link * parent) 1669 { 1670 struct semid_ds semds; 1671 int r, shift, id[3]; 1672 1673 while ((shift = rcv(parent)) != -1) { 1674 id[0] = rcv(parent); 1675 id[1] = rcv(parent); 1676 id[2] = rcv(parent); 1677 1678 /* 1679 * Test IPC_SET. Ideally, we would set the permissions to what 1680 * they currently are, but we do not actually know what they 1681 * are, and IPC_STAT requires read permission which we may not 1682 * have! However, no matter what we do, we cannot prevent the 1683 * other child from being able to remove the semaphore sets 1684 * afterwards. So, we just set the permissions to all-zeroes; 1685 * even though those values are meaningful (mode 0000, uid 0, 1686 * gid 0) they could be anything: the API will accept anything. 1687 * This does mean we need to test IPC_RMID permissions from 1688 * another procedure, because we may now be locking ourselves 1689 * out. The System V IPC interface is pretty strange that way. 1690 */ 1691 memset(&semds, 0, sizeof(semds)); 1692 1693 r = semctl(id[0], 0, IPC_SET, &semds); 1694 if (r < 0 && (r != -1 || errno != EPERM)) e(0); 1695 if ((shift == 6) != (r != -1)) e(0); 1696 1697 r = semctl(id[1], 0, IPC_SET, &semds); 1698 if (r < 0 && (r != -1 || errno != EPERM)) e(0); 1699 if ((shift == 6) != (r != -1)) e(0); 1700 1701 /* For once, this too should succeed. */ 1702 r = semctl(id[2], 0, IPC_SET, &semds); 1703 if (r < 0 && (r != -1 || errno != EPERM)) e(0); 1704 if ((shift == 6) != (r != -1)) e(0); 1705 1706 snd(parent, 0); 1707 } 1708 } 1709 1710 /* 1711 * Test semctl(2) permission checks, part 3: the IPC_RMID command. 1712 */ 1713 static void 1714 test88c_perm3(struct link * parent) 1715 { 1716 int r, shift, id[3]; 1717 1718 while ((shift = rcv(parent)) != -1) { 1719 id[0] = rcv(parent); 1720 id[1] = rcv(parent); 1721 id[2] = rcv(parent); 1722 1723 r = semctl(id[0], 0, IPC_RMID); 1724 if (r < 0 && (r != -1 || errno != EPERM)) e(0); 1725 if ((shift == 6) != (r != -1)) e(0); 1726 1727 r = semctl(id[1], 0, IPC_RMID); 1728 if (r < 0 && (r != -1 || errno != EPERM)) e(0); 1729 if ((shift == 6) != (r != -1)) e(0); 1730 1731 /* Okay, twice then. */ 1732 r = semctl(id[2], 0, IPC_RMID); 1733 if (r < 0 && (r != -1 || errno != EPERM)) e(0); 1734 if ((shift == 6) != (r != -1)) e(0); 1735 1736 snd(parent, 0); 1737 } 1738 } 1739 1740 /* 1741 * Test the basic semctl(2) functionality. 1742 */ 1743 static void 1744 test88c(void) 1745 { 1746 static const int cmds[] = { GETVAL, GETPID, GETNCNT, GETZCNT }; 1747 struct seminfo seminfo; 1748 struct semid_ds semds, osemds; 1749 unsigned short val[4], seen[2]; 1750 char statbuf[sizeof(struct semid_ds) + 1]; 1751 unsigned int i, j; 1752 time_t now; 1753 int r, id, id2, badid1, badid2, cmd; 1754 1755 subtest = 2; 1756 1757 if (semctl(0, 0, IPC_INFO, &seminfo) == -1) e(0); 1758 1759 /* 1760 * Start with permission checks on the commands. IPC_SET and IPC_RMID 1761 * are special: they check for ownership (uid/cuid) and return EPERM 1762 * rather than EACCES on permission failure. 1763 */ 1764 test_perm(test88c_perm1, 0 /*owner_test*/); 1765 test_perm(test88c_perm2, 1 /*owner_test*/); 1766 test_perm(test88c_perm3, 1 /*owner_test*/); 1767 1768 /* Create identifiers known to be invalid. */ 1769 if ((badid1 = semget(IPC_PRIVATE, 1, 0600)) < 0) e(0); 1770 1771 if (semctl(badid1, 0, IPC_RMID) != 0) e(0); 1772 1773 memset(&semds, 0, sizeof(semds)); 1774 badid2 = IXSEQ_TO_IPCID(seminfo.semmni, semds.sem_perm); 1775 1776 if ((id = semget(IPC_PRIVATE, 3, IPC_CREAT | 0600)) < 0) e(0); 1777 1778 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 1779 if (semds.sem_otime != 0) e(0); 1780 if (semds.sem_ctime == 0) e(0); 1781 1782 /* In this case we can't avoid sleeping for longer periods.. */ 1783 while (time(&now) == semds.sem_ctime) 1784 usleep(250000); 1785 1786 /* 1787 * Test the simple GET commands. The actual functionality of these 1788 * commands have already been tested thoroughly as part of the 1789 * semop(2) part of the test set, so we do not repeat that here. 1790 */ 1791 for (i = 0; i < __arraycount(cmds); i++) { 1792 for (j = 0; j < 3; j++) 1793 if (semctl(id, j, cmds[i]) != 0) e(0); 1794 1795 if (semctl(badid1, 0, cmds[i]) != -1) e(0); 1796 if (errno != EINVAL) e(0); 1797 1798 if (semctl(badid2, 0, cmds[i]) != -1) e(0); 1799 if (errno != EINVAL) e(0); 1800 1801 if (semctl(-1, 0, cmds[i]) != -1) e(0); 1802 if (errno != EINVAL) e(0); 1803 1804 if (semctl(INT_MIN, 0, cmds[i]) != -1) e(0); 1805 if (errno != EINVAL) e(0); 1806 1807 if (semctl(id, -1, cmds[i]) != -1) e(0); 1808 if (errno != EINVAL) e(0); 1809 1810 if (semctl(id, 3, cmds[i]) != -1) e(0); 1811 if (errno != EINVAL) e(0); 1812 1813 /* These commands should not update ctime or otime. */ 1814 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 1815 if (semds.sem_otime != 0) e(0); 1816 if (semds.sem_ctime >= now) e(0); 1817 } 1818 1819 /* 1820 * Test the GETALL command. 1821 */ 1822 /* 1823 * Contrary to what the Open Group specification suggests, actual 1824 * implementations agree that the semnum parameter is to be ignored for 1825 * calls not involving a specific semaphore in the set. 1826 */ 1827 for (j = 0; j < 5; j++) { 1828 for (i = 0; i < __arraycount(val); i++) 1829 val[i] = USHRT_MAX; 1830 1831 if (semctl(id, (int)j - 1, GETALL, val) != 0) e(0); 1832 for (i = 0; i < 3; i++) 1833 if (val[i] != 0) e(0); 1834 if (val[i] != USHRT_MAX) e(0); 1835 } 1836 1837 for (i = 0; i < __arraycount(val); i++) 1838 val[i] = USHRT_MAX; 1839 1840 if (semctl(badid1, 0, GETALL, val) != -1) e(0); 1841 if (errno != EINVAL) e(0); 1842 1843 if (semctl(badid2, 0, GETALL, val) != -1) e(0); 1844 if (errno != EINVAL) e(0); 1845 1846 if (semctl(-1, 0, GETALL, val) != -1) e(0); 1847 if (errno != EINVAL) e(0); 1848 1849 if (semctl(INT_MIN, 0, GETALL, val) != -1) e(0); 1850 if (errno != EINVAL) e(0); 1851 1852 for (i = 0; i < __arraycount(val); i++) 1853 if (val[i] != USHRT_MAX) e(0); 1854 1855 if (semctl(id, 0, GETALL, NULL) != -1) e(0); 1856 if (errno != EFAULT) e(0); 1857 1858 if (semctl(id, 0, GETALL, bad_ptr) != -1) e(0); 1859 if (errno != EFAULT) e(0); 1860 1861 if (semctl(id, 0, GETALL, ((unsigned short *)bad_ptr) - 2) != -1) e(0); 1862 if (errno != EFAULT) e(0); 1863 1864 if (semctl(id, 0, GETALL, ((unsigned short *)bad_ptr) - 3) != 0) e(0); 1865 1866 /* Still no change in either otime or ctime. */ 1867 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 1868 if (semds.sem_otime != 0) e(0); 1869 if (semds.sem_ctime >= now) e(0); 1870 1871 /* 1872 * Test the IPC_STAT command. This is the last command we are testing 1873 * here that does not affect sem_ctime, so in order to avoid extra 1874 * sleep times, we test this command first now. 1875 */ 1876 /* 1877 * The basic IPC_STAT functionality has already been tested heavily as 1878 * part of the semget(2) and permission tests, so we do not repeat that 1879 * here. 1880 */ 1881 memset(statbuf, 0x5a, sizeof(statbuf)); 1882 1883 if (semctl(badid1, 0, IPC_STAT, statbuf) != -1) e(0); 1884 if (errno != EINVAL) e(0); 1885 1886 if (semctl(badid2, 0, IPC_STAT, statbuf) != -1) e(0); 1887 if (errno != EINVAL) e(0); 1888 1889 if (semctl(-1, 0, IPC_STAT, statbuf) != -1) e(0); 1890 if (errno != EINVAL) e(0); 1891 1892 if (semctl(INT_MIN, 0, IPC_STAT, statbuf) != -1) e(0); 1893 if (errno != EINVAL) e(0); 1894 1895 for (i = 0; i < sizeof(statbuf); i++) 1896 if (statbuf[i] != 0x5a) e(0); 1897 1898 if (semctl(id, 0, IPC_STAT, statbuf) != 0) e(0); 1899 1900 if (statbuf[sizeof(statbuf) - 1] != 0x5a) e(0); 1901 1902 if (semctl(id, 0, IPC_STAT, NULL) != -1) e(0); 1903 if (errno != EFAULT) e(0); 1904 1905 if (semctl(id, 0, IPC_STAT, bad_ptr) != -1) e(0); 1906 if (errno != EFAULT) e(0); 1907 1908 if (semctl(id, 0, IPC_STAT, ((struct semid_ds *)bad_ptr) - 1) != 0) 1909 e(0); 1910 1911 if (semctl(id, -1, IPC_STAT, &semds) != 0) e(0); 1912 if (semds.sem_otime != 0) e(0); 1913 if (semds.sem_ctime >= now) e(0); 1914 1915 /* 1916 * Test SEM_STAT. 1917 */ 1918 if ((id2 = semget(KEY_A, seminfo.semmsl, IPC_CREAT | 0642)) < 0) e(0); 1919 1920 memset(statbuf, 0x5a, sizeof(statbuf)); 1921 1922 if (semctl(-1, 0, SEM_STAT, statbuf) != -1) e(0); 1923 if (errno != EINVAL) e(0); 1924 1925 if (semctl(seminfo.semmni, 0, SEM_STAT, statbuf) != -1) e(0); 1926 if (errno != EINVAL) e(0); 1927 1928 for (i = 0; i < sizeof(statbuf); i++) 1929 if (statbuf[i] != 0x5a) e(0); 1930 1931 memset(seen, 0, sizeof(seen)); 1932 1933 for (i = 0; i < seminfo.semmni; i++) { 1934 errno = 0; 1935 if ((r = semctl(i, i / 2 - 1, SEM_STAT, statbuf)) == -1) { 1936 if (errno != EINVAL) e(0); 1937 continue; 1938 } 1939 if (r < 0) e(0); 1940 memcpy(&semds, statbuf, sizeof(semds)); 1941 if (!(semds.sem_perm.mode & SEM_ALLOC)) e(0); 1942 if (semds.sem_ctime == 0) e(0); 1943 if (IXSEQ_TO_IPCID(i, semds.sem_perm) != r) e(0); 1944 if (r == id) { 1945 seen[0]++; 1946 if (semds.sem_perm.mode != (SEM_ALLOC | 0600)) e(0); 1947 if (semds.sem_perm.uid != geteuid()) e(0); 1948 if (semds.sem_perm.gid != getegid()) e(0); 1949 if (semds.sem_perm.cuid != semds.sem_perm.uid) e(0); 1950 if (semds.sem_perm.cgid != semds.sem_perm.gid) e(0); 1951 if (semds.sem_perm._key != IPC_PRIVATE) e(0); 1952 if (semds.sem_nsems != 3) e(0); 1953 if (semds.sem_otime != 0) e(0); 1954 1955 /* This is here because we need a valid index. */ 1956 if (semctl(i, 0, SEM_STAT, NULL) != -1) e(0); 1957 if (errno != EFAULT) e(0); 1958 1959 if (semctl(i, 0, SEM_STAT, bad_ptr) != -1) e(0); 1960 if (errno != EFAULT) e(0); 1961 } else if (r == id2) { 1962 seen[1]++; 1963 if (semds.sem_perm.mode != (SEM_ALLOC | 0642)) e(0); 1964 if (semds.sem_perm.uid != geteuid()) e(0); 1965 if (semds.sem_perm.gid != getegid()) e(0); 1966 if (semds.sem_perm.cuid != semds.sem_perm.uid) e(0); 1967 if (semds.sem_perm.cgid != semds.sem_perm.gid) e(0); 1968 if (semds.sem_perm._key != KEY_A) e(0); 1969 if (semds.sem_nsems != seminfo.semmsl) e(0); 1970 } 1971 } 1972 1973 if (seen[0] != 1) e(0); 1974 if (seen[1] != 1) e(0); 1975 1976 if (statbuf[sizeof(statbuf) - 1] != 0x5a) e(0); 1977 1978 if (semctl(id, 5, IPC_STAT, &semds) != 0) e(0); 1979 if (semds.sem_otime != 0) e(0); 1980 if (semds.sem_ctime >= now) e(0); 1981 1982 /* 1983 * Test SETVAL. We start with all the failure cases, so as to be able 1984 * to check that sem_ctime is not changed in those cases. 1985 */ 1986 if (semctl(badid1, 0, SETVAL, 1) != -1) e(0); 1987 if (errno != EINVAL) e(0); 1988 1989 if (semctl(badid2, 0, SETVAL, 1) != -1) e(0); 1990 if (errno != EINVAL) e(0); 1991 1992 if (semctl(-1, 0, SETVAL, 1) != -1) e(0); 1993 if (errno != EINVAL) e(0); 1994 1995 if (semctl(INT_MIN, 0, SETVAL, 1) != -1) e(0); 1996 if (errno != EINVAL) e(0); 1997 1998 if (semctl(id, -1, SETVAL, 1) != -1) e(0); 1999 if (errno != EINVAL) e(0); 2000 2001 if (semctl(id, 3, SETVAL, 1) != -1) e(0); 2002 if (errno != EINVAL) e(0); 2003 2004 if (semctl(id, 0, SETVAL, -1) != -1) e(0); 2005 if (errno != ERANGE) e(0); 2006 2007 if (semctl(id, 0, SETVAL, seminfo.semvmx + 1) != -1) e(0); 2008 if (errno != ERANGE) e(0); 2009 2010 TEST_SEM(id, 0, 0, 0, 0, 0); 2011 2012 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 2013 if (semds.sem_otime != 0) e(0); 2014 if (semds.sem_ctime >= now) e(0); 2015 2016 /* Alright, there we go.. */ 2017 if (semctl(id, 1, SETVAL, 0) != 0) e(0); 2018 2019 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 2020 if (semds.sem_otime != 0) e(0); 2021 if (semds.sem_ctime < now || semds.sem_ctime >= now + 10) e(0); 2022 2023 TEST_SEM(id, 1, 0, 0, 0, 0); 2024 2025 if (semctl(id, 2, SETVAL, seminfo.semvmx) != 0) e(0); 2026 2027 TEST_SEM(id, 2, seminfo.semvmx, 0, 0, 0); 2028 2029 if (semctl(id, 0, SETVAL, 1) != 0) e(0); 2030 2031 TEST_SEM(id, 0, 1, 0, 0, 0); 2032 TEST_SEM(id, 1, 0, 0, 0, 0); 2033 TEST_SEM(id, 2, seminfo.semvmx, 0, 0, 0); 2034 2035 if (semctl(id, 0, GETALL, val) != 0) e(0); 2036 if (val[0] != 1) e(0); 2037 if (val[1] != 0) e(0); 2038 if (val[2] != seminfo.semvmx) e(0); 2039 2040 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 2041 2042 while (time(&now) == semds.sem_ctime) 2043 usleep(250000); 2044 2045 /* 2046 * Test SETALL. Same idea: failure cases first. 2047 */ 2048 if (semctl(badid1, 0, SETALL, 1) != -1) e(0); 2049 if (errno != EINVAL) e(0); 2050 2051 if (semctl(badid2, 0, SETALL, 1) != -1) e(0); 2052 if (errno != EINVAL) e(0); 2053 2054 if (semctl(-1, 0, SETALL, 1) != -1) e(0); 2055 if (errno != EINVAL) e(0); 2056 2057 if (semctl(INT_MIN, 0, SETALL, 1) != -1) e(0); 2058 if (errno != EINVAL) e(0); 2059 2060 val[0] = seminfo.semvmx + 1; 2061 val[1] = 0; 2062 val[2] = 0; 2063 if (semctl(id, 0, SETALL, val) != -1) e(0); 2064 if (errno != ERANGE) e(0); 2065 2066 val[0] = 0; 2067 val[1] = 1; 2068 val[2] = seminfo.semvmx + 1; 2069 if (semctl(id, 0, SETALL, val) != -1) e(0); 2070 if (errno != ERANGE) e(0); 2071 2072 if (semctl(id, 0, SETALL, NULL) != -1) e(0); 2073 if (errno != EFAULT) e(0); 2074 2075 if (semctl(id, 0, SETALL, bad_ptr) != -1) e(0); 2076 if (errno != EFAULT) e(0); 2077 2078 if (semctl(id, 0, SETALL, ((unsigned short *)bad_ptr) - 2) != -1) e(0); 2079 if (errno != EFAULT) e(0); 2080 2081 TEST_SEM(id, 0, 1, 0, 0, 0); 2082 TEST_SEM(id, 1, 0, 0, 0, 0); 2083 TEST_SEM(id, 2, seminfo.semvmx, 0, 0, 0); 2084 2085 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 2086 if (semds.sem_otime != 0) e(0); 2087 if (semds.sem_ctime >= now) e(0); 2088 2089 val[0] = seminfo.semvmx; 2090 val[1] = 0; 2091 val[2] = 0; 2092 if (semctl(id, 0, SETALL, val) != 0) e(0); 2093 2094 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 2095 if (semds.sem_otime != 0) e(0); 2096 if (semds.sem_ctime < now || semds.sem_ctime >= now + 10) e(0); 2097 2098 TEST_SEM(id, 0, seminfo.semvmx, 0, 0, 0); 2099 TEST_SEM(id, 1, 0, 0, 0, 0); 2100 TEST_SEM(id, 2, 0, 0, 0, 0); 2101 2102 val[0] = 0; 2103 val[1] = 1; 2104 val[2] = seminfo.semvmx; 2105 if (semctl(id, INT_MAX, SETALL, val) != 0) e(0); 2106 2107 TEST_SEM(id, 0, 0, 0, 0, 0); 2108 TEST_SEM(id, 1, 1, 0, 0, 0); 2109 TEST_SEM(id, 2, seminfo.semvmx, 0, 0, 0); 2110 2111 memset(page_ptr, 0, page_size); 2112 if (semctl(id, 0, SETALL, ((unsigned short *)bad_ptr) - 3) != 0) e(0); 2113 2114 TEST_SEM(id, 0, 0, 0, 0, 0); 2115 TEST_SEM(id, 1, 0, 0, 0, 0); 2116 TEST_SEM(id, 2, 0, 0, 0, 0); 2117 2118 while (time(&now) == semds.sem_ctime) 2119 usleep(250000); 2120 2121 /* 2122 * Test IPC_SET. Its core functionality has already been tested 2123 * thoroughly as part of the permission tests. 2124 */ 2125 if (semctl(badid1, 0, IPC_SET, &semds) != -1) e(0); 2126 if (errno != EINVAL) e(0); 2127 2128 if (semctl(badid2, 0, IPC_SET, &semds) != -1) e(0); 2129 if (errno != EINVAL) e(0); 2130 2131 if (semctl(-1, 0, IPC_SET, &semds) != -1) e(0); 2132 if (errno != EINVAL) e(0); 2133 2134 if (semctl(INT_MIN, 0, IPC_SET, &semds) != -1) e(0); 2135 if (errno != EINVAL) e(0); 2136 2137 if (semctl(id, 0, IPC_SET, NULL) != -1) e(0); 2138 if (errno != EFAULT) e(0); 2139 2140 if (semctl(id, 0, IPC_SET, bad_ptr) != -1) e(0); 2141 if (errno != EFAULT) e(0); 2142 2143 if (semctl(id, 0, IPC_STAT, &osemds) != 0) e(0); 2144 if (osemds.sem_otime != 0) e(0); 2145 if (osemds.sem_ctime >= now) e(0); 2146 2147 /* 2148 * Only mode, uid, gid may be set. While the given mode is sanitized 2149 * in our implementation (see below; the open group specification 2150 * leaves this undefined), the uid and gid are not (we do not test this 2151 * exhaustively). The other given fields must be ignored. The ctime 2152 * field will be updated. 2153 */ 2154 memset(&semds, 0x5b, sizeof(semds)); 2155 semds.sem_perm.mode = 0712; 2156 semds.sem_perm.uid = UID_MAX; 2157 semds.sem_perm.gid = GID_MAX - 1; 2158 if (semctl(id, 0, IPC_SET, &semds) != 0) e(0); 2159 2160 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0); 2161 if (semds.sem_perm.mode != (SEM_ALLOC | 0712)) e(0); 2162 if (semds.sem_perm.uid != UID_MAX) e(0); 2163 if (semds.sem_perm.gid != GID_MAX - 1) e(0); 2164 if (semds.sem_perm.cuid != osemds.sem_perm.cuid) e(0); 2165 if (semds.sem_perm.cgid != osemds.sem_perm.cgid) e(0); 2166 if (semds.sem_perm._seq != osemds.sem_perm._seq) e(0); 2167 if (semds.sem_perm._key != osemds.sem_perm._key) e(0); 2168 if (semds.sem_nsems != osemds.sem_nsems) e(0); 2169 if (semds.sem_otime != osemds.sem_otime) e(0); 2170 if (semds.sem_ctime < now || semds.sem_ctime >= now + 10) e(0); 2171 2172 /* It should be possible to set any mode, but mask 0777 is applied. */ 2173 semds.sem_perm.uid = osemds.sem_perm.uid; 2174 semds.sem_perm.gid = osemds.sem_perm.gid; 2175 for (i = 0; i < 0777; i++) { 2176 semds.sem_perm.mode = i; 2177 if (semctl(id, i / 2 - 1, IPC_SET, &semds) != 0) e(0); 2178 2179 if (semctl(id, i / 2 - 2, IPC_STAT, &semds) != 0) e(0); 2180 if (semds.sem_perm.mode != (SEM_ALLOC | i)) e(0); 2181 2182 semds.sem_perm.mode = ~0777 | i; 2183 if (semctl(id, i / 2 - 3, IPC_SET, &semds) != 0) e(0); 2184 2185 if (semctl(id, i / 2 - 4, IPC_STAT, &semds) != 0) e(0); 2186 if (semds.sem_perm.mode != (SEM_ALLOC | i)) e(0); 2187 } 2188 if (semds.sem_perm.uid != osemds.sem_perm.uid) e(0); 2189 if (semds.sem_perm.gid != osemds.sem_perm.gid) e(0); 2190 2191 if (semctl(id, 0, IPC_SET, ((struct semid_ds *)bad_ptr) - 1) != 0) 2192 e(0); 2193 2194 /* 2195 * Test IPC_RMID. Its basic functionality has already been tested 2196 * multiple times over, so there is not much left to do here. 2197 */ 2198 if (semctl(badid1, 0, IPC_RMID) != -1) e(0); 2199 if (errno != EINVAL) e(0); 2200 2201 if (semctl(badid2, 0, IPC_RMID) != -1) e(0); 2202 if (errno != EINVAL) e(0); 2203 2204 if (semctl(-1, 0, IPC_RMID) != -1) e(0); 2205 if (errno != EINVAL) e(0); 2206 2207 if (semctl(INT_MIN, 0, IPC_RMID) != -1) e(0); 2208 if (errno != EINVAL) e(0); 2209 2210 if (semctl(id, 0, IPC_RMID) != 0) e(0); 2211 2212 if (semctl(id, 0, IPC_RMID) != -1) e(0); 2213 if (errno != EINVAL) e(0); 2214 2215 if (semctl(id, 0, IPC_STAT, &semds) != -1) e(0); 2216 if (errno != EINVAL) e(0); 2217 2218 if (semctl(id2, 1, IPC_RMID) != 0) e(0); 2219 2220 if (semctl(id2, 1, IPC_RMID) != -1) e(0); 2221 if (errno != EINVAL) e(0); 2222 2223 /* 2224 * Test IPC_INFO and SEM_INFO. Right now, for all practical purposes, 2225 * these identifiers behave pretty much the same. 2226 */ 2227 if ((id = semget(IPC_PRIVATE, 3, 0600)) == -1) e(0); 2228 if ((id2 = semget(IPC_PRIVATE, 1, 0600)) == -1) e(0); 2229 2230 for (i = 0; i <= 1; i++) { 2231 cmd = (i == 0) ? IPC_INFO : SEM_INFO; 2232 2233 memset(&seminfo, 0xff, sizeof(seminfo)); 2234 2235 if ((r = semctl(0, 0, cmd, &seminfo)) == -1) e(0); 2236 2237 /* 2238 * These commands return the index of the highest in-use slot 2239 * in the semaphore set table. Bad idea of course, because 2240 * that means the value 0 has two potential meanings. Since we 2241 * cannot guarantee that no other running application is using 2242 * semaphores, we settle for "at least" tests based on the two 2243 * semaphore sets we just created. 2244 */ 2245 if (r < 1 || r >= seminfo.semmni) e(0); 2246 2247 /* 2248 * Many of these checks are rather basic because of missing 2249 * SEM_UNDO support. The only difference between IPC_INFO and 2250 * SEM_INFO is the meaning of the semusz and semaem fields. 2251 */ 2252 if (seminfo.semmap < 0) e(0); 2253 if (seminfo.semmni < 3 || seminfo.semmni > USHRT_MAX) e(0); 2254 if (seminfo.semmns < 3 || seminfo.semmns > USHRT_MAX) e(0); 2255 if (seminfo.semmnu < 0) e(0); 2256 if (seminfo.semmsl < 3 || seminfo.semmsl > USHRT_MAX) e(0); 2257 if (seminfo.semopm < 3 || seminfo.semopm > USHRT_MAX) e(0); 2258 if (seminfo.semume < 0) e(0); 2259 if (cmd == SEM_INFO) { 2260 if (seminfo.semusz < 2) e(0); 2261 } else 2262 if (seminfo.semusz < 0) e(0); 2263 if (seminfo.semvmx < 3 || seminfo.semvmx > SHRT_MAX) e(0); 2264 if (cmd == SEM_INFO) { 2265 if (seminfo.semaem < 4) e(0); 2266 } else 2267 if (seminfo.semaem < 0) e(0); 2268 2269 if (semctl(INT_MAX, -1, cmd, &seminfo) == -1) e(0); 2270 if (semctl(-1, INT_MAX, cmd, &seminfo) == -1) e(0); 2271 2272 if (semctl(0, 0, cmd, NULL) != -1) e(0); 2273 if (errno != EFAULT) e(0); 2274 2275 if (semctl(0, 0, cmd, bad_ptr) != -1) e(0); 2276 if (errno != EFAULT) e(0); 2277 2278 if (semctl(0, 0, cmd, ((struct seminfo *)bad_ptr) - 1) == -1) 2279 e(0); 2280 } 2281 2282 if (semctl(id2, 0, IPC_RMID) != 0) e(0); 2283 2284 /* 2285 * Finally, test invalid commands. Well, hopefully invalid commands, 2286 * anyway. 2287 */ 2288 if (semctl(id, 0, INT_MIN) != -1) e(0); 2289 if (errno != EINVAL) e(0); 2290 2291 if (semctl(id, 0, INT_MAX) != -1) e(0); 2292 if (errno != EINVAL) e(0); 2293 2294 if (semctl(id, 0, IPC_RMID) != 0) e(0); 2295 } 2296 2297 /* 2298 * Test SEM_UNDO support. Right now this functionality is missing altogether. 2299 * For now, we test that any attempt to use SEM_UNDO fails. 2300 */ 2301 static void 2302 test88d(void) 2303 { 2304 struct sembuf sop; 2305 int id; 2306 2307 subtest = 3; 2308 2309 if ((id = semget(IPC_PRIVATE, 1, 0600)) == -1) e(0); 2310 2311 /* 2312 * Use an all-ones (but positive) flag field. This will include 2313 * SEM_UNDO, but also tell the IPC server to report no warning. 2314 */ 2315 if (!(SHRT_MAX & SEM_UNDO)) e(0); 2316 sop.sem_num = 0; 2317 sop.sem_op = 1; 2318 sop.sem_flg = SHRT_MAX; 2319 if (semop(id, &sop, 1) != -1) e(0); 2320 if (errno != EINVAL) e(0); 2321 2322 if (semctl(id, 0, IPC_RMID) != 0) e(0); 2323 } 2324 2325 enum { 2326 RESUME_SEMOP, /* use semop() to resume blocked parties */ 2327 RESUME_SETVAL, /* use semctl(SETVAL) to resume blocked parties */ 2328 RESUME_SETALL, /* use semctl(SETALL) to resume blocked parties */ 2329 NR_RESUMES 2330 }; 2331 2332 enum { 2333 MATCH_FIRST, /* first match completes, blocks second match */ 2334 MATCH_SECOND, /* first match does not complete, second match does */ 2335 MATCH_KILL, /* second match completes after first is aborted */ 2336 MATCH_BOTH, /* first and second match both complete */ 2337 MATCH_CASCADE, /* completed match in turn causes another match */ 2338 MATCH_ALL, /* a combination of the last two */ 2339 NR_MATCHES 2340 }; 2341 2342 /* 2343 * Auxiliary child procedure. The auxiliary children will deadlock until the 2344 * semaphore set is removed. 2345 */ 2346 static void 2347 test88e_childaux(struct link * parent) 2348 { 2349 struct sembuf sops[3]; 2350 struct seminfo seminfo; 2351 int child, id, num; 2352 2353 child = rcv(parent); 2354 id = rcv(parent); 2355 num = rcv(parent); 2356 2357 memset(sops, 0, sizeof(sops)); 2358 2359 /* These operations are guaranteed to never return successfully. */ 2360 switch (child) { 2361 case 1: 2362 sops[0].sem_num = num; 2363 sops[0].sem_op = 1; 2364 sops[1].sem_num = num; 2365 sops[1].sem_op = 0; 2366 sops[2].sem_num = 0; 2367 sops[2].sem_op = 1; 2368 break; 2369 case 2: 2370 if (semctl(0, 0, IPC_INFO, &seminfo) == -1) e(0); 2371 sops[0].sem_num = num; 2372 sops[0].sem_op = -seminfo.semvmx; 2373 sops[1].sem_num = num; 2374 sops[1].sem_op = -seminfo.semvmx; 2375 sops[2].sem_num = 0; 2376 sops[2].sem_op = 1; 2377 break; 2378 default: 2379 e(0); 2380 } 2381 2382 snd(parent, 0); 2383 2384 if (semop(id, sops, 3) != -1) e(0); 2385 if (errno != EIDRM) e(0); 2386 } 2387 2388 /* 2389 * First child procedure. 2390 */ 2391 static void 2392 test88e_child1(struct link * parent) 2393 { 2394 struct sembuf sops[3]; 2395 size_t nsops; 2396 int match, id, expect; 2397 2398 match = rcv(parent); 2399 id = rcv(parent); 2400 2401 /* Start off with some defaults, then refine by match type. */ 2402 memset(sops, 0, sizeof(sops)); 2403 sops[0].sem_num = 2; 2404 sops[0].sem_op = -1; 2405 nsops = 2; 2406 expect = 0; 2407 switch (match) { 2408 case MATCH_FIRST: 2409 sops[1].sem_num = 3; 2410 sops[1].sem_op = 1; 2411 break; 2412 case MATCH_SECOND: 2413 sops[1].sem_num = 3; 2414 sops[1].sem_op = -1; 2415 sops[2].sem_num = 0; 2416 sops[2].sem_op = 1; 2417 nsops = 3; 2418 expect = -1; 2419 break; 2420 case MATCH_KILL: 2421 sops[1].sem_num = 0; 2422 sops[1].sem_op = 1; 2423 expect = INT_MIN; 2424 break; 2425 case MATCH_BOTH: 2426 case MATCH_CASCADE: 2427 case MATCH_ALL: 2428 sops[1].sem_num = 3; 2429 sops[1].sem_op = 1; 2430 break; 2431 default: 2432 e(0); 2433 } 2434 2435 snd(parent, 0); 2436 2437 if (semop(id, sops, nsops) != expect) e(0); 2438 if (expect == -1 && errno != EIDRM) e(0); 2439 } 2440 2441 /* 2442 * Second child procedure. 2443 */ 2444 static void 2445 test88e_child2(struct link * parent) 2446 { 2447 struct sembuf sops[2]; 2448 size_t nsops; 2449 int match, id, expect; 2450 2451 match = rcv(parent); 2452 id = rcv(parent); 2453 2454 /* Start off with some defaults, then refine by match type. */ 2455 memset(sops, 0, sizeof(sops)); 2456 sops[0].sem_num = 2; 2457 sops[0].sem_op = -1; 2458 nsops = 2; 2459 expect = 0; 2460 switch (match) { 2461 case MATCH_FIRST: 2462 sops[1].sem_num = 0; 2463 sops[1].sem_op = 1; 2464 expect = -1; 2465 break; 2466 case MATCH_SECOND: 2467 case MATCH_KILL: 2468 nsops = 1; 2469 break; 2470 case MATCH_BOTH: 2471 case MATCH_ALL: 2472 sops[1].sem_num = 3; 2473 sops[1].sem_op = 1; 2474 break; 2475 case MATCH_CASCADE: 2476 sops[0].sem_num = 3; 2477 nsops = 1; 2478 break; 2479 default: 2480 e(0); 2481 } 2482 2483 snd(parent, 0); 2484 2485 if (semop(id, sops, nsops) != expect) e(0); 2486 if (expect == -1 && errno != EIDRM) e(0); 2487 } 2488 2489 /* 2490 * Third child procedure. 2491 */ 2492 static void 2493 test88e_child3(struct link * parent) 2494 { 2495 struct sembuf sops[1]; 2496 size_t nsops; 2497 int match, id; 2498 2499 match = rcv(parent); 2500 id = rcv(parent); 2501 2502 /* Things are a bit simpler here. */ 2503 memset(sops, 0, sizeof(sops)); 2504 nsops = 1; 2505 switch (match) { 2506 case MATCH_ALL: 2507 sops[0].sem_num = 3; 2508 sops[0].sem_op = -2; 2509 break; 2510 default: 2511 e(0); 2512 } 2513 2514 snd(parent, 0); 2515 2516 if (semop(id, sops, nsops) != 0) e(0); 2517 } 2518 2519 /* 2520 * Perform one test for operations affecting multiple processes. 2521 */ 2522 static void 2523 sub88e(unsigned int match, unsigned int resume, unsigned int aux) 2524 { 2525 struct link aux1, aux2, child1, child2, child3; 2526 struct sembuf sop; 2527 unsigned short val[4]; 2528 int id, inc, aux_zcnt, aux_ncnt; 2529 2530 /* 2531 * For this test we use one single semaphore set, with four semaphores. 2532 * The first semaphore is increased in the case that an operation that 2533 * should never complete does complete, and thus should stay zero. 2534 * Depending on 'aux', the second or third semaphore is used by the 2535 * auxiliary children (if any, also depending on 'aux') to deadlock on. 2536 * The third and higher semaphores are used in the main operations. 2537 */ 2538 if ((id = semget(IPC_PRIVATE, __arraycount(val), 0666)) == -1) e(0); 2539 2540 aux_zcnt = aux_ncnt = 0; 2541 2542 /* Start the first auxiliary child if desired, before all others. */ 2543 if (aux & 1) { 2544 spawn(&aux1, test88e_childaux, DROP_ALL); 2545 2546 snd(&aux1, 1); 2547 snd(&aux1, id); 2548 snd(&aux1, (aux & 4) ? 2 : 1); 2549 2550 if (rcv(&aux1) != 0) e(0); 2551 2552 if (aux & 4) 2553 aux_zcnt++; 2554 } 2555 2556 /* Start and configure all children for this specific match test. */ 2557 spawn(&child1, test88e_child1, DROP_ALL); 2558 2559 snd(&child1, match); 2560 snd(&child1, id); 2561 2562 if (rcv(&child1) != 0) e(0); 2563 2564 /* 2565 * For fairness tests, we must ensure that the first child blocks on 2566 * the semaphore before the second child does. 2567 */ 2568 switch (match) { 2569 case MATCH_FIRST: 2570 case MATCH_SECOND: 2571 case MATCH_KILL: 2572 usleep(WAIT_USECS); 2573 break; 2574 } 2575 2576 spawn(&child2, test88e_child2, DROP_NONE); 2577 2578 snd(&child2, match); 2579 snd(&child2, id); 2580 2581 if (rcv(&child2) != 0) e(0); 2582 2583 if (match == MATCH_ALL) { 2584 spawn(&child3, test88e_child3, DROP_USER); 2585 2586 snd(&child3, match); 2587 snd(&child3, id); 2588 2589 if (rcv(&child3) != 0) e(0); 2590 } 2591 2592 /* Start the second auxiliary child if desired, after all others. */ 2593 if (aux & 2) { 2594 spawn(&aux2, test88e_childaux, DROP_NONE); 2595 2596 snd(&aux2, 2); 2597 snd(&aux2, id); 2598 snd(&aux2, (aux & 4) ? 2 : 1); 2599 2600 if (rcv(&aux2) != 0) e(0); 2601 2602 if (aux & 4) 2603 aux_ncnt++; 2604 } 2605 2606 usleep(WAIT_USECS); 2607 2608 /* 2609 * Test semaphore values and determine the value with which to increase 2610 * the third semaphore. For MATCH_KILL, also kill the first child. 2611 */ 2612 inc = 1; 2613 switch (match) { 2614 case MATCH_FIRST: 2615 case MATCH_SECOND: 2616 TEST_SEM(id, 2, 0, 0, 2 + aux_ncnt, aux_zcnt); 2617 TEST_SEM(id, 3, 0, 0, 0, 0); 2618 break; 2619 case MATCH_KILL: 2620 TEST_SEM(id, 2, 0, 0, 2 + aux_ncnt, aux_zcnt); 2621 2622 terminate(&child1); 2623 2624 /* As stated before, non-self kills need not be instant. */ 2625 usleep(WAIT_USECS); 2626 2627 TEST_SEM(id, 2, 0, 0, 1 + aux_ncnt, aux_zcnt); 2628 TEST_SEM(id, 3, 0, 0, 0, 0); 2629 break; 2630 case MATCH_BOTH: 2631 TEST_SEM(id, 2, 0, 0, 2 + aux_ncnt, aux_zcnt); 2632 TEST_SEM(id, 3, 0, 0, 0, 0); 2633 inc = 2; 2634 break; 2635 case MATCH_CASCADE: 2636 TEST_SEM(id, 2, 0, 0, 1 + aux_ncnt, aux_zcnt); 2637 TEST_SEM(id, 3, 0, 0, 1, 0); 2638 break; 2639 case MATCH_ALL: 2640 TEST_SEM(id, 2, 0, 0, 2 + aux_ncnt, aux_zcnt); 2641 TEST_SEM(id, 3, 0, 0, 1, 0); 2642 inc = 2; 2643 break; 2644 default: 2645 e(0); 2646 } 2647 2648 TEST_SEM(id, 0, 0, 0, 0, 0); 2649 TEST_SEM(id, 1, 0, 0, -1, -1); 2650 2651 /* Resume the appropriate set of children. */ 2652 switch (resume) { 2653 case RESUME_SEMOP: 2654 memset(&sop, 0, sizeof(sop)); 2655 sop.sem_num = 2; 2656 sop.sem_op = inc; 2657 if (semop(id, &sop, 1) != 0) e(0); 2658 break; 2659 case RESUME_SETVAL: 2660 if (semctl(id, 2, SETVAL, inc) != 0) e(0); 2661 break; 2662 case RESUME_SETALL: 2663 memset(val, 0, sizeof(val)); 2664 val[2] = inc; 2665 if (semctl(id, 0, SETALL, val) != 0) e(0); 2666 break; 2667 default: 2668 e(0); 2669 } 2670 2671 /* 2672 * See if the right children were indeed resumed, and retest the 2673 * semaphore values. 2674 */ 2675 switch (match) { 2676 case MATCH_FIRST: 2677 TEST_SEM(id, 2, 0, child1.pid, 1 + aux_ncnt, aux_zcnt); 2678 TEST_SEM(id, 3, 1, child1.pid, 0, 0); 2679 collect(&child1); 2680 break; 2681 case MATCH_SECOND: 2682 TEST_SEM(id, 2, 0, child2.pid, 1 + aux_ncnt, aux_zcnt); 2683 TEST_SEM(id, 3, 0, 0, 0, 0); 2684 collect(&child2); 2685 break; 2686 case MATCH_KILL: 2687 TEST_SEM(id, 2, 0, child2.pid, aux_ncnt, aux_zcnt); 2688 TEST_SEM(id, 3, 0, 0, 0, 0); 2689 collect(&child2); 2690 break; 2691 case MATCH_BOTH: 2692 /* 2693 * The children are not ordered in this case, so we do not know 2694 * which one gets access to the semaphores last. 2695 */ 2696 TEST_SEM(id, 2, 0, -1, aux_ncnt, aux_zcnt); 2697 TEST_SEM(id, 3, 2, -1, 0, 0); 2698 collect(&child1); 2699 collect(&child2); 2700 break; 2701 case MATCH_CASCADE: 2702 TEST_SEM(id, 2, 0, child1.pid, aux_ncnt, aux_zcnt); 2703 TEST_SEM(id, 3, 0, child2.pid, 0, 0); 2704 collect(&child1); 2705 collect(&child2); 2706 break; 2707 case MATCH_ALL: 2708 TEST_SEM(id, 2, 0, -1, aux_ncnt, aux_zcnt); 2709 TEST_SEM(id, 3, 0, child3.pid, 0, 0); 2710 collect(&child1); 2711 collect(&child2); 2712 collect(&child3); 2713 break; 2714 default: 2715 e(0); 2716 } 2717 2718 TEST_SEM(id, 0, 0, 0, 0, 0); 2719 TEST_SEM(id, 1, 0, 0, -1, -1); 2720 2721 /* Remove the semaphore set. This should unblock remaining callers. */ 2722 if (semctl(id, 0, IPC_RMID) != 0) e(0); 2723 2724 /* Wait for the children that were not resumed, but should be now. */ 2725 switch (match) { 2726 case MATCH_FIRST: 2727 collect(&child2); 2728 break; 2729 case MATCH_SECOND: 2730 collect(&child1); 2731 break; 2732 case MATCH_KILL: 2733 case MATCH_BOTH: 2734 case MATCH_CASCADE: 2735 case MATCH_ALL: 2736 break; 2737 default: 2738 e(0); 2739 } 2740 2741 /* Wait for the auxiliary children as well. */ 2742 if (aux & 1) 2743 collect(&aux1); 2744 if (aux & 2) 2745 collect(&aux2); 2746 } 2747 2748 /* 2749 * Test operations affecting multiple processes, ensuring the following points: 2750 * 1) an operation resumes all possible waiters; 2) a resumed operation in turn 2751 * correctly resumes other now-unblocked operations; 3) a basic level of FIFO 2752 * fairness is provided between blocked parties; 4) all the previous points are 2753 * unaffected by additional waiters that are not being resumed; 5) identifier 2754 * removal properly resumes all affected waiters. 2755 */ 2756 static void 2757 test88e(void) 2758 { 2759 unsigned int resume, match, aux; 2760 2761 subtest = 4; 2762 2763 for (match = 0; match < NR_MATCHES; match++) 2764 for (resume = 0; resume < NR_RESUMES; resume++) 2765 for (aux = 1; aux <= 8; aux++) /* 0 and 4 are equal */ 2766 sub88e(match, resume, aux); 2767 } 2768 2769 /* 2770 * Initialize the test. 2771 */ 2772 static void 2773 test88_init(void) 2774 { 2775 struct group *gr; 2776 2777 /* Start with full root privileges. */ 2778 setuid(geteuid()); 2779 2780 if ((gr = getgrnam(ROOT_GROUP)) == NULL) e(0); 2781 2782 setgid(gr->gr_gid); 2783 setegid(gr->gr_gid); 2784 2785 page_size = getpagesize(); 2786 page_ptr = mmap(NULL, page_size * 2, PROT_READ | PROT_WRITE, 2787 MAP_ANON | MAP_PRIVATE, -1, 0); 2788 if (page_ptr == MAP_FAILED) e(0); 2789 bad_ptr = page_ptr + page_size; 2790 if (munmap(bad_ptr, page_size) != 0) e(0); 2791 } 2792 2793 /* 2794 * Test program for SysV IPC semaphores. 2795 */ 2796 int 2797 main(int argc, char ** argv) 2798 { 2799 int i, m; 2800 2801 start(88); 2802 2803 test88_init(); 2804 2805 if (argc == 2) 2806 m = atoi(argv[1]); 2807 else 2808 m = 0xFF; 2809 2810 for (i = 0; i < ITERATIONS; i++) { 2811 if (m & 0x01) test88a(); 2812 if (m & 0x02) test88b(); 2813 if (m & 0x04) test88c(); 2814 if (m & 0x08) test88d(); 2815 if (m & 0x10) test88e(); 2816 } 2817 2818 quit(); 2819 } 2820