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