xref: /minix3/minix/tests/test88.c (revision 53d2fa057ee88a709bcc793d3c777acad2c2a2ee)
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