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. */
11 #include <sys/sysctl.h>
18 #define WAIT_USECS 100000 /* time for processes to get ready */
20 #define KEY_A 0x73570001
21 #define KEY_B (KEY_A + 1)
22 #define KEY_C (KEY_A + 2)
24 #define ROOT_USER "root" /* name of root */
25 #define ROOT_GROUP "wheel" /* name of root's group */
26 #define NONROOT_USER "bin" /* name of any unprivileged user */
27 #define NONROOT_GROUP "bin" /* name of any unprivileged group */
50 * Test semaphore properties. This is a macro, so that it prints useful line
51 * information if an error occurs.
53 #define TEST_SEM(id, num, val, pid, ncnt, zcnt) do { \
54 if (semctl(id, num, GETVAL) != val) e(0); \
55 if (pid != -1 && semctl(id, num, GETPID) != pid) e(1); \
56 if (ncnt != -1 && semctl(id, num, GETNCNT) != ncnt) e(2); \
57 if (zcnt != -1 && semctl(id, num, GETZCNT) != zcnt) e(3); \
60 static int nr_signals
= 0;
62 static size_t page_size
;
63 static char *page_ptr
;
67 * Spawn a child process, with a pair of pipes to talk to it bidirectionally.
68 * Drop user and group privileges in the child process if requested.
71 spawn(struct link
* link
, void (* proc
)(struct link
*), int drop
)
80 if (pipe(up
) != 0) e(0);
81 if (pipe(dn
) != 0) e(0);
90 link
->pid
= getppid();
98 if (setgroups(0, NULL
) != 0) e(0);
100 if ((gr
= getgrnam(NONROOT_GROUP
)) == NULL
) e(0);
102 if (setgid(gr
->gr_gid
) != 0) e(0);
103 if (setegid(gr
->gr_gid
) != 0) e(0);
107 if ((pw
= getpwnam(NONROOT_USER
)) == NULL
) e(0);
109 if (setuid(pw
->pw_uid
) != 0) e(0);
114 /* Close our pipe FDs on exit, so that we can make zombies. */
129 * Wait for a child process to terminate, and clean up.
132 collect(struct link
* link
)
139 if (waitpid(link
->pid
, &status
, 0) != link
->pid
) e(0);
141 if (!WIFEXITED(status
)) e(0);
142 else errct
+= WEXITSTATUS(status
);
146 * Forcibly terminate a child process, and clean up.
149 terminate(struct link
* link
)
153 if (kill(link
->pid
, SIGKILL
) != 0) e(0);
158 if (waitpid(link
->pid
, &status
, 0) <= 0) e(0);
160 if (WIFSIGNALED(status
)) {
161 if (WTERMSIG(status
) != SIGKILL
) e(0);
163 if (!WIFEXITED(status
)) e(0);
164 else errct
+= WEXITSTATUS(status
);
169 * Send an integer value to the child or parent.
172 snd(struct link
* link
, int val
)
175 if (write(link
->sndfd
, (void *)&val
, sizeof(val
)) != sizeof(val
)) e(0);
179 * Receive an integer value from the child or parent, or -1 on EOF.
182 rcv(struct link
* link
)
186 if ((r
= read(link
->rcvfd
, (void *)&val
, sizeof(val
))) == 0)
189 if (r
!= sizeof(val
)) e(0);
195 * Child procedure that creates semaphore sets.
198 test_perm_child(struct link
* parent
)
202 struct semid_ds semds
;
205 int mask
, rmask
, sugid
, id
[3];
208 * Repeatedly create a number of semaphores with the masks provided by
209 * the parent process.
211 while ((mask
= rcv(parent
)) != -1) {
216 * Create the semaphores. For KEY_A, if we are going to set
217 * the mode through IPC_SET anyway, start with a zero mask to
218 * check that the replaced mode is used (thus testing IPC_SET).
220 if ((id
[0] = semget(KEY_A
, 3,
221 IPC_CREAT
| IPC_EXCL
|
222 ((sugid
== SUGID_NONE
) ? mask
: 0))) == -1) e(0);
223 if ((id
[1] = semget(KEY_B
, 3,
224 IPC_CREAT
| IPC_EXCL
| mask
| rmask
)) == -1) e(0);
225 if ((id
[2] = semget(KEY_C
, 3,
226 IPC_CREAT
| IPC_EXCL
| rmask
)) == -1) e(0);
230 if (sugid
!= SUGID_NONE
) {
232 case SUGID_ROOT_USER
:
233 if ((pw
= getpwnam(ROOT_USER
)) == NULL
) e(0);
236 case SUGID_NONROOT_USER
:
237 if ((pw
= getpwnam(NONROOT_USER
)) == NULL
)
241 case SUGID_ROOT_GROUP
:
242 if ((gr
= getgrnam(ROOT_GROUP
)) == NULL
) e(0);
245 case SUGID_NONROOT_GROUP
:
246 if ((gr
= getgrnam(NONROOT_GROUP
)) == NULL
)
252 semds
.sem_perm
.uid
= uid
;
253 semds
.sem_perm
.gid
= gid
;
254 semds
.sem_perm
.mode
= mask
;
255 if (semctl(id
[0], 0, IPC_SET
, &semds
) != 0) e(0);
256 semds
.sem_perm
.mode
= mask
| rmask
;
257 if (semctl(id
[1], 0, IPC_SET
, &semds
) != 0) e(0);
258 semds
.sem_perm
.mode
= rmask
;
259 if (semctl(id
[2], 0, IPC_SET
, &semds
) != 0) e(0);
262 /* Do a quick test to confirm the right privileges. */
264 if (semctl(id
[0], 0, IPC_STAT
, &semds
) != 0) e(0);
265 if (semds
.sem_perm
.mode
!= (SEM_ALLOC
| mask
)) e(0);
266 if (semds
.sem_perm
.uid
!= uid
) e(0);
267 if (semds
.sem_perm
.gid
!= gid
) e(0);
268 if (semds
.sem_perm
.cuid
!= geteuid()) e(0);
269 if (semds
.sem_perm
.cgid
!= getegid()) e(0);
276 /* The other child process runs here. */
278 if (rcv(parent
) != 0) e(0);
281 * For owner tests, the other child may already have removed
282 * the semaphore sets, so ignore return values here.
284 (void)semctl(id
[0], 0, IPC_RMID
);
285 (void)semctl(id
[1], 0, IPC_RMID
);
286 (void)semctl(id
[2], 0, IPC_RMID
);
291 * Perform a permission test. The given procedure will be called for various
292 * access masks, which it can use to determine whether operations on three
293 * created semaphore sets should succeed or fail. The first two semaphore sets
294 * are created with appropriate privileges, the third one is not. If the
295 * 'owner_test' variable is set, the test will change slightly so as to allow
296 * testing of operations that require a matching uid/cuid.
299 test_perm(void (* proc
)(struct link
*), int owner_test
)
301 struct link child1
, child2
;
302 int n
, shift
, bit
, mask
, rmask
, drop1
, drop2
, sugid
, id
[3];
304 for (n
= 0; n
< 7; n
++) {
306 * Child 1 creates the semaphores, and child 2 opens them.
307 * For shift 6 (0700), child 1 drops its privileges to match
308 * child 2's (n=0). For shift 3 (0070), child 2 drops its user
309 * privileges (n=3). For shift 0 (0007), child 2 drops its
310 * group in addition to its user privileges (n=6). Also try
311 * with differing uid/cuid (n=1,2) and gid/cgid (n=4,5), where
312 * the current ownership (n=1,4) or the creator's ownership
326 sugid
= SUGID_NONROOT_USER
;
332 sugid
= SUGID_ROOT_USER
;
344 sugid
= SUGID_NONROOT_GROUP
;
347 /* The root group has no special privileges. */
351 sugid
= SUGID_NONROOT_GROUP
;
361 spawn(&child1
, test_perm_child
, drop1
);
362 spawn(&child2
, proc
, drop2
);
364 for (bit
= 0; bit
<= 7; bit
++) {
366 rmask
= 0777 & ~(7 << shift
);
371 id
[0] = rcv(&child1
);
372 id
[1] = rcv(&child1
);
373 id
[2] = rcv(&child1
);
375 snd(&child2
, (owner_test
) ? shift
: bit
);
379 if (rcv(&child2
) != 0) e(0);
384 /* We use a bitmask of -1 to terminate the children. */
394 * Test semget(2) permission checks. Please note that the checks are advisory:
395 * nothing keeps a process from opening a semaphore set with fewer privileges
396 * than required by the operations the process subsequently issues on the set.
399 test88a_perm(struct link
* parent
)
401 int r
, tbit
, bit
, mask
, id
[3];
403 while ((tbit
= rcv(parent
)) != -1) {
409 * We skip setting lower bits, as it is not clear what effect
410 * that should have. We assume that zero bits should result in
413 for (bit
= 0; bit
<= 7; bit
++) {
417 * Opening semaphore set A must succeed iff the given
418 * bits are all set in the relevant three-bit section
419 * of the creation mask.
421 r
= semget(KEY_A
, 0, mask
);
422 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
423 if ((bit
!= 0 && (bit
& tbit
) == bit
) != (r
!= -1))
425 if (r
!= -1 && r
!= id
[0]) e(0);
428 * Same for semaphore set B, which was created with all
429 * irrelevant mode bits inverted.
431 r
= semget(KEY_B
, 0, mask
);
432 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
433 if ((bit
!= 0 && (bit
& tbit
) == bit
) != (r
!= -1))
435 if (r
!= -1 && r
!= id
[1]) e(0);
438 * Semaphore set C was created with only irrelevant
439 * mode bits set, so opening it must always fail.
441 if (semget(KEY_C
, 0, mask
) != -1) e(0);
442 if (errno
!= EACCES
) e(0);
450 * Test the basic semget(2) functionality.
455 struct seminfo seminfo
;
456 struct semid_ds semds
;
464 * The key IPC_PRIVATE must always yield a new semaphore set identifier
465 * regardless of whether IPC_CREAT and IPC_EXCL are supplied.
467 if ((id
[0] = semget(IPC_PRIVATE
, 1, IPC_CREAT
| 0600)) < 0) e(0);
469 if ((id
[1] = semget(IPC_PRIVATE
, 1, IPC_CREAT
| IPC_EXCL
| 0600)) < 0)
472 if ((id
[2] = semget(IPC_PRIVATE
, 1, 0600)) < 0) e(0);
474 if (id
[0] == id
[1]) e(0);
475 if (id
[1] == id
[2]) e(0);
476 if (id
[0] == id
[2]) e(0);
478 if (semctl(id
[0], 0, IPC_RMID
) != 0) e(0);
479 if (semctl(id
[1], 0, IPC_RMID
) != 0) e(0);
480 if (semctl(id
[2], 0, IPC_RMID
) != 0) e(0);
482 /* Remove any leftovers from previous test runs. */
483 if ((id
[0] = semget(KEY_A
, 0, 0600)) >= 0 &&
484 semctl(id
[0], 0, IPC_RMID
) == -1) e(0);
485 if ((id
[0] = semget(KEY_B
, 0, 0600)) >= 0 &&
486 semctl(id
[0], 0, IPC_RMID
) == -1) e(0);
489 * For non-IPC_PRIVATE keys, open(2)-like semantics apply with respect
490 * to IPC_CREAT and IPC_EXCL flags. The behavior of supplying IPC_EXCL
491 * without IPC_CREAT is undefined, so we do not test for that here.
493 if (semget(KEY_A
, 1, 0600) != -1) e(0);
494 if (errno
!= ENOENT
);
496 if ((id
[0] = semget(KEY_A
, 1, IPC_CREAT
| IPC_EXCL
| 0600)) < 0) e(0);
498 if (semget(KEY_B
, 1, 0600) != -1) e(0);
499 if (errno
!= ENOENT
);
501 if ((id
[1] = semget(KEY_B
, 1, IPC_CREAT
| 0600)) < 0) e(0);
503 if (id
[0] == id
[1]) e(0);
505 if ((id
[2] = semget(KEY_A
, 1, 0600)) < 0) e(0);
506 if (id
[2] != id
[0]) e(0);
508 if ((id
[2] = semget(KEY_B
, 1, IPC_CREAT
| 0600)) < 0) e(0);
509 if (id
[2] != id
[2]) e(0);
511 if (semget(KEY_A
, 1, IPC_CREAT
| IPC_EXCL
| 0600) != -1) e(0);
512 if (errno
!= EEXIST
) e(0);
514 if (semctl(id
[0], 0, IPC_RMID
) != 0) e(0);
515 if (semctl(id
[1], 0, IPC_RMID
) != 0) e(0);
518 * Check that we get the right error when we run out of semaphore sets.
519 * It is possible that other processes in the system are using sets
520 * right now, so see if we can anywhere from three (the number we had
521 * already) to SEMMNI semaphore sets, and check for ENOSPC after that.
523 if (semctl(0, 0, IPC_INFO
, &seminfo
) == -1) e(0);
524 if (seminfo
.semmni
< 3 || seminfo
.semmni
> USHRT_MAX
) e(0);
526 if ((idp
= malloc(sizeof(int) * (seminfo
.semmni
+ 1))) == NULL
) e(0);
528 for (i
= 0; i
< seminfo
.semmni
+ 1; i
++) {
529 if ((idp
[i
] = semget(KEY_A
+ i
, 1, IPC_CREAT
| 0600)) < 0)
532 /* Ensure that there are no ID collisions. O(n**2). */
533 for (j
= 0; j
< i
; j
++)
534 if (idp
[i
] == idp
[j
]) e(0);
537 if (errno
!= ENOSPC
) e(0);
539 if (i
== seminfo
.semmni
+ 1) e(0);
542 if (semctl(idp
[i
], 0, IPC_RMID
) != 0) e(0);
547 * The given number of semaphores must be within bounds.
549 if (semget(KEY_A
, -1, IPC_CREAT
| 0600) != -1) e(0);
550 if (errno
!= EINVAL
) e(0);
552 if (semget(KEY_A
, 0, IPC_CREAT
| 0600) != -1) e(0);
553 if (errno
!= EINVAL
) e(0);
555 if (seminfo
.semmsl
< 3 || seminfo
.semmsl
> USHRT_MAX
) e(0);
556 if (semget(KEY_A
, seminfo
.semmsl
+ 1, IPC_CREAT
| 0600) != -1) e(0);
557 if (errno
!= EINVAL
) e(0);
559 if ((id
[0] = semget(KEY_A
, seminfo
.semmsl
, IPC_CREAT
| 0600)) < 0)
561 if (semctl(id
[0], 0, IPC_RMID
) != 0) e(0);
563 if ((id
[0] = semget(KEY_A
, 2, IPC_CREAT
| 0600)) < 0) e(0);
565 if ((id
[1] = semget(KEY_A
, 0, 0600)) < 0) e(0);
566 if (id
[0] != id
[1]) e(0);
568 if ((id
[1] = semget(KEY_A
, 1, 0600)) < 0) e(0);
569 if (id
[0] != id
[1]) e(0);
571 if ((id
[1] = semget(KEY_A
, 2, 0600)) < 0) e(0);
572 if (id
[0] != id
[1]) e(0);
574 if ((id
[1] = semget(KEY_A
, 3, 0600)) != -1) e(0);
575 if (errno
!= EINVAL
) e(0);
577 if ((id
[1] = semget(KEY_A
, seminfo
.semmsl
+ 1, 0600)) != -1) e(0);
578 if (errno
!= EINVAL
) e(0);
580 if (semctl(id
[0], 0, IPC_RMID
) != 0) e(0);
583 * Verify that the initial values for the semaphore set are as
587 if (seminfo
.semmns
< 3 + seminfo
.semmsl
) e(0);
588 if ((id
[0] = semget(IPC_PRIVATE
, 3, IPC_CREAT
| IPC_EXCL
| 0642)) < 0)
590 if ((id
[1] = semget(KEY_A
, seminfo
.semmsl
, IPC_CREAT
| 0613)) < 0)
593 if (semctl(id
[0], 0, IPC_STAT
, &semds
) != 0) e(0);
594 if (semds
.sem_perm
.uid
!= geteuid()) e(0);
595 if (semds
.sem_perm
.gid
!= getegid()) e(0);
596 if (semds
.sem_perm
.cuid
!= geteuid()) e(0);
597 if (semds
.sem_perm
.cgid
!= getegid()) e(0);
598 if (semds
.sem_perm
.mode
!= (SEM_ALLOC
| 0642)) e(0);
599 if (semds
.sem_perm
._key
!= IPC_PRIVATE
) e(0);
600 if (semds
.sem_nsems
!= 3) e(0);
601 if (semds
.sem_otime
!= 0) e(0);
602 if (semds
.sem_ctime
< now
|| semds
.sem_ctime
>= now
+ 10) e(0);
604 for (i
= 0; i
< semds
.sem_nsems
; i
++)
605 TEST_SEM(id
[0], i
, 0, 0, 0, 0);
607 if (semctl(id
[1], 0, IPC_STAT
, &semds
) != 0) e(0);
608 if (semds
.sem_perm
.uid
!= geteuid()) e(0);
609 if (semds
.sem_perm
.gid
!= getegid()) e(0);
610 if (semds
.sem_perm
.cuid
!= geteuid()) e(0);
611 if (semds
.sem_perm
.cgid
!= getegid()) e(0);
612 if (semds
.sem_perm
.mode
!= (SEM_ALLOC
| 0613)) e(0);
613 if (semds
.sem_perm
._key
!= KEY_A
) e(0);
614 if (semds
.sem_nsems
!= seminfo
.semmsl
) e(0);
615 if (semds
.sem_otime
!= 0) e(0);
616 if (semds
.sem_ctime
< now
|| semds
.sem_ctime
>= now
+ 10) e(0);
618 for (i
= 0; i
< semds
.sem_nsems
; i
++)
619 TEST_SEM(id
[1], i
, 0, 0, 0, 0);
621 if (semctl(id
[1], 0, IPC_RMID
) != 0) e(0);
622 if (semctl(id
[0], 0, IPC_RMID
) != 0) e(0);
625 * Finally, perform a number of permission-related checks. Since the
626 * main test program is running with superuser privileges, most of the
627 * permission tests use an unprivileged child process.
629 /* The superuser can always open and destroy a semaphore set. */
630 if ((id
[0] = semget(KEY_A
, 1, IPC_CREAT
| IPC_EXCL
| 0000)) < 0) e(0);
632 if ((id
[1] = semget(KEY_A
, 0, 0600)) < 0) e(0);
633 if (id
[0] != id
[1]) e(0);
635 if ((id
[1] = semget(KEY_A
, 0, 0000)) < 0) e(0);
636 if (id
[0] != id
[1]) e(0);
638 if (semctl(id
[0], 0, IPC_RMID
) != 0) e(0);
641 * When an unprivileged process tries to open a semaphore set, the
642 * given upper three permission bits from the mode (0700) are tested
643 * against the appropriate permission bits from the semaphore set.
645 test_perm(test88a_perm
, 0 /*owner_test*/);
649 * Test semop(2) permission checks.
652 test88b_perm(struct link
* parent
)
654 struct sembuf sops
[2];
656 int i
, r
, tbit
, bit
, id
[3];
658 while ((tbit
= rcv(parent
)) != -1) {
664 * This loop is designed such that failure of any bit-based
665 * subset will not result in subsequent operations blocking.
667 for (i
= 0; i
< 8; i
++) {
668 memset(sops
, 0, sizeof(sops
));
703 * Two operations on the same semaphore. As
704 * such, this verifies that operations are
705 * processed in array order.
714 * Test the order of checks. Since IPC_STAT
715 * requires read permission, it is reasonable
716 * that the check against sem_nsems be done
717 * only after the permission check as well.
718 * For this test we rewrite EFBIG to OK below.
720 sops
[0].sem_num
= USHRT_MAX
;
726 r
= semop(id
[0], sops
, nsops
);
727 if (i
== 7 && r
== -1 && errno
== EFBIG
) r
= 0;
728 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
729 if (((bit
& tbit
) == bit
) != (r
!= -1)) e(0);
731 r
= semop(id
[1], sops
, nsops
);
732 if (i
== 7 && r
== -1 && errno
== EFBIG
) r
= 0;
733 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
734 if (((bit
& tbit
) == bit
) != (r
!= -1)) e(0);
736 if (semop(id
[2], sops
, nsops
) != -1) e(0);
737 if (errno
!= EACCES
) e(0);
751 if (sig
!= SIGHUP
) e(0);
752 if (nr_signals
!= 0) e(0);
757 * Child process for semop(2) tests, mainly testing blocking operations.
760 test88b_child(struct link
* parent
)
762 struct sembuf sops
[5];
763 struct sigaction act
;
768 memset(sops
, 0, sizeof(sops
));
769 if (semop(id
, sops
, 1) != 0) e(0);
771 if (rcv(parent
) != 1) e(0);
774 if (semop(id
, sops
, 1) != 0) e(0);
776 if (rcv(parent
) != 2) e(0);
784 if (semop(id
, sops
, 3) != 0) e(0);
786 if (rcv(parent
) != 3) e(0);
798 if (semop(id
, sops
, 5) != 0) e(0);
800 if (rcv(parent
) != 4) e(0);
806 if (semop(id
, sops
, 2) != 0) e(0);
808 if (rcv(parent
) != 5) e(0);
814 sops
[1].sem_flg
= IPC_NOWAIT
;
815 if (semop(id
, sops
, 2) != 0) e(0);
817 if (rcv(parent
) != 6) e(0);
823 sops
[1].sem_flg
= IPC_NOWAIT
;
824 if (semop(id
, sops
, 2) != -1) e(0);
825 if (errno
!= EAGAIN
) e(0);
827 if (rcv(parent
) != 7) e(0);
834 if (semop(id
, sops
, 2) != 0) e(0);
836 if (rcv(parent
) != 8) e(0);
842 if (semop(id
, sops
, 2) != -1) e(0);
843 if (errno
!= ERANGE
) e(0);
845 memset(&act
, 0, sizeof(act
));
846 act
.sa_handler
= got_signal
;
847 sigfillset(&act
.sa_mask
);
848 if (sigaction(SIGHUP
, &act
, NULL
) != 0) e(0);
850 if (rcv(parent
) != 9) e(0);
852 memset(sops
, 0, sizeof(sops
));
859 if (semop(id
, sops
, 3) != -1)
860 if (errno
!= EINTR
) e(0);
861 if (nr_signals
!= 1) e(0);
863 TEST_SEM(id
, 0, 0, parent
->pid
, 0, 0);
864 TEST_SEM(id
, 1, 1, parent
->pid
, 0, 0);
866 if (rcv(parent
) != 10) e(0);
868 memset(sops
, 0, sizeof(sops
));
870 if (semop(id
, sops
, 1) != -1) e(0);
871 if (errno
!= EIDRM
) e(0);
879 if (semop(id
, sops
, 2) != -1) e(0);
880 if (errno
!= ERANGE
) e(0);
882 if (rcv(parent
) != 11) e(0);
888 if (semop(id
, sops
, 2) != 0) e(0);
896 if (semop(id
, sops
, 2) != 0) e(0);
899 if (rcv(parent
) != 12) e(0);
901 /* The child will be killed during this call. It should not return. */
906 (void)semop(id
, sops
, 2);
912 * Test the basic semop(2) functionality.
917 struct seminfo seminfo
;
918 struct semid_ds semds
;
919 struct sembuf
*sops
, *sops2
;
923 unsigned short val
[2];
928 /* Allocate a buffer for operations. */
929 if (semctl(0, 0, IPC_INFO
, &seminfo
) == -1) e(0);
931 if (seminfo
.semopm
< 3 || seminfo
.semopm
> USHRT_MAX
) e(0);
933 size
= sizeof(sops
[0]) * (seminfo
.semopm
+ 1);
934 if ((sops
= malloc(size
)) == NULL
) e(0);
935 memset(sops
, 0, size
);
937 /* Do a few first tests with a set containing one semaphore. */
938 if ((id
= semget(IPC_PRIVATE
, 1, IPC_CREAT
| 0600)) == -1) e(0);
940 /* If no operations are given, the call should succeed. */
941 if (semop(id
, NULL
, 0) != 0) e(0);
944 * If any operations are given, the pointer must be valid. Moreover,
945 * partially valid buffers must never be processed partially.
947 if (semop(id
, NULL
, 1) != -1) e(0);
948 if (errno
!= EFAULT
) e(0);
950 if (semop(id
, bad_ptr
, 1) != -1) e(0);
951 if (errno
!= EFAULT
) e(0);
953 memset(page_ptr
, 0, page_size
);
954 sops2
= ((struct sembuf
*)bad_ptr
) - 1;
956 if (semop(id
, sops2
, 2) != -1) e(0);
957 if (errno
!= EFAULT
) e(0);
959 TEST_SEM(id
, 0, 0, 0, 0, 0);
960 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
961 if (semds
.sem_otime
!= 0) e(0);
964 * A new semaphore set is initialized to an all-zeroes state, and a
965 * zeroed operation tests for a zeroed semaphore. This should pass.
968 if (semop(id
, sops
, 1) != 0) e(0);
970 TEST_SEM(id
, 0, 0, getpid(), 0, 0);
971 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
972 if (semds
.sem_otime
< now
|| semds
.sem_otime
>= now
+ 10) e(0);
974 /* Test the limit on the number of operations. */
975 if (semop(id
, sops
, seminfo
.semopm
) != 0) e(0);
977 if (semop(id
, sops
, seminfo
.semopm
+ 1) != -1) e(0);
978 if (errno
!= E2BIG
) e(0);
980 if (semop(id
, sops
, SIZE_MAX
) != -1) e(0);
981 if (errno
!= E2BIG
) e(0);
983 /* Test the range check on the semaphore numbers. */
985 if (semop(id
, sops
, 2) != -1) e(0);
986 if (errno
!= EFBIG
) e(0);
988 sops
[1].sem_num
= USHRT_MAX
;
989 if (semop(id
, sops
, 2) != -1) e(0);
990 if (errno
!= EFBIG
) e(0);
993 * Test nonblocking operations on a single semaphore, starting with
994 * value limit and overflow cases.
996 if (seminfo
.semvmx
< 3 || seminfo
.semvmx
> SHRT_MAX
) e(0);
998 sops
[0].sem_flg
= IPC_NOWAIT
;
1000 /* This block does not trigger on MINIX3. */
1001 if (seminfo
.semvmx
< SHRT_MAX
) {
1002 sops
[0].sem_op
= seminfo
.semvmx
+ 1;
1003 if (semop(id
, sops
, 1) != -1) e(0);
1004 if (errno
!= ERANGE
) e(0);
1005 if (semctl(id
, 0, GETVAL
) != 0) e(0);
1008 sops
[0].sem_op
= seminfo
.semvmx
;
1009 if (semop(id
, sops
, 1) != 0) e(0);
1010 if (semctl(id
, 0, GETVAL
) != seminfo
.semvmx
) e(0);
1012 /* As of writing, the proper checks for this is missing on NetBSD. */
1014 if (semop(id
, sops
, 1) != -1) e(0);
1015 if (errno
!= ERANGE
) e(0);
1016 if (semctl(id
, 0, GETVAL
) != seminfo
.semvmx
) e(0);
1018 sops
[0].sem_op
= seminfo
.semvmx
;
1019 if (semop(id
, sops
, 1) != -1) e(0);
1020 if (errno
!= ERANGE
) e(0);
1021 if (semctl(id
, 0, GETVAL
) != seminfo
.semvmx
) e(0);
1023 sops
[0].sem_op
= SHRT_MAX
;
1024 if (semop(id
, sops
, 1) != -1) e(0);
1025 if (errno
!= ERANGE
) e(0);
1026 if (semctl(id
, 0, GETVAL
) != seminfo
.semvmx
) e(0);
1028 /* This block does trigger on MINIX3. */
1029 if (seminfo
.semvmx
< -(int)SHRT_MIN
) {
1030 sops
[0].sem_op
= -seminfo
.semvmx
- 1;
1031 if (semop(id
, sops
, 1) != -1) e(0);
1032 if (errno
!= EAGAIN
) e(0);
1033 if (semctl(id
, 0, GETVAL
) != seminfo
.semvmx
) e(0);
1036 sops
[0].sem_op
= -seminfo
.semvmx
;
1037 if (semop(id
, sops
, 1) != 0) e(0);
1038 if (semctl(id
, 0, GETVAL
) != 0) e(0);
1041 * Test basic nonblocking operations on a single semaphore.
1044 if (semop(id
, sops
, 1) != 0) e(0);
1047 if (semop(id
, sops
, 1) != 0) e(0);
1048 if (semctl(id
, 0, GETVAL
) != 2) e(0);
1051 if (semop(id
, sops
, 1) != -1) e(0);
1052 if (errno
!= EAGAIN
) e(0);
1054 sops
[0].sem_op
= -3;
1055 if (semop(id
, sops
, 1) != -1) e(0);
1056 if (errno
!= EAGAIN
) e(0);
1059 if (semop(id
, sops
, 1) != 0) e(0);
1060 if (semctl(id
, 0, GETVAL
) != 3) e(0);
1062 sops
[0].sem_op
= -1;
1063 if (semop(id
, sops
, 1) != 0) e(0);
1064 if (semctl(id
, 0, GETVAL
) != 2) e(0);
1067 if (semop(id
, sops
, 1) != -1) e(0);
1068 if (errno
!= EAGAIN
) e(0);
1070 sops
[0].sem_op
= -2;
1071 if (semop(id
, sops
, 1) != 0) e(0);
1072 if (semctl(id
, 0, GETVAL
) != 0) e(0);
1075 if (semop(id
, sops
, 1) != 0) e(0);
1077 /* Make sure that not too much data is being read in. */
1080 if (semop(id
, sops2
, 2) != 0) e(0);
1082 /* Even if no operations are given, the identifier must be valid. */
1083 if (semctl(id
, 0, IPC_RMID
) != 0) e(0);
1085 if (semop(id
, NULL
, 0) != -1) e(0);
1086 if (errno
!= EINVAL
) e(0);
1088 if (semop(-1, NULL
, 0) != -1) e(0);
1089 if (errno
!= EINVAL
) e(0);
1091 if (semop(INT_MIN
, NULL
, 0) != -1) e(0);
1092 if (errno
!= EINVAL
) e(0);
1094 memset(&semds
, 0, sizeof(semds
));
1095 id
= IXSEQ_TO_IPCID(seminfo
.semmni
, semds
.sem_perm
);
1096 if (semop(id
, NULL
, 0) != -1) e(0);
1097 if (errno
!= EINVAL
) e(0);
1100 * Test permission checks. As part of this, test basic nonblocking
1101 * multi-operation calls, including operation processing in array order
1102 * and the order of (permission vs other) checks.
1104 test_perm(test88b_perm
, 0 /*owner_test*/);
1107 * Test blocking operations, starting with a single blocking operation.
1109 if ((id
= semget(IPC_PRIVATE
, 3, 0600)) == -1) e(0);
1111 memset(sops
, 0, sizeof(sops
[0]));
1113 if (semop(id
, sops
, 1) != 0) e(0);
1115 TEST_SEM(id
, 0, 1, getpid(), 0, 0);
1117 spawn(&child
, test88b_child
, DROP_NONE
);
1122 * In various places, we have to sleep in order to allow the child to
1123 * get itself blocked in a semop(2) call.
1127 TEST_SEM(id
, 0, 1, getpid(), 0, 1);
1129 sops
[0].sem_op
= -1;
1130 if (semop(id
, sops
, 1) != 0) e(0);
1134 TEST_SEM(id
, 0, 0, child
.pid
, 0, 0);
1137 if (semop(id
, sops
, 1) != 0) e(0);
1139 TEST_SEM(id
, 0, 1, getpid(), 0, 0);
1145 TEST_SEM(id
, 0, 1, getpid(), 1, 0);
1147 /* This should cause a (fruitless) retry of the blocking operation. */
1149 if (semop(id
, sops
, 1) != 0) e(0);
1153 TEST_SEM(id
, 0, 2, getpid(), 1, 0);
1156 if (semop(id
, sops
, 1) != 0) e(0);
1160 TEST_SEM(id
, 0, 0, child
.pid
, 0, 0);
1163 * Test blocking operations, verifying the correct operation of
1164 * multiple (partially) blocking operations and atomicity.
1166 memset(sops
, 0, sizeof(sops
[0]) * 2);
1167 if (semop(id
, sops
, 1) != 0) e(0);
1169 /* One blocking operation. */
1174 TEST_SEM(id
, 0, 0, getpid(), 0, 0);
1175 TEST_SEM(id
, 1, 0, 0, 1, 0);
1176 TEST_SEM(id
, 2, 0, 0, 0, 0);
1178 sops
[0].sem_num
= 1;
1180 if (semop(id
, sops
, 1) != 0) e(0);
1184 TEST_SEM(id
, 0, 1, child
.pid
, 0, 0);
1185 TEST_SEM(id
, 1, 0, child
.pid
, 0, 0);
1186 TEST_SEM(id
, 2, 2, child
.pid
, 0, 0);
1188 /* Two blocking operations in one call, resolved at once. */
1193 TEST_SEM(id
, 0, 1, child
.pid
, 0, 1);
1194 TEST_SEM(id
, 1, 0, child
.pid
, 0, 0);
1195 TEST_SEM(id
, 2, 2, child
.pid
, 0, 0);
1197 sops
[0].sem_num
= 0;
1198 sops
[0].sem_op
= -1;
1199 sops
[1].sem_num
= 2;
1200 sops
[1].sem_op
= -2;
1201 if (semop(id
, sops
, 2) != 0) e(0);
1205 TEST_SEM(id
, 0, 0, child
.pid
, 0, 0);
1206 TEST_SEM(id
, 1, 1, child
.pid
, 0, 0);
1207 TEST_SEM(id
, 2, 1, child
.pid
, 0, 0);
1209 /* Two blocking operations in one call, resolved one by one. */
1214 TEST_SEM(id
, 0, 0, child
.pid
, 0, 0);
1215 TEST_SEM(id
, 1, 1, child
.pid
, 1, 0);
1216 TEST_SEM(id
, 2, 1, child
.pid
, 0, 0);
1218 sops
[0].sem_num
= 1;
1220 if (semop(id
, sops
, 1) != 0) e(0);
1224 TEST_SEM(id
, 0, 0, child
.pid
, 0, 0);
1225 TEST_SEM(id
, 1, 2, getpid(), 0, 0);
1226 TEST_SEM(id
, 2, 1, child
.pid
, 0, 1);
1228 sops
[0].sem_num
= 2;
1229 sops
[0].sem_op
= -1;
1230 if (semop(id
, sops
, 1) != 0) e(0);
1234 TEST_SEM(id
, 0, 0, child
.pid
, 0, 0);
1235 TEST_SEM(id
, 1, 0, child
.pid
, 0, 0);
1236 TEST_SEM(id
, 2, 0, child
.pid
, 0, 0);
1238 /* One blocking op followed by a nonblocking one, cleared at once. */
1239 sops
[0].sem_num
= 0;
1241 sops
[1].sem_num
= 1;
1243 if (semop(id
, sops
, 2) != 0) e(0);
1249 TEST_SEM(id
, 0, 0, getpid(), 1, 0);
1250 TEST_SEM(id
, 1, 0, getpid(), 0, 0);
1252 sops
[0].sem_num
= 0;
1254 sops
[1].sem_num
= 1;
1256 if (semop(id
, sops
, 2) != 0) e(0);
1260 TEST_SEM(id
, 0, 0, child
.pid
, 0, 0);
1261 TEST_SEM(id
, 1, 0, child
.pid
, 0, 0);
1263 /* One blocking op followed by a nonblocking one, only one cleared. */
1264 sops
[0].sem_num
= 0;
1266 sops
[1].sem_num
= 1;
1268 if (semop(id
, sops
, 2) != 0) e(0);
1274 TEST_SEM(id
, 0, 1, getpid(), 0, 0);
1275 TEST_SEM(id
, 1, 1, getpid(), 0, 1);
1277 sops
[0].sem_num
= 1;
1278 sops
[0].sem_op
= -1;
1279 if (semop(id
, sops
, 1) != 0) e(0);
1283 TEST_SEM(id
, 0, 1, getpid(), 0, 0);
1284 TEST_SEM(id
, 1, 0, getpid(), 0, 0);
1287 * Ensure that all semaphore numbers are checked immediately, which
1288 * given the earlier test results also implies that permissions are
1289 * checked immediately (so we don't have to recheck that too). We do
1290 * not check whether permissions are rechecked after a blocking
1291 * operation, because the specification does not describe the intended
1292 * behavior on this point.
1294 sops
[0].sem_num
= 0;
1296 sops
[1].sem_num
= 4;
1298 if (semop(id
, sops
, 2) != -1) e(0);
1299 if (errno
!= EFBIG
) e(0);
1302 * Ensure that semaphore value overflow is detected properly, at the
1303 * moment that the operation is actually processed.
1305 sops
[0].sem_num
= 1;
1306 sops
[0].sem_op
= seminfo
.semvmx
;
1307 if (semop(id
, sops
, 1) != 0) e(0);
1313 TEST_SEM(id
, 0, 1, getpid(), 0, 1);
1314 TEST_SEM(id
, 1, seminfo
.semvmx
, getpid(), 0, 0);
1316 sops
[0].sem_num
= 0;
1317 sops
[0].sem_op
= -1;
1318 sops
[1].sem_num
= 1;
1319 sops
[1].sem_op
= -1;
1320 if (semop(id
, sops
, 2) != 0) e(0);
1322 TEST_SEM(id
, 0, 0, child
.pid
, 0, 0);
1323 TEST_SEM(id
, 1, seminfo
.semvmx
, child
.pid
, 0, 0);
1325 sops
[0].sem_num
= 1;
1326 sops
[0].sem_op
= -2;
1327 if (semop(id
, sops
, 1) != 0) e(0);
1333 TEST_SEM(id
, 0, 0, child
.pid
, 1, 0);
1334 TEST_SEM(id
, 1, seminfo
.semvmx
- 2, getpid(), 0, 0);
1336 sops
[0].sem_num
= 0;
1338 sops
[1].sem_num
= 1;
1340 if (semop(id
, sops
, 2) != 0) e(0);
1342 TEST_SEM(id
, 0, 1, getpid(), 0, 0);
1343 TEST_SEM(id
, 1, seminfo
.semvmx
- 1, getpid(), 0, 0);
1345 sops
[0].sem_num
= 0;
1346 sops
[0].sem_op
= seminfo
.semvmx
- 1;
1347 sops
[1].sem_num
= 0;
1348 sops
[1].sem_op
= seminfo
.semvmx
- 1;
1349 sops
[2].sem_num
= 0;
1352 * With the current SEMVMX, the sum of the values is now USHRT_MAX-1,
1353 * which if processed could result in a zero semaphore value. That
1354 * should not happen. Looking at you, NetBSD.
1356 if (semop(id
, sops
, 3) != -1) e(0);
1357 if (errno
!= ERANGE
) e(0);
1359 TEST_SEM(id
, 0, 1, getpid(), 0, 0);
1362 * Check that a blocking semop(2) call fails with EINTR if a signal is
1363 * caught by the process after the call has blocked.
1365 if (semctl(id
, 1, SETVAL
, 0) != 0) e(0);
1366 sops
[0].sem_num
= 0;
1367 sops
[0].sem_op
= -1;
1368 sops
[1].sem_num
= 1;
1370 if (semop(id
, sops
, 2) != 0) e(0);
1372 TEST_SEM(id
, 0, 0, getpid(), 0, 0);
1373 TEST_SEM(id
, 1, 1, getpid(), 0, 0);
1379 TEST_SEM(id
, 0, 0, getpid(), 0, 0);
1380 TEST_SEM(id
, 1, 1, getpid(), 0, 1);
1382 kill(child
.pid
, SIGHUP
);
1384 * Kills are not guaranteed to be delivered immediately to processes
1385 * other than the caller of kill(2), so let the child perform checks.
1389 * Check that a blocking semop(2) call fails with EIDRM if the
1390 * semaphore set is removed after the call has blocked.
1396 if (semctl(id
, 0, IPC_RMID
) != 0) e(0);
1399 * Check if sem_otime is updated correctly. Instead of sleeping for
1400 * whole seconds so as to be able to detect differences, use SETVAL,
1401 * which does not update sem_otime at all. This doubles as a first
1402 * test to see if SETVAL correctly wakes up a blocked semop(2) call.
1404 if ((id
= semget(IPC_PRIVATE
, 2, 0600)) == -1) e(0);
1410 TEST_SEM(id
, 0, 0, 0, 1, 0);
1411 TEST_SEM(id
, 1, 0, 0, 0, 0);
1412 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
1413 if (semds
.sem_otime
!= 0) e(0);
1415 if (semctl(id
, 1, SETVAL
, seminfo
.semvmx
) != 0) e(0);
1417 TEST_SEM(id
, 0, 0, 0, 1, 0);
1418 TEST_SEM(id
, 1, seminfo
.semvmx
, 0, 0, 0);
1419 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
1420 if (semds
.sem_otime
!= 0) e(0);
1422 if (semctl(id
, 0, SETVAL
, 1) != 0) e(0);
1423 TEST_SEM(id
, 0, 1, 0, 0, 0);
1424 TEST_SEM(id
, 1, seminfo
.semvmx
, 0, 0, 0);
1426 if (semctl(id
, 0, SETVAL
, 0) != 0) e(0);
1432 TEST_SEM(id
, 0, 0, 0, 0, 0);
1433 TEST_SEM(id
, 1, seminfo
.semvmx
, 0, 0, 1);
1434 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
1435 if (semds
.sem_otime
!= 0) e(0);
1437 if (semctl(id
, 1, SETVAL
, 0) != 0) e(0);
1439 TEST_SEM(id
, 0, 0, 0, 1, 0);
1440 TEST_SEM(id
, 1, 0, 0, 0, 0);
1441 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
1442 if (semds
.sem_otime
!= 0) e(0);
1445 if (semctl(id
, 0, SETVAL
, 2) != 0) e(0);
1447 TEST_SEM(id
, 0, 1, child
.pid
, 0, 0);
1448 TEST_SEM(id
, 1, 0, child
.pid
, 0, 0);
1449 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
1450 if (semds
.sem_otime
< now
|| semds
.sem_otime
>= now
+ 10) e(0);
1452 if (semctl(id
, 0, IPC_RMID
) != 0) e(0);
1455 * Perform a similar test for SETALL, ensuring that it causes an
1456 * ongoing semop(2) to behave correctly.
1458 if ((id
= semget(IPC_PRIVATE
, 2, 0600)) == -1) e(0);
1464 TEST_SEM(id
, 0, 0, 0, 1, 0);
1465 TEST_SEM(id
, 1, 0, 0, 0, 0);
1469 if (semctl(id
, 0, SETALL
, val
) != 0) e(0);
1471 TEST_SEM(id
, 0, 1, 0, 0, 0);
1472 TEST_SEM(id
, 1, 1, 0, 0, 1);
1476 if (semctl(id
, 0, SETALL
, val
) != 0) e(0);
1478 TEST_SEM(id
, 0, 0, 0, 1, 0);
1479 TEST_SEM(id
, 1, 1, 0, 0, 0);
1483 if (semctl(id
, 0, SETALL
, val
) != 0) e(0);
1485 TEST_SEM(id
, 0, 1, 0, 0, 0);
1486 TEST_SEM(id
, 1, 1, 0, 0, 1);
1490 if (semctl(id
, 0, SETALL
, val
) != 0) e(0);
1492 TEST_SEM(id
, 0, 0, 0, 1, 0);
1493 TEST_SEM(id
, 1, 0, 0, 0, 0);
1494 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
1495 if (semds
.sem_otime
!= 0) e(0);
1500 if (semctl(id
, 0, SETALL
, val
) != 0) e(0);
1502 TEST_SEM(id
, 0, 0, child
.pid
, 0, 0);
1503 TEST_SEM(id
, 1, 0, child
.pid
, 0, 0);
1504 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
1505 if (semds
.sem_otime
< now
|| semds
.sem_otime
>= now
+ 10) e(0);
1508 * Finally, ensure that if the child is killed, its blocked semop(2)
1509 * call is properly cancelled.
1511 sops
[0].sem_num
= 0;
1513 sops
[1].sem_num
= 1;
1515 if (semop(id
, sops
, 2) != 0) e(0);
1517 TEST_SEM(id
, 0, 0, getpid(), 0, 0);
1518 TEST_SEM(id
, 1, 0, getpid(), 0, 0);
1520 /* We'll be terminating the child, so let it report its errors now. */
1521 if (rcv(&child
) != 0) e(0);
1527 TEST_SEM(id
, 0, 0, getpid(), 0, 0);
1528 TEST_SEM(id
, 1, 0, getpid(), 1, 0);
1532 TEST_SEM(id
, 0, 0, getpid(), 0, 0);
1533 TEST_SEM(id
, 1, 0, getpid(), 0, 0);
1535 if (semctl(id
, 0, IPC_RMID
) != 0) e(0);
1541 * Test semctl(2) permission checks, part 1: regular commands.
1544 test88c_perm1(struct link
* parent
)
1546 static const int cmds
[] = { GETVAL
, GETPID
, GETNCNT
, GETZCNT
};
1547 struct semid_ds semds
;
1548 struct seminfo seminfo
;
1549 unsigned short val
[3];
1550 int i
, r
, tbit
, bit
, id
[3], cmd
;
1553 while ((tbit
= rcv(parent
)) != -1) {
1554 id
[0] = rcv(parent
);
1555 id
[1] = rcv(parent
);
1556 id
[2] = rcv(parent
);
1558 /* First the read-only, no-argument cases. */
1560 for (i
= 0; i
< __arraycount(cmds
); i
++) {
1561 r
= semctl(id
[0], 0, cmds
[i
]);
1562 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
1563 if (((bit
& tbit
) == bit
) != (r
!= -1)) e(0);
1565 r
= semctl(id
[1], 0, cmds
[i
]);
1566 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
1567 if (((bit
& tbit
) == bit
) != (r
!= -1)) e(0);
1569 if (semctl(id
[2], 0, cmds
[i
]) != -1) e(0);
1570 if (errno
!= EACCES
) e(0);
1574 * Then SETVAL, which requires write permission and is the only
1575 * one that takes an integer argument.
1578 r
= semctl(id
[0], 0, SETVAL
, 0);
1579 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
1580 if (((bit
& tbit
) == bit
) != (r
!= -1)) e(0);
1582 r
= semctl(id
[1], 0, SETVAL
, 0);
1583 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
1584 if (((bit
& tbit
) == bit
) != (r
!= -1)) e(0);
1586 if (semctl(id
[2], 0, SETVAL
, 0) != -1) e(0);
1587 if (errno
!= EACCES
) e(0);
1590 * Finally the commands that require read or write permission
1591 * and take a pointer as argument.
1593 memset(val
, 0, sizeof(val
));
1595 for (i
= 0; i
< 3; i
++) {
1616 r
= semctl(id
[0], 0, cmd
, ptr
);
1617 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
1618 if (((bit
& tbit
) == bit
) != (r
!= -1)) e(0);
1620 r
= semctl(id
[1], 0, cmd
, ptr
);
1621 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
1622 if (((bit
& tbit
) == bit
) != (r
!= -1)) e(0);
1624 if (semctl(id
[2], 0, cmd
, ptr
) != -1) e(0);
1625 if (errno
!= EACCES
) e(0);
1629 * I was hoping to avoid this, but otherwise we have to make
1630 * the other child iterate through all semaphore sets to find
1631 * the right index for each of the identifiers. As noted in
1632 * the IPC server itself as well, duplicating these macros is
1633 * not a big deal since the split is firmly hardcoded through
1634 * the exposure of IXSEQ_TO_IPCID to userland.
1637 #define IPCID_TO_IX(id) ((id) & 0xffff)
1642 r
= semctl(IPCID_TO_IX(id
[0]), 0, SEM_STAT
, &semds
);
1643 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
1644 if (((bit
& tbit
) == bit
) != (r
!= -1)) e(0);
1646 r
= semctl(IPCID_TO_IX(id
[1]), 0, SEM_STAT
, &semds
);
1647 if (r
< 0 && (r
!= -1 || errno
!= EACCES
)) e(0);
1648 if (((bit
& tbit
) == bit
) != (r
!= -1)) e(0);
1650 if (semctl(IPCID_TO_IX(id
[2]), 0, SEM_STAT
, &semds
) != -1)
1652 if (errno
!= EACCES
) e(0);
1655 * IPC_INFO and SEM_INFO should always succeed. They do not
1656 * even take a semaphore set identifier.
1658 if (semctl(0, 0, IPC_INFO
, &seminfo
) == -1) e(0);
1659 if (semctl(0, 0, SEM_INFO
, &seminfo
) == -1) e(0);
1666 * Test semctl(2) permission checks, part 2: the IPC_SET command.
1669 test88c_perm2(struct link
* parent
)
1671 struct semid_ds semds
;
1672 int r
, shift
, id
[3];
1674 while ((shift
= rcv(parent
)) != -1) {
1675 id
[0] = rcv(parent
);
1676 id
[1] = rcv(parent
);
1677 id
[2] = rcv(parent
);
1680 * Test IPC_SET. Ideally, we would set the permissions to what
1681 * they currently are, but we do not actually know what they
1682 * are, and IPC_STAT requires read permission which we may not
1683 * have! However, no matter what we do, we cannot prevent the
1684 * other child from being able to remove the semaphore sets
1685 * afterwards. So, we just set the permissions to all-zeroes;
1686 * even though those values are meaningful (mode 0000, uid 0,
1687 * gid 0) they could be anything: the API will accept anything.
1688 * This does mean we need to test IPC_RMID permissions from
1689 * another procedure, because we may now be locking ourselves
1690 * out. The System V IPC interface is pretty strange that way.
1692 memset(&semds
, 0, sizeof(semds
));
1694 r
= semctl(id
[0], 0, IPC_SET
, &semds
);
1695 if (r
< 0 && (r
!= -1 || errno
!= EPERM
)) e(0);
1696 if ((shift
== 6) != (r
!= -1)) e(0);
1698 r
= semctl(id
[1], 0, IPC_SET
, &semds
);
1699 if (r
< 0 && (r
!= -1 || errno
!= EPERM
)) e(0);
1700 if ((shift
== 6) != (r
!= -1)) e(0);
1702 /* For once, this too should succeed. */
1703 r
= semctl(id
[2], 0, IPC_SET
, &semds
);
1704 if (r
< 0 && (r
!= -1 || errno
!= EPERM
)) e(0);
1705 if ((shift
== 6) != (r
!= -1)) e(0);
1712 * Test semctl(2) permission checks, part 3: the IPC_RMID command.
1715 test88c_perm3(struct link
* parent
)
1717 int r
, shift
, id
[3];
1719 while ((shift
= rcv(parent
)) != -1) {
1720 id
[0] = rcv(parent
);
1721 id
[1] = rcv(parent
);
1722 id
[2] = rcv(parent
);
1724 r
= semctl(id
[0], 0, IPC_RMID
);
1725 if (r
< 0 && (r
!= -1 || errno
!= EPERM
)) e(0);
1726 if ((shift
== 6) != (r
!= -1)) e(0);
1728 r
= semctl(id
[1], 0, IPC_RMID
);
1729 if (r
< 0 && (r
!= -1 || errno
!= EPERM
)) e(0);
1730 if ((shift
== 6) != (r
!= -1)) e(0);
1732 /* Okay, twice then. */
1733 r
= semctl(id
[2], 0, IPC_RMID
);
1734 if (r
< 0 && (r
!= -1 || errno
!= EPERM
)) e(0);
1735 if ((shift
== 6) != (r
!= -1)) e(0);
1742 * Test the basic semctl(2) functionality.
1747 static const int cmds
[] = { GETVAL
, GETPID
, GETNCNT
, GETZCNT
};
1748 struct seminfo seminfo
;
1749 struct semid_ds semds
, osemds
;
1750 unsigned short val
[4], seen
[2];
1751 char statbuf
[sizeof(struct semid_ds
) + 1];
1754 int r
, id
, id2
, badid1
, badid2
, cmd
;
1758 if (semctl(0, 0, IPC_INFO
, &seminfo
) == -1) e(0);
1761 * Start with permission checks on the commands. IPC_SET and IPC_RMID
1762 * are special: they check for ownership (uid/cuid) and return EPERM
1763 * rather than EACCES on permission failure.
1765 test_perm(test88c_perm1
, 0 /*owner_test*/);
1766 test_perm(test88c_perm2
, 1 /*owner_test*/);
1767 test_perm(test88c_perm3
, 1 /*owner_test*/);
1769 /* Create identifiers known to be invalid. */
1770 if ((badid1
= semget(IPC_PRIVATE
, 1, 0600)) < 0) e(0);
1772 if (semctl(badid1
, 0, IPC_RMID
) != 0) e(0);
1774 memset(&semds
, 0, sizeof(semds
));
1775 badid2
= IXSEQ_TO_IPCID(seminfo
.semmni
, semds
.sem_perm
);
1777 if ((id
= semget(IPC_PRIVATE
, 3, IPC_CREAT
| 0600)) < 0) e(0);
1779 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
1780 if (semds
.sem_otime
!= 0) e(0);
1781 if (semds
.sem_ctime
== 0) e(0);
1783 /* In this case we can't avoid sleeping for longer periods.. */
1784 while (time(&now
) == semds
.sem_ctime
)
1788 * Test the simple GET commands. The actual functionality of these
1789 * commands have already been tested thoroughly as part of the
1790 * semop(2) part of the test set, so we do not repeat that here.
1792 for (i
= 0; i
< __arraycount(cmds
); i
++) {
1793 for (j
= 0; j
< 3; j
++)
1794 if (semctl(id
, j
, cmds
[i
]) != 0) e(0);
1796 if (semctl(badid1
, 0, cmds
[i
]) != -1) e(0);
1797 if (errno
!= EINVAL
) e(0);
1799 if (semctl(badid2
, 0, cmds
[i
]) != -1) e(0);
1800 if (errno
!= EINVAL
) e(0);
1802 if (semctl(-1, 0, cmds
[i
]) != -1) e(0);
1803 if (errno
!= EINVAL
) e(0);
1805 if (semctl(INT_MIN
, 0, cmds
[i
]) != -1) e(0);
1806 if (errno
!= EINVAL
) e(0);
1808 if (semctl(id
, -1, cmds
[i
]) != -1) e(0);
1809 if (errno
!= EINVAL
) e(0);
1811 if (semctl(id
, 3, cmds
[i
]) != -1) e(0);
1812 if (errno
!= EINVAL
) e(0);
1814 /* These commands should not update ctime or otime. */
1815 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
1816 if (semds
.sem_otime
!= 0) e(0);
1817 if (semds
.sem_ctime
>= now
) e(0);
1821 * Test the GETALL command.
1824 * Contrary to what the Open Group specification suggests, actual
1825 * implementations agree that the semnum parameter is to be ignored for
1826 * calls not involving a specific semaphore in the set.
1828 for (j
= 0; j
< 5; j
++) {
1829 for (i
= 0; i
< __arraycount(val
); i
++)
1832 if (semctl(id
, (int)j
- 1, GETALL
, val
) != 0) e(0);
1833 for (i
= 0; i
< 3; i
++)
1834 if (val
[i
] != 0) e(0);
1835 if (val
[i
] != USHRT_MAX
) e(0);
1838 for (i
= 0; i
< __arraycount(val
); i
++)
1841 if (semctl(badid1
, 0, GETALL
, val
) != -1) e(0);
1842 if (errno
!= EINVAL
) e(0);
1844 if (semctl(badid2
, 0, GETALL
, val
) != -1) e(0);
1845 if (errno
!= EINVAL
) e(0);
1847 if (semctl(-1, 0, GETALL
, val
) != -1) e(0);
1848 if (errno
!= EINVAL
) e(0);
1850 if (semctl(INT_MIN
, 0, GETALL
, val
) != -1) e(0);
1851 if (errno
!= EINVAL
) e(0);
1853 for (i
= 0; i
< __arraycount(val
); i
++)
1854 if (val
[i
] != USHRT_MAX
) e(0);
1856 if (semctl(id
, 0, GETALL
, NULL
) != -1) e(0);
1857 if (errno
!= EFAULT
) e(0);
1859 if (semctl(id
, 0, GETALL
, bad_ptr
) != -1) e(0);
1860 if (errno
!= EFAULT
) e(0);
1862 if (semctl(id
, 0, GETALL
, ((unsigned short *)bad_ptr
) - 2) != -1) e(0);
1863 if (errno
!= EFAULT
) e(0);
1865 if (semctl(id
, 0, GETALL
, ((unsigned short *)bad_ptr
) - 3) != 0) e(0);
1867 /* Still no change in either otime or ctime. */
1868 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
1869 if (semds
.sem_otime
!= 0) e(0);
1870 if (semds
.sem_ctime
>= now
) e(0);
1873 * Test the IPC_STAT command. This is the last command we are testing
1874 * here that does not affect sem_ctime, so in order to avoid extra
1875 * sleep times, we test this command first now.
1878 * The basic IPC_STAT functionality has already been tested heavily as
1879 * part of the semget(2) and permission tests, so we do not repeat that
1882 memset(statbuf
, 0x5a, sizeof(statbuf
));
1884 if (semctl(badid1
, 0, IPC_STAT
, statbuf
) != -1) e(0);
1885 if (errno
!= EINVAL
) e(0);
1887 if (semctl(badid2
, 0, IPC_STAT
, statbuf
) != -1) e(0);
1888 if (errno
!= EINVAL
) e(0);
1890 if (semctl(-1, 0, IPC_STAT
, statbuf
) != -1) e(0);
1891 if (errno
!= EINVAL
) e(0);
1893 if (semctl(INT_MIN
, 0, IPC_STAT
, statbuf
) != -1) e(0);
1894 if (errno
!= EINVAL
) e(0);
1896 for (i
= 0; i
< sizeof(statbuf
); i
++)
1897 if (statbuf
[i
] != 0x5a) e(0);
1899 if (semctl(id
, 0, IPC_STAT
, statbuf
) != 0) e(0);
1901 if (statbuf
[sizeof(statbuf
) - 1] != 0x5a) e(0);
1903 if (semctl(id
, 0, IPC_STAT
, NULL
) != -1) e(0);
1904 if (errno
!= EFAULT
) e(0);
1906 if (semctl(id
, 0, IPC_STAT
, bad_ptr
) != -1) e(0);
1907 if (errno
!= EFAULT
) e(0);
1909 if (semctl(id
, 0, IPC_STAT
, ((struct semid_ds
*)bad_ptr
) - 1) != 0)
1912 if (semctl(id
, -1, IPC_STAT
, &semds
) != 0) e(0);
1913 if (semds
.sem_otime
!= 0) e(0);
1914 if (semds
.sem_ctime
>= now
) e(0);
1919 if ((id2
= semget(KEY_A
, seminfo
.semmsl
, IPC_CREAT
| 0642)) < 0) e(0);
1921 memset(statbuf
, 0x5a, sizeof(statbuf
));
1923 if (semctl(-1, 0, SEM_STAT
, statbuf
) != -1) e(0);
1924 if (errno
!= EINVAL
) e(0);
1926 if (semctl(seminfo
.semmni
, 0, SEM_STAT
, statbuf
) != -1) e(0);
1927 if (errno
!= EINVAL
) e(0);
1929 for (i
= 0; i
< sizeof(statbuf
); i
++)
1930 if (statbuf
[i
] != 0x5a) e(0);
1932 memset(seen
, 0, sizeof(seen
));
1934 for (i
= 0; i
< seminfo
.semmni
; i
++) {
1936 if ((r
= semctl(i
, i
/ 2 - 1, SEM_STAT
, statbuf
)) == -1) {
1937 if (errno
!= EINVAL
) e(0);
1941 memcpy(&semds
, statbuf
, sizeof(semds
));
1942 if (!(semds
.sem_perm
.mode
& SEM_ALLOC
)) e(0);
1943 if (semds
.sem_ctime
== 0) e(0);
1944 if (IXSEQ_TO_IPCID(i
, semds
.sem_perm
) != r
) e(0);
1947 if (semds
.sem_perm
.mode
!= (SEM_ALLOC
| 0600)) e(0);
1948 if (semds
.sem_perm
.uid
!= geteuid()) e(0);
1949 if (semds
.sem_perm
.gid
!= getegid()) e(0);
1950 if (semds
.sem_perm
.cuid
!= semds
.sem_perm
.uid
) e(0);
1951 if (semds
.sem_perm
.cgid
!= semds
.sem_perm
.gid
) e(0);
1952 if (semds
.sem_perm
._key
!= IPC_PRIVATE
) e(0);
1953 if (semds
.sem_nsems
!= 3) e(0);
1954 if (semds
.sem_otime
!= 0) e(0);
1956 /* This is here because we need a valid index. */
1957 if (semctl(i
, 0, SEM_STAT
, NULL
) != -1) e(0);
1958 if (errno
!= EFAULT
) e(0);
1960 if (semctl(i
, 0, SEM_STAT
, bad_ptr
) != -1) e(0);
1961 if (errno
!= EFAULT
) e(0);
1962 } else if (r
== id2
) {
1964 if (semds
.sem_perm
.mode
!= (SEM_ALLOC
| 0642)) e(0);
1965 if (semds
.sem_perm
.uid
!= geteuid()) e(0);
1966 if (semds
.sem_perm
.gid
!= getegid()) e(0);
1967 if (semds
.sem_perm
.cuid
!= semds
.sem_perm
.uid
) e(0);
1968 if (semds
.sem_perm
.cgid
!= semds
.sem_perm
.gid
) e(0);
1969 if (semds
.sem_perm
._key
!= KEY_A
) e(0);
1970 if (semds
.sem_nsems
!= seminfo
.semmsl
) e(0);
1974 if (seen
[0] != 1) e(0);
1975 if (seen
[1] != 1) e(0);
1977 if (statbuf
[sizeof(statbuf
) - 1] != 0x5a) e(0);
1979 if (semctl(id
, 5, IPC_STAT
, &semds
) != 0) e(0);
1980 if (semds
.sem_otime
!= 0) e(0);
1981 if (semds
.sem_ctime
>= now
) e(0);
1984 * Test SETVAL. We start with all the failure cases, so as to be able
1985 * to check that sem_ctime is not changed in those cases.
1987 if (semctl(badid1
, 0, SETVAL
, 1) != -1) e(0);
1988 if (errno
!= EINVAL
) e(0);
1990 if (semctl(badid2
, 0, SETVAL
, 1) != -1) e(0);
1991 if (errno
!= EINVAL
) e(0);
1993 if (semctl(-1, 0, SETVAL
, 1) != -1) e(0);
1994 if (errno
!= EINVAL
) e(0);
1996 if (semctl(INT_MIN
, 0, SETVAL
, 1) != -1) e(0);
1997 if (errno
!= EINVAL
) e(0);
1999 if (semctl(id
, -1, SETVAL
, 1) != -1) e(0);
2000 if (errno
!= EINVAL
) e(0);
2002 if (semctl(id
, 3, SETVAL
, 1) != -1) e(0);
2003 if (errno
!= EINVAL
) e(0);
2005 if (semctl(id
, 0, SETVAL
, -1) != -1) e(0);
2006 if (errno
!= ERANGE
) e(0);
2008 if (semctl(id
, 0, SETVAL
, seminfo
.semvmx
+ 1) != -1) e(0);
2009 if (errno
!= ERANGE
) e(0);
2011 TEST_SEM(id
, 0, 0, 0, 0, 0);
2013 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
2014 if (semds
.sem_otime
!= 0) e(0);
2015 if (semds
.sem_ctime
>= now
) e(0);
2017 /* Alright, there we go.. */
2018 if (semctl(id
, 1, SETVAL
, 0) != 0) e(0);
2020 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
2021 if (semds
.sem_otime
!= 0) e(0);
2022 if (semds
.sem_ctime
< now
|| semds
.sem_ctime
>= now
+ 10) e(0);
2024 TEST_SEM(id
, 1, 0, 0, 0, 0);
2026 if (semctl(id
, 2, SETVAL
, seminfo
.semvmx
) != 0) e(0);
2028 TEST_SEM(id
, 2, seminfo
.semvmx
, 0, 0, 0);
2030 if (semctl(id
, 0, SETVAL
, 1) != 0) e(0);
2032 TEST_SEM(id
, 0, 1, 0, 0, 0);
2033 TEST_SEM(id
, 1, 0, 0, 0, 0);
2034 TEST_SEM(id
, 2, seminfo
.semvmx
, 0, 0, 0);
2036 if (semctl(id
, 0, GETALL
, val
) != 0) e(0);
2037 if (val
[0] != 1) e(0);
2038 if (val
[1] != 0) e(0);
2039 if (val
[2] != seminfo
.semvmx
) e(0);
2041 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
2043 while (time(&now
) == semds
.sem_ctime
)
2047 * Test SETALL. Same idea: failure cases first.
2049 if (semctl(badid1
, 0, SETALL
, 1) != -1) e(0);
2050 if (errno
!= EINVAL
) e(0);
2052 if (semctl(badid2
, 0, SETALL
, 1) != -1) e(0);
2053 if (errno
!= EINVAL
) e(0);
2055 if (semctl(-1, 0, SETALL
, 1) != -1) e(0);
2056 if (errno
!= EINVAL
) e(0);
2058 if (semctl(INT_MIN
, 0, SETALL
, 1) != -1) e(0);
2059 if (errno
!= EINVAL
) e(0);
2061 val
[0] = seminfo
.semvmx
+ 1;
2064 if (semctl(id
, 0, SETALL
, val
) != -1) e(0);
2065 if (errno
!= ERANGE
) e(0);
2069 val
[2] = seminfo
.semvmx
+ 1;
2070 if (semctl(id
, 0, SETALL
, val
) != -1) e(0);
2071 if (errno
!= ERANGE
) e(0);
2073 if (semctl(id
, 0, SETALL
, NULL
) != -1) e(0);
2074 if (errno
!= EFAULT
) e(0);
2076 if (semctl(id
, 0, SETALL
, bad_ptr
) != -1) e(0);
2077 if (errno
!= EFAULT
) e(0);
2079 if (semctl(id
, 0, SETALL
, ((unsigned short *)bad_ptr
) - 2) != -1) e(0);
2080 if (errno
!= EFAULT
) e(0);
2082 TEST_SEM(id
, 0, 1, 0, 0, 0);
2083 TEST_SEM(id
, 1, 0, 0, 0, 0);
2084 TEST_SEM(id
, 2, seminfo
.semvmx
, 0, 0, 0);
2086 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
2087 if (semds
.sem_otime
!= 0) e(0);
2088 if (semds
.sem_ctime
>= now
) e(0);
2090 val
[0] = seminfo
.semvmx
;
2093 if (semctl(id
, 0, SETALL
, val
) != 0) e(0);
2095 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
2096 if (semds
.sem_otime
!= 0) e(0);
2097 if (semds
.sem_ctime
< now
|| semds
.sem_ctime
>= now
+ 10) e(0);
2099 TEST_SEM(id
, 0, seminfo
.semvmx
, 0, 0, 0);
2100 TEST_SEM(id
, 1, 0, 0, 0, 0);
2101 TEST_SEM(id
, 2, 0, 0, 0, 0);
2105 val
[2] = seminfo
.semvmx
;
2106 if (semctl(id
, INT_MAX
, SETALL
, val
) != 0) e(0);
2108 TEST_SEM(id
, 0, 0, 0, 0, 0);
2109 TEST_SEM(id
, 1, 1, 0, 0, 0);
2110 TEST_SEM(id
, 2, seminfo
.semvmx
, 0, 0, 0);
2112 memset(page_ptr
, 0, page_size
);
2113 if (semctl(id
, 0, SETALL
, ((unsigned short *)bad_ptr
) - 3) != 0) e(0);
2115 TEST_SEM(id
, 0, 0, 0, 0, 0);
2116 TEST_SEM(id
, 1, 0, 0, 0, 0);
2117 TEST_SEM(id
, 2, 0, 0, 0, 0);
2119 while (time(&now
) == semds
.sem_ctime
)
2123 * Test IPC_SET. Its core functionality has already been tested
2124 * thoroughly as part of the permission tests.
2126 if (semctl(badid1
, 0, IPC_SET
, &semds
) != -1) e(0);
2127 if (errno
!= EINVAL
) e(0);
2129 if (semctl(badid2
, 0, IPC_SET
, &semds
) != -1) e(0);
2130 if (errno
!= EINVAL
) e(0);
2132 if (semctl(-1, 0, IPC_SET
, &semds
) != -1) e(0);
2133 if (errno
!= EINVAL
) e(0);
2135 if (semctl(INT_MIN
, 0, IPC_SET
, &semds
) != -1) e(0);
2136 if (errno
!= EINVAL
) e(0);
2138 if (semctl(id
, 0, IPC_SET
, NULL
) != -1) e(0);
2139 if (errno
!= EFAULT
) e(0);
2141 if (semctl(id
, 0, IPC_SET
, bad_ptr
) != -1) e(0);
2142 if (errno
!= EFAULT
) e(0);
2144 if (semctl(id
, 0, IPC_STAT
, &osemds
) != 0) e(0);
2145 if (osemds
.sem_otime
!= 0) e(0);
2146 if (osemds
.sem_ctime
>= now
) e(0);
2149 * Only mode, uid, gid may be set. While the given mode is sanitized
2150 * in our implementation (see below; the open group specification
2151 * leaves this undefined), the uid and gid are not (we do not test this
2152 * exhaustively). The other given fields must be ignored. The ctime
2153 * field will be updated.
2155 memset(&semds
, 0x5b, sizeof(semds
));
2156 semds
.sem_perm
.mode
= 0712;
2157 semds
.sem_perm
.uid
= UID_MAX
;
2158 semds
.sem_perm
.gid
= GID_MAX
- 1;
2159 if (semctl(id
, 0, IPC_SET
, &semds
) != 0) e(0);
2161 if (semctl(id
, 0, IPC_STAT
, &semds
) != 0) e(0);
2162 if (semds
.sem_perm
.mode
!= (SEM_ALLOC
| 0712)) e(0);
2163 if (semds
.sem_perm
.uid
!= UID_MAX
) e(0);
2164 if (semds
.sem_perm
.gid
!= GID_MAX
- 1) e(0);
2165 if (semds
.sem_perm
.cuid
!= osemds
.sem_perm
.cuid
) e(0);
2166 if (semds
.sem_perm
.cgid
!= osemds
.sem_perm
.cgid
) e(0);
2167 if (semds
.sem_perm
._seq
!= osemds
.sem_perm
._seq
) e(0);
2168 if (semds
.sem_perm
._key
!= osemds
.sem_perm
._key
) e(0);
2169 if (semds
.sem_nsems
!= osemds
.sem_nsems
) e(0);
2170 if (semds
.sem_otime
!= osemds
.sem_otime
) e(0);
2171 if (semds
.sem_ctime
< now
|| semds
.sem_ctime
>= now
+ 10) e(0);
2173 /* It should be possible to set any mode, but mask 0777 is applied. */
2174 semds
.sem_perm
.uid
= osemds
.sem_perm
.uid
;
2175 semds
.sem_perm
.gid
= osemds
.sem_perm
.gid
;
2176 for (i
= 0; i
< 0777; i
++) {
2177 semds
.sem_perm
.mode
= i
;
2178 if (semctl(id
, i
/ 2 - 1, IPC_SET
, &semds
) != 0) e(0);
2180 if (semctl(id
, i
/ 2 - 2, IPC_STAT
, &semds
) != 0) e(0);
2181 if (semds
.sem_perm
.mode
!= (SEM_ALLOC
| i
)) e(0);
2183 semds
.sem_perm
.mode
= ~0777 | i
;
2184 if (semctl(id
, i
/ 2 - 3, IPC_SET
, &semds
) != 0) e(0);
2186 if (semctl(id
, i
/ 2 - 4, IPC_STAT
, &semds
) != 0) e(0);
2187 if (semds
.sem_perm
.mode
!= (SEM_ALLOC
| i
)) e(0);
2189 if (semds
.sem_perm
.uid
!= osemds
.sem_perm
.uid
) e(0);
2190 if (semds
.sem_perm
.gid
!= osemds
.sem_perm
.gid
) e(0);
2192 if (semctl(id
, 0, IPC_SET
, ((struct semid_ds
*)bad_ptr
) - 1) != 0)
2196 * Test IPC_RMID. Its basic functionality has already been tested
2197 * multiple times over, so there is not much left to do here.
2199 if (semctl(badid1
, 0, IPC_RMID
) != -1) e(0);
2200 if (errno
!= EINVAL
) e(0);
2202 if (semctl(badid2
, 0, IPC_RMID
) != -1) e(0);
2203 if (errno
!= EINVAL
) e(0);
2205 if (semctl(-1, 0, IPC_RMID
) != -1) e(0);
2206 if (errno
!= EINVAL
) e(0);
2208 if (semctl(INT_MIN
, 0, IPC_RMID
) != -1) e(0);
2209 if (errno
!= EINVAL
) e(0);
2211 if (semctl(id
, 0, IPC_RMID
) != 0) e(0);
2213 if (semctl(id
, 0, IPC_RMID
) != -1) e(0);
2214 if (errno
!= EINVAL
) e(0);
2216 if (semctl(id
, 0, IPC_STAT
, &semds
) != -1) e(0);
2217 if (errno
!= EINVAL
) e(0);
2219 if (semctl(id2
, 1, IPC_RMID
) != 0) e(0);
2221 if (semctl(id2
, 1, IPC_RMID
) != -1) e(0);
2222 if (errno
!= EINVAL
) e(0);
2225 * Test IPC_INFO and SEM_INFO. Right now, for all practical purposes,
2226 * these identifiers behave pretty much the same.
2228 if ((id
= semget(IPC_PRIVATE
, 3, 0600)) == -1) e(0);
2229 if ((id2
= semget(IPC_PRIVATE
, 1, 0600)) == -1) e(0);
2231 for (i
= 0; i
<= 1; i
++) {
2232 cmd
= (i
== 0) ? IPC_INFO
: SEM_INFO
;
2234 memset(&seminfo
, 0xff, sizeof(seminfo
));
2236 if ((r
= semctl(0, 0, cmd
, &seminfo
)) == -1) e(0);
2239 * These commands return the index of the highest in-use slot
2240 * in the semaphore set table. Bad idea of course, because
2241 * that means the value 0 has two potential meanings. Since we
2242 * cannot guarantee that no other running application is using
2243 * semaphores, we settle for "at least" tests based on the two
2244 * semaphore sets we just created.
2246 if (r
< 1 || r
>= seminfo
.semmni
) e(0);
2249 * Many of these checks are rather basic because of missing
2250 * SEM_UNDO support. The only difference between IPC_INFO and
2251 * SEM_INFO is the meaning of the semusz and semaem fields.
2253 if (seminfo
.semmap
< 0) e(0);
2254 if (seminfo
.semmni
< 3 || seminfo
.semmni
> USHRT_MAX
) e(0);
2255 if (seminfo
.semmns
< 3 || seminfo
.semmns
> USHRT_MAX
) e(0);
2256 if (seminfo
.semmnu
< 0) e(0);
2257 if (seminfo
.semmsl
< 3 || seminfo
.semmsl
> USHRT_MAX
) e(0);
2258 if (seminfo
.semopm
< 3 || seminfo
.semopm
> USHRT_MAX
) e(0);
2259 if (seminfo
.semume
< 0) e(0);
2260 if (cmd
== SEM_INFO
) {
2261 if (seminfo
.semusz
< 2) e(0);
2263 if (seminfo
.semusz
< 0) e(0);
2264 if (seminfo
.semvmx
< 3 || seminfo
.semvmx
> SHRT_MAX
) e(0);
2265 if (cmd
== SEM_INFO
) {
2266 if (seminfo
.semaem
< 4) e(0);
2268 if (seminfo
.semaem
< 0) e(0);
2270 if (semctl(INT_MAX
, -1, cmd
, &seminfo
) == -1) e(0);
2271 if (semctl(-1, INT_MAX
, cmd
, &seminfo
) == -1) e(0);
2273 if (semctl(0, 0, cmd
, NULL
) != -1) e(0);
2274 if (errno
!= EFAULT
) e(0);
2276 if (semctl(0, 0, cmd
, bad_ptr
) != -1) e(0);
2277 if (errno
!= EFAULT
) e(0);
2279 if (semctl(0, 0, cmd
, ((struct seminfo
*)bad_ptr
) - 1) == -1)
2283 if (semctl(id2
, 0, IPC_RMID
) != 0) e(0);
2286 * Finally, test invalid commands. Well, hopefully invalid commands,
2289 if (semctl(id
, 0, INT_MIN
) != -1) e(0);
2290 if (errno
!= EINVAL
) e(0);
2292 if (semctl(id
, 0, INT_MAX
) != -1) e(0);
2293 if (errno
!= EINVAL
) e(0);
2295 if (semctl(id
, 0, IPC_RMID
) != 0) e(0);
2299 * Test SEM_UNDO support. Right now this functionality is missing altogether.
2300 * For now, we test that any attempt to use SEM_UNDO fails.
2310 if ((id
= semget(IPC_PRIVATE
, 1, 0600)) == -1) e(0);
2313 * Use an all-ones (but positive) flag field. This will include
2314 * SEM_UNDO, but also tell the IPC server to report no warning.
2316 if (!(SHRT_MAX
& SEM_UNDO
)) e(0);
2319 sop
.sem_flg
= SHRT_MAX
;
2320 if (semop(id
, &sop
, 1) != -1) e(0);
2321 if (errno
!= EINVAL
) e(0);
2323 if (semctl(id
, 0, IPC_RMID
) != 0) e(0);
2327 RESUME_SEMOP
, /* use semop() to resume blocked parties */
2328 RESUME_SETVAL
, /* use semctl(SETVAL) to resume blocked parties */
2329 RESUME_SETALL
, /* use semctl(SETALL) to resume blocked parties */
2334 MATCH_FIRST
, /* first match completes, blocks second match */
2335 MATCH_SECOND
, /* first match does not complete, second match does */
2336 MATCH_KILL
, /* second match completes after first is aborted */
2337 MATCH_BOTH
, /* first and second match both complete */
2338 MATCH_CASCADE
, /* completed match in turn causes another match */
2339 MATCH_ALL
, /* a combination of the last two */
2344 * Auxiliary child procedure. The auxiliary children will deadlock until the
2345 * semaphore set is removed.
2348 test88e_childaux(struct link
* parent
)
2350 struct sembuf sops
[3];
2351 struct seminfo seminfo
;
2354 child
= rcv(parent
);
2358 memset(sops
, 0, sizeof(sops
));
2360 /* These operations are guaranteed to never return successfully. */
2363 sops
[0].sem_num
= num
;
2365 sops
[1].sem_num
= num
;
2367 sops
[2].sem_num
= 0;
2371 if (semctl(0, 0, IPC_INFO
, &seminfo
) == -1) e(0);
2372 sops
[0].sem_num
= num
;
2373 sops
[0].sem_op
= -seminfo
.semvmx
;
2374 sops
[1].sem_num
= num
;
2375 sops
[1].sem_op
= -seminfo
.semvmx
;
2376 sops
[2].sem_num
= 0;
2385 if (semop(id
, sops
, 3) != -1) e(0);
2386 if (errno
!= EIDRM
) e(0);
2390 * First child procedure.
2393 test88e_child1(struct link
* parent
)
2395 struct sembuf sops
[3];
2397 int match
, id
, expect
;
2399 match
= rcv(parent
);
2402 /* Start off with some defaults, then refine by match type. */
2403 memset(sops
, 0, sizeof(sops
));
2404 sops
[0].sem_num
= 2;
2405 sops
[0].sem_op
= -1;
2410 sops
[1].sem_num
= 3;
2414 sops
[1].sem_num
= 3;
2415 sops
[1].sem_op
= -1;
2416 sops
[2].sem_num
= 0;
2422 sops
[1].sem_num
= 0;
2429 sops
[1].sem_num
= 3;
2438 if (semop(id
, sops
, nsops
) != expect
) e(0);
2439 if (expect
== -1 && errno
!= EIDRM
) e(0);
2443 * Second child procedure.
2446 test88e_child2(struct link
* parent
)
2448 struct sembuf sops
[2];
2450 int match
, id
, expect
;
2452 match
= rcv(parent
);
2455 /* Start off with some defaults, then refine by match type. */
2456 memset(sops
, 0, sizeof(sops
));
2457 sops
[0].sem_num
= 2;
2458 sops
[0].sem_op
= -1;
2463 sops
[1].sem_num
= 0;
2473 sops
[1].sem_num
= 3;
2477 sops
[0].sem_num
= 3;
2486 if (semop(id
, sops
, nsops
) != expect
) e(0);
2487 if (expect
== -1 && errno
!= EIDRM
) e(0);
2491 * Third child procedure.
2494 test88e_child3(struct link
* parent
)
2496 struct sembuf sops
[1];
2500 match
= rcv(parent
);
2503 /* Things are a bit simpler here. */
2504 memset(sops
, 0, sizeof(sops
));
2508 sops
[0].sem_num
= 3;
2509 sops
[0].sem_op
= -2;
2517 if (semop(id
, sops
, nsops
) != 0) e(0);
2521 * Perform one test for operations affecting multiple processes.
2524 sub88e(unsigned int match
, unsigned int resume
, unsigned int aux
)
2526 struct link aux1
, aux2
, child1
, child2
, child3
;
2528 unsigned short val
[4];
2529 int id
, inc
, aux_zcnt
, aux_ncnt
;
2532 * For this test we use one single semaphore set, with four semaphores.
2533 * The first semaphore is increased in the case that an operation that
2534 * should never complete does complete, and thus should stay zero.
2535 * Depending on 'aux', the second or third semaphore is used by the
2536 * auxiliary children (if any, also depending on 'aux') to deadlock on.
2537 * The third and higher semaphores are used in the main operations.
2539 if ((id
= semget(IPC_PRIVATE
, __arraycount(val
), 0666)) == -1) e(0);
2541 aux_zcnt
= aux_ncnt
= 0;
2543 /* Start the first auxiliary child if desired, before all others. */
2545 spawn(&aux1
, test88e_childaux
, DROP_ALL
);
2549 snd(&aux1
, (aux
& 4) ? 2 : 1);
2551 if (rcv(&aux1
) != 0) e(0);
2557 /* Start and configure all children for this specific match test. */
2558 spawn(&child1
, test88e_child1
, DROP_ALL
);
2560 snd(&child1
, match
);
2563 if (rcv(&child1
) != 0) e(0);
2566 * For fairness tests, we must ensure that the first child blocks on
2567 * the semaphore before the second child does.
2577 spawn(&child2
, test88e_child2
, DROP_NONE
);
2579 snd(&child2
, match
);
2582 if (rcv(&child2
) != 0) e(0);
2584 if (match
== MATCH_ALL
) {
2585 spawn(&child3
, test88e_child3
, DROP_USER
);
2587 snd(&child3
, match
);
2590 if (rcv(&child3
) != 0) e(0);
2593 /* Start the second auxiliary child if desired, after all others. */
2595 spawn(&aux2
, test88e_childaux
, DROP_NONE
);
2599 snd(&aux2
, (aux
& 4) ? 2 : 1);
2601 if (rcv(&aux2
) != 0) e(0);
2610 * Test semaphore values and determine the value with which to increase
2611 * the third semaphore. For MATCH_KILL, also kill the first child.
2617 TEST_SEM(id
, 2, 0, 0, 2 + aux_ncnt
, aux_zcnt
);
2618 TEST_SEM(id
, 3, 0, 0, 0, 0);
2621 TEST_SEM(id
, 2, 0, 0, 2 + aux_ncnt
, aux_zcnt
);
2625 /* As stated before, non-self kills need not be instant. */
2628 TEST_SEM(id
, 2, 0, 0, 1 + aux_ncnt
, aux_zcnt
);
2629 TEST_SEM(id
, 3, 0, 0, 0, 0);
2632 TEST_SEM(id
, 2, 0, 0, 2 + aux_ncnt
, aux_zcnt
);
2633 TEST_SEM(id
, 3, 0, 0, 0, 0);
2637 TEST_SEM(id
, 2, 0, 0, 1 + aux_ncnt
, aux_zcnt
);
2638 TEST_SEM(id
, 3, 0, 0, 1, 0);
2641 TEST_SEM(id
, 2, 0, 0, 2 + aux_ncnt
, aux_zcnt
);
2642 TEST_SEM(id
, 3, 0, 0, 1, 0);
2649 TEST_SEM(id
, 0, 0, 0, 0, 0);
2650 TEST_SEM(id
, 1, 0, 0, -1, -1);
2652 /* Resume the appropriate set of children. */
2655 memset(&sop
, 0, sizeof(sop
));
2658 if (semop(id
, &sop
, 1) != 0) e(0);
2661 if (semctl(id
, 2, SETVAL
, inc
) != 0) e(0);
2664 memset(val
, 0, sizeof(val
));
2666 if (semctl(id
, 0, SETALL
, val
) != 0) e(0);
2673 * See if the right children were indeed resumed, and retest the
2678 TEST_SEM(id
, 2, 0, child1
.pid
, 1 + aux_ncnt
, aux_zcnt
);
2679 TEST_SEM(id
, 3, 1, child1
.pid
, 0, 0);
2683 TEST_SEM(id
, 2, 0, child2
.pid
, 1 + aux_ncnt
, aux_zcnt
);
2684 TEST_SEM(id
, 3, 0, 0, 0, 0);
2688 TEST_SEM(id
, 2, 0, child2
.pid
, aux_ncnt
, aux_zcnt
);
2689 TEST_SEM(id
, 3, 0, 0, 0, 0);
2694 * The children are not ordered in this case, so we do not know
2695 * which one gets access to the semaphores last.
2697 TEST_SEM(id
, 2, 0, -1, aux_ncnt
, aux_zcnt
);
2698 TEST_SEM(id
, 3, 2, -1, 0, 0);
2703 TEST_SEM(id
, 2, 0, child1
.pid
, aux_ncnt
, aux_zcnt
);
2704 TEST_SEM(id
, 3, 0, child2
.pid
, 0, 0);
2709 TEST_SEM(id
, 2, 0, -1, aux_ncnt
, aux_zcnt
);
2710 TEST_SEM(id
, 3, 0, child3
.pid
, 0, 0);
2719 TEST_SEM(id
, 0, 0, 0, 0, 0);
2720 TEST_SEM(id
, 1, 0, 0, -1, -1);
2722 /* Remove the semaphore set. This should unblock remaining callers. */
2723 if (semctl(id
, 0, IPC_RMID
) != 0) e(0);
2725 /* Wait for the children that were not resumed, but should be now. */
2742 /* Wait for the auxiliary children as well. */
2750 * Test operations affecting multiple processes, ensuring the following points:
2751 * 1) an operation resumes all possible waiters; 2) a resumed operation in turn
2752 * correctly resumes other now-unblocked operations; 3) a basic level of FIFO
2753 * fairness is provided between blocked parties; 4) all the previous points are
2754 * unaffected by additional waiters that are not being resumed; 5) identifier
2755 * removal properly resumes all affected waiters.
2760 unsigned int resume
, match
, aux
;
2764 for (match
= 0; match
< NR_MATCHES
; match
++)
2765 for (resume
= 0; resume
< NR_RESUMES
; resume
++)
2766 for (aux
= 1; aux
<= 8; aux
++) /* 0 and 4 are equal */
2767 sub88e(match
, resume
, aux
);
2771 * Verify that non-root processes can use sysctl(2) to see semaphore sets
2775 test88f_child(struct link
* parent
)
2777 static const int mib
[] = { CTL_KERN
, KERN_SYSVIPC
, KERN_SYSVIPC_INFO
,
2778 KERN_SYSVIPC_SEM_INFO
};
2779 struct sem_sysctl_info
*semsi
;
2781 int id
[2], id2
, seen
[2];
2784 id
[0] = rcv(parent
);
2785 id
[1] = rcv(parent
);
2787 if (sysctl(mib
, __arraycount(mib
), NULL
, &len
, NULL
, 0) != 0) e(0);
2789 if ((semsi
= malloc(len
)) == NULL
) e(0);
2791 if (sysctl(mib
, __arraycount(mib
), semsi
, &len
, NULL
, 0) != 0) e(0);
2793 seen
[0] = seen
[1] = 0;
2794 for (i
= 0; i
< semsi
->seminfo
.semmni
; i
++) {
2795 if (!(semsi
->semids
[i
].sem_perm
.mode
& SEM_ALLOC
))
2798 id2
= IXSEQ_TO_IPCID(i
, semsi
->semids
[i
].sem_perm
);
2801 else if (id2
== id
[1])
2807 if (seen
[0] != 1) e(0);
2808 if (seen
[1] != 1) e(0);
2812 * Test sysctl(2) based information retrieval. This test aims to ensure that
2813 * in particular ipcs(1) and ipcrm(1) will be able to do their jobs.
2818 static const int mib
[] = { CTL_KERN
, KERN_SYSVIPC
, KERN_SYSVIPC_INFO
,
2819 KERN_SYSVIPC_SEM_INFO
};
2820 struct seminfo seminfo
, seminfo2
;
2821 struct sem_sysctl_info
*semsi
;
2822 struct semid_ds_sysctl
*semds
;
2829 * Verify that we can retrieve only the general semaphore information,
2830 * without any actual semaphore set entries. This is actually a dirty
2831 * sysctl-level hack, as sysctl requests should not behave differently
2832 * based on the requested length. However, ipcs(1) relies on this.
2834 len
= sizeof(seminfo
);
2835 if (sysctl(mib
, __arraycount(mib
), &seminfo
, &len
, NULL
, 0) != 0) e(0);
2836 if (len
!= sizeof(seminfo
)) e(0);
2838 if (semctl(0, 0, IPC_INFO
, &seminfo2
) == -1) e(0);
2840 if (memcmp(&seminfo
, &seminfo2
, sizeof(seminfo
)) != 0) e(0);
2842 /* Verify that the correct size estimation is returned. */
2843 if (seminfo
.semmni
<= 0) e(0);
2844 if (seminfo
.semmni
> SHRT_MAX
) e(0);
2846 size
= sizeof(*semsi
) +
2847 sizeof(semsi
->semids
[0]) * (seminfo
.semmni
- 1);
2850 if (sysctl(mib
, __arraycount(mib
), NULL
, &len
, NULL
, 0) != 0) e(0);
2851 if (len
!= size
) e(0);
2853 /* Create two semaphore sets that should show up in the listing. */
2854 if ((id
[0] = semget(KEY_A
, 5, IPC_CREAT
| 0612)) < 0) e(0);
2856 if ((id
[1] = semget(IPC_PRIVATE
, 3, 0650)) < 0) e(0);
2859 * Retrieve the entire semaphore array, and verify that the general
2860 * semaphore information is still correct.
2862 if ((semsi
= malloc(size
)) == NULL
) e(0);
2865 if (sysctl(mib
, __arraycount(mib
), semsi
, &len
, NULL
, 0) != 0) e(0);
2866 if (len
!= size
) e(0);
2868 if (sizeof(semsi
->seminfo
) != sizeof(seminfo
)) e(0);
2869 if (memcmp(&semsi
->seminfo
, &seminfo
, sizeof(semsi
->seminfo
)) != 0)
2872 /* Verify that our semaphore sets are each in the array once. */
2873 slot
[0] = slot
[1] = -1;
2874 for (i
= 0; i
< seminfo
.semmni
; i
++) {
2875 if (!(semsi
->semids
[i
].sem_perm
.mode
& SEM_ALLOC
))
2878 id2
= IXSEQ_TO_IPCID(i
, semsi
->semids
[i
].sem_perm
);
2880 if (slot
[0] != -1) e(0);
2882 } else if (id2
== id
[1]) {
2883 if (slot
[1] != -1) e(0);
2888 if (slot
[0] < 0) e(0);
2889 if (slot
[1] < 0) e(0);
2891 /* Check that the semaphore sets have the expected properties. */
2892 semds
= &semsi
->semids
[slot
[0]];
2893 if (semds
->sem_perm
.uid
!= geteuid()) e(0);
2894 if (semds
->sem_perm
.gid
!= getegid()) e(0);
2895 if (semds
->sem_perm
.cuid
!= geteuid()) e(0);
2896 if (semds
->sem_perm
.cgid
!= getegid()) e(0);
2897 if (semds
->sem_perm
.mode
!= (SEM_ALLOC
| 0612)) e(0);
2898 if (semds
->sem_perm
._key
!= KEY_A
) e(0);
2899 if (semds
->sem_nsems
!= 5) e(0);
2900 if (semds
->sem_otime
!= 0) e(0);
2901 if (semds
->sem_ctime
== 0) e(0);
2903 semds
= &semsi
->semids
[slot
[1]];
2904 if (semds
->sem_perm
.uid
!= geteuid()) e(0);
2905 if (semds
->sem_perm
.gid
!= getegid()) e(0);
2906 if (semds
->sem_perm
.cuid
!= geteuid()) e(0);
2907 if (semds
->sem_perm
.cgid
!= getegid()) e(0);
2908 if (semds
->sem_perm
.mode
!= (SEM_ALLOC
| 0650)) e(0);
2909 if (semds
->sem_perm
._key
!= IPC_PRIVATE
) e(0);
2910 if (semds
->sem_nsems
!= 3) e(0);
2911 if (semds
->sem_otime
!= 0) e(0);
2912 if (semds
->sem_ctime
== 0) e(0);
2914 /* Make sure that non-root users can see them as well. */
2915 spawn(&child
, test88f_child
, DROP_ALL
);
2922 /* Clean up, and verify that the sets are no longer in the listing. */
2923 if (semctl(id
[0], 0, IPC_RMID
) != 0) e(0);
2924 if (semctl(id
[1], 0, IPC_RMID
) != 0) e(0);
2927 if (sysctl(mib
, __arraycount(mib
), semsi
, &len
, NULL
, 0) != 0) e(0);
2928 if (len
!= size
) e(0);
2930 for (i
= 0; i
< seminfo
.semmni
; i
++) {
2931 if (!(semsi
->semids
[i
].sem_perm
.mode
& SEM_ALLOC
))
2934 id2
= IXSEQ_TO_IPCID(i
, semsi
->semids
[i
].sem_perm
);
2935 if (id2
== id
[0]) e(0);
2936 if (id2
== id
[1]) e(0);
2943 * Initialize the test.
2948 static const int mib
[] = { CTL_KERN
, KERN_SYSVIPC
, KERN_SYSVIPC_SEM
};
2953 /* Start with full root privileges. */
2956 if ((gr
= getgrnam(ROOT_GROUP
)) == NULL
) e(0);
2959 setegid(gr
->gr_gid
);
2962 * Verify that the IPC service is running at all. If not, there is
2963 * obviously no point in running this test.
2966 if (sysctl(mib
, __arraycount(mib
), &i
, &len
, NULL
, 0) != 0) e(0);
2967 if (len
!= sizeof(i
)) e(0);
2970 printf("skipped\n");
2975 /* Allocate a memory page followed by an unmapped page. */
2976 page_size
= getpagesize();
2977 page_ptr
= mmap(NULL
, page_size
* 2, PROT_READ
| PROT_WRITE
,
2978 MAP_ANON
| MAP_PRIVATE
, -1, 0);
2979 if (page_ptr
== MAP_FAILED
) e(0);
2980 bad_ptr
= page_ptr
+ page_size
;
2981 if (munmap(bad_ptr
, page_size
) != 0) e(0);
2985 * Test program for SysV IPC semaphores.
2988 main(int argc
, char ** argv
)
3001 for (i
= 0; i
< ITERATIONS
; i
++) {
3002 if (m
& 0x01) test88a();
3003 if (m
& 0x02) test88b();
3004 if (m
& 0x04) test88c();
3005 if (m
& 0x08) test88d();
3006 if (m
& 0x10) test88e();
3007 if (m
& 0x20) test88f();