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 <sys/sysctl.h>
12 #include <signal.h>
13
14 #include "common.h"
15
16 #define ITERATIONS 3
17
18 #define WAIT_USECS 100000 /* time for processes to get ready */
19
20 #define KEY_A 0x73570001
21 #define KEY_B (KEY_A + 1)
22 #define KEY_C (KEY_A + 2)
23
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 */
28
29 enum {
30 DROP_NONE,
31 DROP_USER,
32 DROP_ALL,
33 };
34
35 enum {
36 SUGID_NONE,
37 SUGID_ROOT_USER,
38 SUGID_NONROOT_USER,
39 SUGID_ROOT_GROUP,
40 SUGID_NONROOT_GROUP,
41 };
42
43 struct link {
44 pid_t pid;
45 int sndfd;
46 int rcvfd;
47 };
48
49 /*
50 * Test semaphore properties. This is a macro, so that it prints useful line
51 * information if an error occurs.
52 */
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); \
58 } while (0);
59
60 static int nr_signals = 0;
61
62 static size_t page_size;
63 static char *page_ptr;
64 static void *bad_ptr;
65
66 /*
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.
69 */
70 static void
spawn(struct link * link,void (* proc)(struct link *),int drop)71 spawn(struct link * link, void (* proc)(struct link *), int drop)
72 {
73 struct passwd *pw;
74 struct group *gr;
75 int up[2], dn[2];
76
77 fflush(stdout);
78 fflush(stderr);
79
80 if (pipe(up) != 0) e(0);
81 if (pipe(dn) != 0) e(0);
82
83 link->pid = fork();
84
85 switch (link->pid) {
86 case 0:
87 close(up[1]);
88 close(dn[0]);
89
90 link->pid = getppid();
91 link->rcvfd = up[0];
92 link->sndfd = dn[1];
93
94 errct = 0;
95
96 switch (drop) {
97 case DROP_ALL:
98 if (setgroups(0, NULL) != 0) e(0);
99
100 if ((gr = getgrnam(NONROOT_GROUP)) == NULL) e(0);
101
102 if (setgid(gr->gr_gid) != 0) e(0);
103 if (setegid(gr->gr_gid) != 0) e(0);
104
105 /* FALLTHROUGH */
106 case DROP_USER:
107 if ((pw = getpwnam(NONROOT_USER)) == NULL) e(0);
108
109 if (setuid(pw->pw_uid) != 0) e(0);
110 }
111
112 proc(link);
113
114 /* Close our pipe FDs on exit, so that we can make zombies. */
115 exit(errct);
116 case -1:
117 e(0);
118 break;
119 }
120
121 close(up[0]);
122 close(dn[1]);
123
124 link->sndfd = up[1];
125 link->rcvfd = dn[0];
126 }
127
128 /*
129 * Wait for a child process to terminate, and clean up.
130 */
131 static void
collect(struct link * link)132 collect(struct link * link)
133 {
134 int status;
135
136 close(link->sndfd);
137 close(link->rcvfd);
138
139 if (waitpid(link->pid, &status, 0) != link->pid) e(0);
140
141 if (!WIFEXITED(status)) e(0);
142 else errct += WEXITSTATUS(status);
143 }
144
145 /*
146 * Forcibly terminate a child process, and clean up.
147 */
148 static void
terminate(struct link * link)149 terminate(struct link * link)
150 {
151 int status;
152
153 if (kill(link->pid, SIGKILL) != 0) e(0);
154
155 close(link->sndfd);
156 close(link->rcvfd);
157
158 if (waitpid(link->pid, &status, 0) <= 0) e(0);
159
160 if (WIFSIGNALED(status)) {
161 if (WTERMSIG(status) != SIGKILL) e(0);
162 } else {
163 if (!WIFEXITED(status)) e(0);
164 else errct += WEXITSTATUS(status);
165 }
166 }
167
168 /*
169 * Send an integer value to the child or parent.
170 */
171 static void
snd(struct link * link,int val)172 snd(struct link * link, int val)
173 {
174
175 if (write(link->sndfd, (void *)&val, sizeof(val)) != sizeof(val)) e(0);
176 }
177
178 /*
179 * Receive an integer value from the child or parent, or -1 on EOF.
180 */
181 static int
rcv(struct link * link)182 rcv(struct link * link)
183 {
184 int r, val;
185
186 if ((r = read(link->rcvfd, (void *)&val, sizeof(val))) == 0)
187 return -1;
188
189 if (r != sizeof(val)) e(0);
190
191 return val;
192 }
193
194 /*
195 * Child procedure that creates semaphore sets.
196 */
197 static void
test_perm_child(struct link * parent)198 test_perm_child(struct link * parent)
199 {
200 struct passwd *pw;
201 struct group *gr;
202 struct semid_ds semds;
203 uid_t uid;
204 gid_t gid;
205 int mask, rmask, sugid, id[3];
206
207 /*
208 * Repeatedly create a number of semaphores with the masks provided by
209 * the parent process.
210 */
211 while ((mask = rcv(parent)) != -1) {
212 rmask = rcv(parent);
213 sugid = rcv(parent);
214
215 /*
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).
219 */
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);
227
228 uid = geteuid();
229 gid = getegid();
230 if (sugid != SUGID_NONE) {
231 switch (sugid) {
232 case SUGID_ROOT_USER:
233 if ((pw = getpwnam(ROOT_USER)) == NULL) e(0);
234 uid = pw->pw_uid;
235 break;
236 case SUGID_NONROOT_USER:
237 if ((pw = getpwnam(NONROOT_USER)) == NULL)
238 e(0);
239 uid = pw->pw_uid;
240 break;
241 case SUGID_ROOT_GROUP:
242 if ((gr = getgrnam(ROOT_GROUP)) == NULL) e(0);
243 gid = gr->gr_gid;
244 break;
245 case SUGID_NONROOT_GROUP:
246 if ((gr = getgrnam(NONROOT_GROUP)) == NULL)
247 e(0);
248 gid = gr->gr_gid;
249 break;
250 }
251
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);
260 }
261
262 /* Do a quick test to confirm the right privileges. */
263 if (mask & IPC_R) {
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);
270 }
271
272 snd(parent, id[0]);
273 snd(parent, id[1]);
274 snd(parent, id[2]);
275
276 /* The other child process runs here. */
277
278 if (rcv(parent) != 0) e(0);
279
280 /*
281 * For owner tests, the other child may already have removed
282 * the semaphore sets, so ignore return values here.
283 */
284 (void)semctl(id[0], 0, IPC_RMID);
285 (void)semctl(id[1], 0, IPC_RMID);
286 (void)semctl(id[2], 0, IPC_RMID);
287 }
288 }
289
290 /*
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.
297 */
298 static void
test_perm(void (* proc)(struct link *),int owner_test)299 test_perm(void (* proc)(struct link *), int owner_test)
300 {
301 struct link child1, child2;
302 int n, shift, bit, mask, rmask, drop1, drop2, sugid, id[3];
303
304 for (n = 0; n < 7; n++) {
305 /*
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
313 * (n=2,5) is tested.
314 */
315 switch (n) {
316 case 0:
317 shift = 6;
318 drop1 = DROP_ALL;
319 drop2 = DROP_ALL;
320 sugid = SUGID_NONE;
321 break;
322 case 1:
323 shift = 6;
324 drop1 = DROP_NONE;
325 drop2 = DROP_ALL;
326 sugid = SUGID_NONROOT_USER;
327 break;
328 case 2:
329 shift = 6;
330 drop1 = DROP_USER;
331 drop2 = DROP_ALL;
332 sugid = SUGID_ROOT_USER;
333 break;
334 case 3:
335 shift = 3;
336 drop1 = DROP_NONE;
337 drop2 = DROP_USER;
338 sugid = SUGID_NONE;
339 break;
340 case 4:
341 shift = 3;
342 drop1 = DROP_NONE;
343 drop2 = DROP_ALL;
344 sugid = SUGID_NONROOT_GROUP;
345 break;
346 case 5:
347 /* The root group has no special privileges. */
348 shift = 3;
349 drop1 = DROP_NONE;
350 drop2 = DROP_USER;
351 sugid = SUGID_NONROOT_GROUP;
352 break;
353 case 6:
354 shift = 0;
355 drop1 = DROP_NONE;
356 drop2 = DROP_ALL;
357 sugid = SUGID_NONE;
358 break;
359 }
360
361 spawn(&child1, test_perm_child, drop1);
362 spawn(&child2, proc, drop2);
363
364 for (bit = 0; bit <= 7; bit++) {
365 mask = bit << shift;
366 rmask = 0777 & ~(7 << shift);
367
368 snd(&child1, mask);
369 snd(&child1, rmask);
370 snd(&child1, sugid);
371 id[0] = rcv(&child1);
372 id[1] = rcv(&child1);
373 id[2] = rcv(&child1);
374
375 snd(&child2, (owner_test) ? shift : bit);
376 snd(&child2, id[0]);
377 snd(&child2, id[1]);
378 snd(&child2, id[2]);
379 if (rcv(&child2) != 0) e(0);
380
381 snd(&child1, 0);
382 }
383
384 /* We use a bitmask of -1 to terminate the children. */
385 snd(&child1, -1);
386 snd(&child2, -1);
387
388 collect(&child1);
389 collect(&child2);
390 }
391 }
392
393 /*
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.
397 */
398 static void
test88a_perm(struct link * parent)399 test88a_perm(struct link * parent)
400 {
401 int r, tbit, bit, mask, id[3];
402
403 while ((tbit = rcv(parent)) != -1) {
404 id[0] = rcv(parent);
405 id[1] = rcv(parent);
406 id[2] = rcv(parent);
407
408 /*
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
411 * failure.
412 */
413 for (bit = 0; bit <= 7; bit++) {
414 mask = bit << 6;
415
416 /*
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.
420 */
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))
424 e(0);
425 if (r != -1 && r != id[0]) e(0);
426
427 /*
428 * Same for semaphore set B, which was created with all
429 * irrelevant mode bits inverted.
430 */
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))
434 e(0);
435 if (r != -1 && r != id[1]) e(0);
436
437 /*
438 * Semaphore set C was created with only irrelevant
439 * mode bits set, so opening it must always fail.
440 */
441 if (semget(KEY_C, 0, mask) != -1) e(0);
442 if (errno != EACCES) e(0);
443 }
444
445 snd(parent, 0);
446 }
447 }
448
449 /*
450 * Test the basic semget(2) functionality.
451 */
452 static void
test88a(void)453 test88a(void)
454 {
455 struct seminfo seminfo;
456 struct semid_ds semds;
457 time_t now;
458 unsigned int i, j;
459 int id[3], *idp;
460
461 subtest = 0;
462
463 /*
464 * The key IPC_PRIVATE must always yield a new semaphore set identifier
465 * regardless of whether IPC_CREAT and IPC_EXCL are supplied.
466 */
467 if ((id[0] = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600)) < 0) e(0);
468
469 if ((id[1] = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0600)) < 0)
470 e(0);
471
472 if ((id[2] = semget(IPC_PRIVATE, 1, 0600)) < 0) e(0);
473
474 if (id[0] == id[1]) e(0);
475 if (id[1] == id[2]) e(0);
476 if (id[0] == id[2]) e(0);
477
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);
481
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);
487
488 /*
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.
492 */
493 if (semget(KEY_A, 1, 0600) != -1) e(0);
494 if (errno != ENOENT);
495
496 if ((id[0] = semget(KEY_A, 1, IPC_CREAT | IPC_EXCL | 0600)) < 0) e(0);
497
498 if (semget(KEY_B, 1, 0600) != -1) e(0);
499 if (errno != ENOENT);
500
501 if ((id[1] = semget(KEY_B, 1, IPC_CREAT | 0600)) < 0) e(0);
502
503 if (id[0] == id[1]) e(0);
504
505 if ((id[2] = semget(KEY_A, 1, 0600)) < 0) e(0);
506 if (id[2] != id[0]) e(0);
507
508 if ((id[2] = semget(KEY_B, 1, IPC_CREAT | 0600)) < 0) e(0);
509 if (id[2] != id[2]) e(0);
510
511 if (semget(KEY_A, 1, IPC_CREAT | IPC_EXCL | 0600) != -1) e(0);
512 if (errno != EEXIST) e(0);
513
514 if (semctl(id[0], 0, IPC_RMID) != 0) e(0);
515 if (semctl(id[1], 0, IPC_RMID) != 0) e(0);
516
517 /*
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.
522 */
523 if (semctl(0, 0, IPC_INFO, &seminfo) == -1) e(0);
524 if (seminfo.semmni < 3 || seminfo.semmni > USHRT_MAX) e(0);
525
526 if ((idp = malloc(sizeof(int) * (seminfo.semmni + 1))) == NULL) e(0);
527
528 for (i = 0; i < seminfo.semmni + 1; i++) {
529 if ((idp[i] = semget(KEY_A + i, 1, IPC_CREAT | 0600)) < 0)
530 break;
531
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);
535 }
536
537 if (errno != ENOSPC) e(0);
538 if (i < 3) e(0);
539 if (i == seminfo.semmni + 1) e(0);
540
541 while (i-- > 0)
542 if (semctl(idp[i], 0, IPC_RMID) != 0) e(0);
543
544 free(idp);
545
546 /*
547 * The given number of semaphores must be within bounds.
548 */
549 if (semget(KEY_A, -1, IPC_CREAT | 0600) != -1) e(0);
550 if (errno != EINVAL) e(0);
551
552 if (semget(KEY_A, 0, IPC_CREAT | 0600) != -1) e(0);
553 if (errno != EINVAL) e(0);
554
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);
558
559 if ((id[0] = semget(KEY_A, seminfo.semmsl, IPC_CREAT | 0600)) < 0)
560 e(0);
561 if (semctl(id[0], 0, IPC_RMID) != 0) e(0);
562
563 if ((id[0] = semget(KEY_A, 2, IPC_CREAT | 0600)) < 0) e(0);
564
565 if ((id[1] = semget(KEY_A, 0, 0600)) < 0) e(0);
566 if (id[0] != id[1]) e(0);
567
568 if ((id[1] = semget(KEY_A, 1, 0600)) < 0) e(0);
569 if (id[0] != id[1]) e(0);
570
571 if ((id[1] = semget(KEY_A, 2, 0600)) < 0) e(0);
572 if (id[0] != id[1]) e(0);
573
574 if ((id[1] = semget(KEY_A, 3, 0600)) != -1) e(0);
575 if (errno != EINVAL) e(0);
576
577 if ((id[1] = semget(KEY_A, seminfo.semmsl + 1, 0600)) != -1) e(0);
578 if (errno != EINVAL) e(0);
579
580 if (semctl(id[0], 0, IPC_RMID) != 0) e(0);
581
582 /*
583 * Verify that the initial values for the semaphore set are as
584 * expected.
585 */
586 time(&now);
587 if (seminfo.semmns < 3 + seminfo.semmsl) e(0);
588 if ((id[0] = semget(IPC_PRIVATE, 3, IPC_CREAT | IPC_EXCL | 0642)) < 0)
589 e(0);
590 if ((id[1] = semget(KEY_A, seminfo.semmsl, IPC_CREAT | 0613)) < 0)
591 e(0);
592
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);
603
604 for (i = 0; i < semds.sem_nsems; i++)
605 TEST_SEM(id[0], i, 0, 0, 0, 0);
606
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);
617
618 for (i = 0; i < semds.sem_nsems; i++)
619 TEST_SEM(id[1], i, 0, 0, 0, 0);
620
621 if (semctl(id[1], 0, IPC_RMID) != 0) e(0);
622 if (semctl(id[0], 0, IPC_RMID) != 0) e(0);
623
624 /*
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.
628 */
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);
631
632 if ((id[1] = semget(KEY_A, 0, 0600)) < 0) e(0);
633 if (id[0] != id[1]) e(0);
634
635 if ((id[1] = semget(KEY_A, 0, 0000)) < 0) e(0);
636 if (id[0] != id[1]) e(0);
637
638 if (semctl(id[0], 0, IPC_RMID) != 0) e(0);
639
640 /*
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.
644 */
645 test_perm(test88a_perm, 0 /*owner_test*/);
646 }
647
648 /*
649 * Test semop(2) permission checks.
650 */
651 static void
test88b_perm(struct link * parent)652 test88b_perm(struct link * parent)
653 {
654 struct sembuf sops[2];
655 size_t nsops;
656 int i, r, tbit, bit, id[3];
657
658 while ((tbit = rcv(parent)) != -1) {
659 id[0] = rcv(parent);
660 id[1] = rcv(parent);
661 id[2] = rcv(parent);
662
663 /*
664 * This loop is designed such that failure of any bit-based
665 * subset will not result in subsequent operations blocking.
666 */
667 for (i = 0; i < 8; i++) {
668 memset(sops, 0, sizeof(sops));
669
670 switch (i) {
671 case 0:
672 nsops = 1;
673 bit = 4;
674 break;
675 case 1:
676 sops[0].sem_op = 1;
677 nsops = 1;
678 bit = 2;
679 break;
680 case 2:
681 sops[0].sem_op = -1;
682 nsops = 1;
683 bit = 2;
684 break;
685 case 3:
686 sops[1].sem_op = 1;
687 nsops = 2;
688 bit = 6;
689 break;
690 case 4:
691 sops[0].sem_num = 1;
692 sops[1].sem_op = -1;
693 nsops = 2;
694 bit = 6;
695 break;
696 case 5:
697 sops[1].sem_num = 1;
698 nsops = 2;
699 bit = 4;
700 break;
701 case 6:
702 /*
703 * Two operations on the same semaphore. As
704 * such, this verifies that operations are
705 * processed in array order.
706 */
707 sops[0].sem_op = 1;
708 sops[1].sem_op = -1;
709 nsops = 2;
710 bit = 2;
711 break;
712 case 7:
713 /*
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.
719 */
720 sops[0].sem_num = USHRT_MAX;
721 nsops = 2;
722 bit = 4;
723 break;
724 }
725
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);
730
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);
735
736 if (semop(id[2], sops, nsops) != -1) e(0);
737 if (errno != EACCES) e(0);
738 }
739
740 snd(parent, 0);
741 }
742 }
743
744 /*
745 * Signal handler.
746 */
747 static void
got_signal(int sig)748 got_signal(int sig)
749 {
750
751 if (sig != SIGHUP) e(0);
752 if (nr_signals != 0) e(0);
753 nr_signals++;
754 }
755
756 /*
757 * Child process for semop(2) tests, mainly testing blocking operations.
758 */
759 static void
test88b_child(struct link * parent)760 test88b_child(struct link * parent)
761 {
762 struct sembuf sops[5];
763 struct sigaction act;
764 int id;
765
766 id = rcv(parent);
767
768 memset(sops, 0, sizeof(sops));
769 if (semop(id, sops, 1) != 0) e(0);
770
771 if (rcv(parent) != 1) e(0);
772
773 sops[0].sem_op = -3;
774 if (semop(id, sops, 1) != 0) e(0);
775
776 if (rcv(parent) != 2) e(0);
777
778 sops[0].sem_num = 2;
779 sops[0].sem_op = 2;
780 sops[1].sem_num = 1;
781 sops[1].sem_op = -1;
782 sops[2].sem_num = 0;
783 sops[2].sem_op = 1;
784 if (semop(id, sops, 3) != 0) e(0);
785
786 if (rcv(parent) != 3) e(0);
787
788 sops[0].sem_num = 1;
789 sops[0].sem_op = 0;
790 sops[1].sem_num = 1;
791 sops[1].sem_op = 1;
792 sops[2].sem_num = 0;
793 sops[2].sem_op = 0;
794 sops[3].sem_num = 2;
795 sops[3].sem_op = 0;
796 sops[4].sem_num = 2;
797 sops[4].sem_op = 1;
798 if (semop(id, sops, 5) != 0) e(0);
799
800 if (rcv(parent) != 4) e(0);
801
802 sops[0].sem_num = 1;
803 sops[0].sem_op = -2;
804 sops[1].sem_num = 2;
805 sops[1].sem_op = 0;
806 if (semop(id, sops, 2) != 0) e(0);
807
808 if (rcv(parent) != 5) e(0);
809
810 sops[0].sem_num = 0;
811 sops[0].sem_op = -1;
812 sops[1].sem_num = 1;
813 sops[1].sem_op = -1;
814 sops[1].sem_flg = IPC_NOWAIT;
815 if (semop(id, sops, 2) != 0) e(0);
816
817 if (rcv(parent) != 6) e(0);
818
819 sops[0].sem_num = 1;
820 sops[0].sem_op = 0;
821 sops[1].sem_num = 0;
822 sops[1].sem_op = 0;
823 sops[1].sem_flg = IPC_NOWAIT;
824 if (semop(id, sops, 2) != -1) e(0);
825 if (errno != EAGAIN) e(0);
826
827 if (rcv(parent) != 7) e(0);
828
829 sops[0].sem_num = 0;
830 sops[0].sem_op = 0;
831 sops[1].sem_num = 1;
832 sops[1].sem_op = 1;
833 sops[1].sem_flg = 0;
834 if (semop(id, sops, 2) != 0) e(0);
835
836 if (rcv(parent) != 8) e(0);
837
838 sops[0].sem_num = 0;
839 sops[0].sem_op = -1;
840 sops[1].sem_num = 1;
841 sops[1].sem_op = 2;
842 if (semop(id, sops, 2) != -1) e(0);
843 if (errno != ERANGE) e(0);
844
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);
849
850 if (rcv(parent) != 9) e(0);
851
852 memset(sops, 0, sizeof(sops));
853 sops[0].sem_num = 0;
854 sops[0].sem_op = 0;
855 sops[1].sem_num = 0;
856 sops[1].sem_op = 1;
857 sops[2].sem_num = 1;
858 sops[2].sem_op = 0;
859 if (semop(id, sops, 3) != -1)
860 if (errno != EINTR) e(0);
861 if (nr_signals != 1) e(0);
862
863 TEST_SEM(id, 0, 0, parent->pid, 0, 0);
864 TEST_SEM(id, 1, 1, parent->pid, 0, 0);
865
866 if (rcv(parent) != 10) e(0);
867
868 memset(sops, 0, sizeof(sops));
869 sops[0].sem_op = -3;
870 if (semop(id, sops, 1) != -1) e(0);
871 if (errno != EIDRM) e(0);
872
873 id = rcv(parent);
874
875 sops[0].sem_num = 0;
876 sops[0].sem_op = -1;
877 sops[1].sem_num = 1;
878 sops[1].sem_op = 1;
879 if (semop(id, sops, 2) != -1) e(0);
880 if (errno != ERANGE) e(0);
881
882 if (rcv(parent) != 11) e(0);
883
884 sops[0].sem_num = 1;
885 sops[0].sem_op = 0;
886 sops[1].sem_num = 0;
887 sops[1].sem_op = -1;
888 if (semop(id, sops, 2) != 0) e(0);
889
890 id = rcv(parent);
891
892 sops[0].sem_num = 0;
893 sops[0].sem_op = -1;
894 sops[1].sem_num = 1;
895 sops[1].sem_op = 0;
896 if (semop(id, sops, 2) != 0) e(0);
897
898 snd(parent, errct);
899 if (rcv(parent) != 12) e(0);
900
901 /* The child will be killed during this call. It should not return. */
902 sops[0].sem_num = 1;
903 sops[0].sem_op = -1;
904 sops[1].sem_num = 0;
905 sops[1].sem_op = 3;
906 (void)semop(id, sops, 2);
907
908 e(0);
909 }
910
911 /*
912 * Test the basic semop(2) functionality.
913 */
914 static void
test88b(void)915 test88b(void)
916 {
917 struct seminfo seminfo;
918 struct semid_ds semds;
919 struct sembuf *sops, *sops2;
920 size_t size;
921 struct link child;
922 time_t now;
923 unsigned short val[2];
924 int id;
925
926 subtest = 1;
927
928 /* Allocate a buffer for operations. */
929 if (semctl(0, 0, IPC_INFO, &seminfo) == -1) e(0);
930
931 if (seminfo.semopm < 3 || seminfo.semopm > USHRT_MAX) e(0);
932
933 size = sizeof(sops[0]) * (seminfo.semopm + 1);
934 if ((sops = malloc(size)) == NULL) e(0);
935 memset(sops, 0, size);
936
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);
939
940 /* If no operations are given, the call should succeed. */
941 if (semop(id, NULL, 0) != 0) e(0);
942
943 /*
944 * If any operations are given, the pointer must be valid. Moreover,
945 * partially valid buffers must never be processed partially.
946 */
947 if (semop(id, NULL, 1) != -1) e(0);
948 if (errno != EFAULT) e(0);
949
950 if (semop(id, bad_ptr, 1) != -1) e(0);
951 if (errno != EFAULT) e(0);
952
953 memset(page_ptr, 0, page_size);
954 sops2 = ((struct sembuf *)bad_ptr) - 1;
955 sops2->sem_op = 1;
956 if (semop(id, sops2, 2) != -1) e(0);
957 if (errno != EFAULT) e(0);
958
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);
962
963 /*
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.
966 */
967 time(&now);
968 if (semop(id, sops, 1) != 0) e(0);
969
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);
973
974 /* Test the limit on the number of operations. */
975 if (semop(id, sops, seminfo.semopm) != 0) e(0);
976
977 if (semop(id, sops, seminfo.semopm + 1) != -1) e(0);
978 if (errno != E2BIG) e(0);
979
980 if (semop(id, sops, SIZE_MAX) != -1) e(0);
981 if (errno != E2BIG) e(0);
982
983 /* Test the range check on the semaphore numbers. */
984 sops[1].sem_num = 1;
985 if (semop(id, sops, 2) != -1) e(0);
986 if (errno != EFBIG) e(0);
987
988 sops[1].sem_num = USHRT_MAX;
989 if (semop(id, sops, 2) != -1) e(0);
990 if (errno != EFBIG) e(0);
991
992 /*
993 * Test nonblocking operations on a single semaphore, starting with
994 * value limit and overflow cases.
995 */
996 if (seminfo.semvmx < 3 || seminfo.semvmx > SHRT_MAX) e(0);
997
998 sops[0].sem_flg = IPC_NOWAIT;
999
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);
1006 }
1007
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);
1011
1012 /* As of writing, the proper checks for this is missing on NetBSD. */
1013 sops[0].sem_op = 1;
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);
1017
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);
1022
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);
1027
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);
1034 }
1035
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);
1039
1040 /*
1041 * Test basic nonblocking operations on a single semaphore.
1042 */
1043 sops[0].sem_op = 0;
1044 if (semop(id, sops, 1) != 0) e(0);
1045
1046 sops[0].sem_op = 2;
1047 if (semop(id, sops, 1) != 0) e(0);
1048 if (semctl(id, 0, GETVAL) != 2) e(0);
1049
1050 sops[0].sem_op = 0;
1051 if (semop(id, sops, 1) != -1) e(0);
1052 if (errno != EAGAIN) e(0);
1053
1054 sops[0].sem_op = -3;
1055 if (semop(id, sops, 1) != -1) e(0);
1056 if (errno != EAGAIN) e(0);
1057
1058 sops[0].sem_op = 1;
1059 if (semop(id, sops, 1) != 0) e(0);
1060 if (semctl(id, 0, GETVAL) != 3) e(0);
1061
1062 sops[0].sem_op = -1;
1063 if (semop(id, sops, 1) != 0) e(0);
1064 if (semctl(id, 0, GETVAL) != 2) e(0);
1065
1066 sops[0].sem_op = 0;
1067 if (semop(id, sops, 1) != -1) e(0);
1068 if (errno != EAGAIN) e(0);
1069
1070 sops[0].sem_op = -2;
1071 if (semop(id, sops, 1) != 0) e(0);
1072 if (semctl(id, 0, GETVAL) != 0) e(0);
1073
1074 sops[0].sem_op = 0;
1075 if (semop(id, sops, 1) != 0) e(0);
1076
1077 /* Make sure that not too much data is being read in. */
1078 sops2->sem_op = 0;
1079 sops2--;
1080 if (semop(id, sops2, 2) != 0) e(0);
1081
1082 /* Even if no operations are given, the identifier must be valid. */
1083 if (semctl(id, 0, IPC_RMID) != 0) e(0);
1084
1085 if (semop(id, NULL, 0) != -1) e(0);
1086 if (errno != EINVAL) e(0);
1087
1088 if (semop(-1, NULL, 0) != -1) e(0);
1089 if (errno != EINVAL) e(0);
1090
1091 if (semop(INT_MIN, NULL, 0) != -1) e(0);
1092 if (errno != EINVAL) e(0);
1093
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);
1098
1099 /*
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.
1103 */
1104 test_perm(test88b_perm, 0 /*owner_test*/);
1105
1106 /*
1107 * Test blocking operations, starting with a single blocking operation.
1108 */
1109 if ((id = semget(IPC_PRIVATE, 3, 0600)) == -1) e(0);
1110
1111 memset(sops, 0, sizeof(sops[0]));
1112 sops[0].sem_op = 1;
1113 if (semop(id, sops, 1) != 0) e(0);
1114
1115 TEST_SEM(id, 0, 1, getpid(), 0, 0);
1116
1117 spawn(&child, test88b_child, DROP_NONE);
1118
1119 snd(&child, id);
1120
1121 /*
1122 * In various places, we have to sleep in order to allow the child to
1123 * get itself blocked in a semop(2) call.
1124 */
1125 usleep(WAIT_USECS);
1126
1127 TEST_SEM(id, 0, 1, getpid(), 0, 1);
1128
1129 sops[0].sem_op = -1;
1130 if (semop(id, sops, 1) != 0) e(0);
1131
1132 usleep(WAIT_USECS);
1133
1134 TEST_SEM(id, 0, 0, child.pid, 0, 0);
1135
1136 sops[0].sem_op = 1;
1137 if (semop(id, sops, 1) != 0) e(0);
1138
1139 TEST_SEM(id, 0, 1, getpid(), 0, 0);
1140
1141 snd(&child, 1);
1142
1143 usleep(WAIT_USECS);
1144
1145 TEST_SEM(id, 0, 1, getpid(), 1, 0);
1146
1147 /* This should cause a (fruitless) retry of the blocking operation. */
1148 sops[0].sem_op = 1;
1149 if (semop(id, sops, 1) != 0) e(0);
1150
1151 usleep(WAIT_USECS);
1152
1153 TEST_SEM(id, 0, 2, getpid(), 1, 0);
1154
1155 sops[0].sem_op = 1;
1156 if (semop(id, sops, 1) != 0) e(0);
1157
1158 usleep(WAIT_USECS);
1159
1160 TEST_SEM(id, 0, 0, child.pid, 0, 0);
1161
1162 /*
1163 * Test blocking operations, verifying the correct operation of
1164 * multiple (partially) blocking operations and atomicity.
1165 */
1166 memset(sops, 0, sizeof(sops[0]) * 2);
1167 if (semop(id, sops, 1) != 0) e(0);
1168
1169 /* One blocking operation. */
1170 snd(&child, 2);
1171
1172 usleep(WAIT_USECS);
1173
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);
1177
1178 sops[0].sem_num = 1;
1179 sops[0].sem_op = 1;
1180 if (semop(id, sops, 1) != 0) e(0);
1181
1182 usleep(WAIT_USECS);
1183
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);
1187
1188 /* Two blocking operations in one call, resolved at once. */
1189 snd(&child, 3);
1190
1191 usleep(WAIT_USECS);
1192
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);
1196
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);
1202
1203 usleep(WAIT_USECS);
1204
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);
1208
1209 /* Two blocking operations in one call, resolved one by one. */
1210 snd(&child, 4);
1211
1212 usleep(WAIT_USECS);
1213
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);
1217
1218 sops[0].sem_num = 1;
1219 sops[0].sem_op = 1;
1220 if (semop(id, sops, 1) != 0) e(0);
1221
1222 usleep(WAIT_USECS);
1223
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);
1227
1228 sops[0].sem_num = 2;
1229 sops[0].sem_op = -1;
1230 if (semop(id, sops, 1) != 0) e(0);
1231
1232 usleep(WAIT_USECS);
1233
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);
1237
1238 /* One blocking op followed by a nonblocking one, cleared at once. */
1239 sops[0].sem_num = 0;
1240 sops[0].sem_op = 0;
1241 sops[1].sem_num = 1;
1242 sops[1].sem_op = 0;
1243 if (semop(id, sops, 2) != 0) e(0);
1244
1245 snd(&child, 5);
1246
1247 usleep(WAIT_USECS);
1248
1249 TEST_SEM(id, 0, 0, getpid(), 1, 0);
1250 TEST_SEM(id, 1, 0, getpid(), 0, 0);
1251
1252 sops[0].sem_num = 0;
1253 sops[0].sem_op = 1;
1254 sops[1].sem_num = 1;
1255 sops[1].sem_op = 1;
1256 if (semop(id, sops, 2) != 0) e(0);
1257
1258 usleep(WAIT_USECS);
1259
1260 TEST_SEM(id, 0, 0, child.pid, 0, 0);
1261 TEST_SEM(id, 1, 0, child.pid, 0, 0);
1262
1263 /* One blocking op followed by a nonblocking one, only one cleared. */
1264 sops[0].sem_num = 0;
1265 sops[0].sem_op = 1;
1266 sops[1].sem_num = 1;
1267 sops[1].sem_op = 1;
1268 if (semop(id, sops, 2) != 0) e(0);
1269
1270 snd(&child, 6);
1271
1272 usleep(WAIT_USECS);
1273
1274 TEST_SEM(id, 0, 1, getpid(), 0, 0);
1275 TEST_SEM(id, 1, 1, getpid(), 0, 1);
1276
1277 sops[0].sem_num = 1;
1278 sops[0].sem_op = -1;
1279 if (semop(id, sops, 1) != 0) e(0);
1280
1281 usleep(WAIT_USECS);
1282
1283 TEST_SEM(id, 0, 1, getpid(), 0, 0);
1284 TEST_SEM(id, 1, 0, getpid(), 0, 0);
1285
1286 /*
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.
1293 */
1294 sops[0].sem_num = 0;
1295 sops[0].sem_op = 0;
1296 sops[1].sem_num = 4;
1297 sops[1].sem_op = 0;
1298 if (semop(id, sops, 2) != -1) e(0);
1299 if (errno != EFBIG) e(0);
1300
1301 /*
1302 * Ensure that semaphore value overflow is detected properly, at the
1303 * moment that the operation is actually processed.
1304 */
1305 sops[0].sem_num = 1;
1306 sops[0].sem_op = seminfo.semvmx;
1307 if (semop(id, sops, 1) != 0) e(0);
1308
1309 snd(&child, 7);
1310
1311 usleep(WAIT_USECS);
1312
1313 TEST_SEM(id, 0, 1, getpid(), 0, 1);
1314 TEST_SEM(id, 1, seminfo.semvmx, getpid(), 0, 0);
1315
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);
1321
1322 TEST_SEM(id, 0, 0, child.pid, 0, 0);
1323 TEST_SEM(id, 1, seminfo.semvmx, child.pid, 0, 0);
1324
1325 sops[0].sem_num = 1;
1326 sops[0].sem_op = -2;
1327 if (semop(id, sops, 1) != 0) e(0);
1328
1329 snd(&child, 8);
1330
1331 usleep(WAIT_USECS);
1332
1333 TEST_SEM(id, 0, 0, child.pid, 1, 0);
1334 TEST_SEM(id, 1, seminfo.semvmx - 2, getpid(), 0, 0);
1335
1336 sops[0].sem_num = 0;
1337 sops[0].sem_op = 1;
1338 sops[1].sem_num = 1;
1339 sops[1].sem_op = 1;
1340 if (semop(id, sops, 2) != 0) e(0);
1341
1342 TEST_SEM(id, 0, 1, getpid(), 0, 0);
1343 TEST_SEM(id, 1, seminfo.semvmx - 1, getpid(), 0, 0);
1344
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;
1350 sops[2].sem_op = 2;
1351 /*
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.
1355 */
1356 if (semop(id, sops, 3) != -1) e(0);
1357 if (errno != ERANGE) e(0);
1358
1359 TEST_SEM(id, 0, 1, getpid(), 0, 0);
1360
1361 /*
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.
1364 */
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;
1369 sops[1].sem_op = 1;
1370 if (semop(id, sops, 2) != 0) e(0);
1371
1372 TEST_SEM(id, 0, 0, getpid(), 0, 0);
1373 TEST_SEM(id, 1, 1, getpid(), 0, 0);
1374
1375 snd(&child, 9);
1376
1377 usleep(WAIT_USECS);
1378
1379 TEST_SEM(id, 0, 0, getpid(), 0, 0);
1380 TEST_SEM(id, 1, 1, getpid(), 0, 1);
1381
1382 kill(child.pid, SIGHUP);
1383 /*
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.
1386 */
1387
1388 /*
1389 * Check that a blocking semop(2) call fails with EIDRM if the
1390 * semaphore set is removed after the call has blocked.
1391 */
1392 snd(&child, 10);
1393
1394 usleep(WAIT_USECS);
1395
1396 if (semctl(id, 0, IPC_RMID) != 0) e(0);
1397
1398 /*
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.
1403 */
1404 if ((id = semget(IPC_PRIVATE, 2, 0600)) == -1) e(0);
1405
1406 snd(&child, id);
1407
1408 usleep(WAIT_USECS);
1409
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);
1414
1415 if (semctl(id, 1, SETVAL, seminfo.semvmx) != 0) e(0);
1416
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);
1421
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);
1425
1426 if (semctl(id, 0, SETVAL, 0) != 0) e(0);
1427
1428 snd(&child, 11);
1429
1430 usleep(WAIT_USECS);
1431
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);
1436
1437 if (semctl(id, 1, SETVAL, 0) != 0) e(0);
1438
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);
1443
1444 time(&now);
1445 if (semctl(id, 0, SETVAL, 2) != 0) e(0);
1446
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);
1451
1452 if (semctl(id, 0, IPC_RMID) != 0) e(0);
1453
1454 /*
1455 * Perform a similar test for SETALL, ensuring that it causes an
1456 * ongoing semop(2) to behave correctly.
1457 */
1458 if ((id = semget(IPC_PRIVATE, 2, 0600)) == -1) e(0);
1459
1460 snd(&child, id);
1461
1462 usleep(WAIT_USECS);
1463
1464 TEST_SEM(id, 0, 0, 0, 1, 0);
1465 TEST_SEM(id, 1, 0, 0, 0, 0);
1466
1467 val[0] = 1;
1468 val[1] = 1;
1469 if (semctl(id, 0, SETALL, val) != 0) e(0);
1470
1471 TEST_SEM(id, 0, 1, 0, 0, 0);
1472 TEST_SEM(id, 1, 1, 0, 0, 1);
1473
1474 val[0] = 0;
1475 val[1] = 1;
1476 if (semctl(id, 0, SETALL, val) != 0) e(0);
1477
1478 TEST_SEM(id, 0, 0, 0, 1, 0);
1479 TEST_SEM(id, 1, 1, 0, 0, 0);
1480
1481 val[0] = 1;
1482 val[1] = 1;
1483 if (semctl(id, 0, SETALL, val) != 0) e(0);
1484
1485 TEST_SEM(id, 0, 1, 0, 0, 0);
1486 TEST_SEM(id, 1, 1, 0, 0, 1);
1487
1488 val[0] = 0;
1489 val[1] = 0;
1490 if (semctl(id, 0, SETALL, val) != 0) e(0);
1491
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);
1496
1497 time(&now);
1498 val[0] = 1;
1499 val[1] = 0;
1500 if (semctl(id, 0, SETALL, val) != 0) e(0);
1501
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);
1506
1507 /*
1508 * Finally, ensure that if the child is killed, its blocked semop(2)
1509 * call is properly cancelled.
1510 */
1511 sops[0].sem_num = 0;
1512 sops[0].sem_op = 0;
1513 sops[1].sem_num = 1;
1514 sops[1].sem_op = 0;
1515 if (semop(id, sops, 2) != 0) e(0);
1516
1517 TEST_SEM(id, 0, 0, getpid(), 0, 0);
1518 TEST_SEM(id, 1, 0, getpid(), 0, 0);
1519
1520 /* We'll be terminating the child, so let it report its errors now. */
1521 if (rcv(&child) != 0) e(0);
1522
1523 snd(&child, 12);
1524
1525 usleep(WAIT_USECS);
1526
1527 TEST_SEM(id, 0, 0, getpid(), 0, 0);
1528 TEST_SEM(id, 1, 0, getpid(), 1, 0);
1529
1530 terminate(&child);
1531
1532 TEST_SEM(id, 0, 0, getpid(), 0, 0);
1533 TEST_SEM(id, 1, 0, getpid(), 0, 0);
1534
1535 if (semctl(id, 0, IPC_RMID) != 0) e(0);
1536
1537 free(sops);
1538 }
1539
1540 /*
1541 * Test semctl(2) permission checks, part 1: regular commands.
1542 */
1543 static void
test88c_perm1(struct link * parent)1544 test88c_perm1(struct link * parent)
1545 {
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;
1551 void *ptr;
1552
1553 while ((tbit = rcv(parent)) != -1) {
1554 id[0] = rcv(parent);
1555 id[1] = rcv(parent);
1556 id[2] = rcv(parent);
1557
1558 /* First the read-only, no-argument cases. */
1559 bit = 4;
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);
1564
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);
1568
1569 if (semctl(id[2], 0, cmds[i]) != -1) e(0);
1570 if (errno != EACCES) e(0);
1571 }
1572
1573 /*
1574 * Then SETVAL, which requires write permission and is the only
1575 * one that takes an integer argument.
1576 */
1577 bit = 2;
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);
1581
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);
1585
1586 if (semctl(id[2], 0, SETVAL, 0) != -1) e(0);
1587 if (errno != EACCES) e(0);
1588
1589 /*
1590 * Finally the commands that require read or write permission
1591 * and take a pointer as argument.
1592 */
1593 memset(val, 0, sizeof(val));
1594
1595 for (i = 0; i < 3; i++) {
1596 switch (i) {
1597 case 0:
1598 cmd = GETALL;
1599 ptr = val;
1600 bit = 4;
1601 break;
1602 case 1:
1603 cmd = SETALL;
1604 ptr = val;
1605 bit = 2;
1606 break;
1607 case 2:
1608 cmd = IPC_STAT;
1609 ptr = &semds;
1610 bit = 4;
1611 break;
1612 default:
1613 abort();
1614 }
1615
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);
1619
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);
1623
1624 if (semctl(id[2], 0, cmd, ptr) != -1) e(0);
1625 if (errno != EACCES) e(0);
1626 }
1627
1628 /*
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.
1635 */
1636 #ifndef IPCID_TO_IX
1637 #define IPCID_TO_IX(id) ((id) & 0xffff)
1638 #endif
1639
1640 bit = 4;
1641
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);
1645
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);
1649
1650 if (semctl(IPCID_TO_IX(id[2]), 0, SEM_STAT, &semds) != -1)
1651 e(0);
1652 if (errno != EACCES) e(0);
1653
1654 /*
1655 * IPC_INFO and SEM_INFO should always succeed. They do not
1656 * even take a semaphore set identifier.
1657 */
1658 if (semctl(0, 0, IPC_INFO, &seminfo) == -1) e(0);
1659 if (semctl(0, 0, SEM_INFO, &seminfo) == -1) e(0);
1660
1661 snd(parent, 0);
1662 }
1663 }
1664
1665 /*
1666 * Test semctl(2) permission checks, part 2: the IPC_SET command.
1667 */
1668 static void
test88c_perm2(struct link * parent)1669 test88c_perm2(struct link * parent)
1670 {
1671 struct semid_ds semds;
1672 int r, shift, id[3];
1673
1674 while ((shift = rcv(parent)) != -1) {
1675 id[0] = rcv(parent);
1676 id[1] = rcv(parent);
1677 id[2] = rcv(parent);
1678
1679 /*
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.
1691 */
1692 memset(&semds, 0, sizeof(semds));
1693
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);
1697
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);
1701
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);
1706
1707 snd(parent, 0);
1708 }
1709 }
1710
1711 /*
1712 * Test semctl(2) permission checks, part 3: the IPC_RMID command.
1713 */
1714 static void
test88c_perm3(struct link * parent)1715 test88c_perm3(struct link * parent)
1716 {
1717 int r, shift, id[3];
1718
1719 while ((shift = rcv(parent)) != -1) {
1720 id[0] = rcv(parent);
1721 id[1] = rcv(parent);
1722 id[2] = rcv(parent);
1723
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);
1727
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);
1731
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);
1736
1737 snd(parent, 0);
1738 }
1739 }
1740
1741 /*
1742 * Test the basic semctl(2) functionality.
1743 */
1744 static void
test88c(void)1745 test88c(void)
1746 {
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];
1752 unsigned int i, j;
1753 time_t now;
1754 int r, id, id2, badid1, badid2, cmd;
1755
1756 subtest = 2;
1757
1758 if (semctl(0, 0, IPC_INFO, &seminfo) == -1) e(0);
1759
1760 /*
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.
1764 */
1765 test_perm(test88c_perm1, 0 /*owner_test*/);
1766 test_perm(test88c_perm2, 1 /*owner_test*/);
1767 test_perm(test88c_perm3, 1 /*owner_test*/);
1768
1769 /* Create identifiers known to be invalid. */
1770 if ((badid1 = semget(IPC_PRIVATE, 1, 0600)) < 0) e(0);
1771
1772 if (semctl(badid1, 0, IPC_RMID) != 0) e(0);
1773
1774 memset(&semds, 0, sizeof(semds));
1775 badid2 = IXSEQ_TO_IPCID(seminfo.semmni, semds.sem_perm);
1776
1777 if ((id = semget(IPC_PRIVATE, 3, IPC_CREAT | 0600)) < 0) e(0);
1778
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);
1782
1783 /* In this case we can't avoid sleeping for longer periods.. */
1784 while (time(&now) == semds.sem_ctime)
1785 usleep(250000);
1786
1787 /*
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.
1791 */
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);
1795
1796 if (semctl(badid1, 0, cmds[i]) != -1) e(0);
1797 if (errno != EINVAL) e(0);
1798
1799 if (semctl(badid2, 0, cmds[i]) != -1) e(0);
1800 if (errno != EINVAL) e(0);
1801
1802 if (semctl(-1, 0, cmds[i]) != -1) e(0);
1803 if (errno != EINVAL) e(0);
1804
1805 if (semctl(INT_MIN, 0, cmds[i]) != -1) e(0);
1806 if (errno != EINVAL) e(0);
1807
1808 if (semctl(id, -1, cmds[i]) != -1) e(0);
1809 if (errno != EINVAL) e(0);
1810
1811 if (semctl(id, 3, cmds[i]) != -1) e(0);
1812 if (errno != EINVAL) e(0);
1813
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);
1818 }
1819
1820 /*
1821 * Test the GETALL command.
1822 */
1823 /*
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.
1827 */
1828 for (j = 0; j < 5; j++) {
1829 for (i = 0; i < __arraycount(val); i++)
1830 val[i] = USHRT_MAX;
1831
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);
1836 }
1837
1838 for (i = 0; i < __arraycount(val); i++)
1839 val[i] = USHRT_MAX;
1840
1841 if (semctl(badid1, 0, GETALL, val) != -1) e(0);
1842 if (errno != EINVAL) e(0);
1843
1844 if (semctl(badid2, 0, GETALL, val) != -1) e(0);
1845 if (errno != EINVAL) e(0);
1846
1847 if (semctl(-1, 0, GETALL, val) != -1) e(0);
1848 if (errno != EINVAL) e(0);
1849
1850 if (semctl(INT_MIN, 0, GETALL, val) != -1) e(0);
1851 if (errno != EINVAL) e(0);
1852
1853 for (i = 0; i < __arraycount(val); i++)
1854 if (val[i] != USHRT_MAX) e(0);
1855
1856 if (semctl(id, 0, GETALL, NULL) != -1) e(0);
1857 if (errno != EFAULT) e(0);
1858
1859 if (semctl(id, 0, GETALL, bad_ptr) != -1) e(0);
1860 if (errno != EFAULT) e(0);
1861
1862 if (semctl(id, 0, GETALL, ((unsigned short *)bad_ptr) - 2) != -1) e(0);
1863 if (errno != EFAULT) e(0);
1864
1865 if (semctl(id, 0, GETALL, ((unsigned short *)bad_ptr) - 3) != 0) e(0);
1866
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);
1871
1872 /*
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.
1876 */
1877 /*
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
1880 * here.
1881 */
1882 memset(statbuf, 0x5a, sizeof(statbuf));
1883
1884 if (semctl(badid1, 0, IPC_STAT, statbuf) != -1) e(0);
1885 if (errno != EINVAL) e(0);
1886
1887 if (semctl(badid2, 0, IPC_STAT, statbuf) != -1) e(0);
1888 if (errno != EINVAL) e(0);
1889
1890 if (semctl(-1, 0, IPC_STAT, statbuf) != -1) e(0);
1891 if (errno != EINVAL) e(0);
1892
1893 if (semctl(INT_MIN, 0, IPC_STAT, statbuf) != -1) e(0);
1894 if (errno != EINVAL) e(0);
1895
1896 for (i = 0; i < sizeof(statbuf); i++)
1897 if (statbuf[i] != 0x5a) e(0);
1898
1899 if (semctl(id, 0, IPC_STAT, statbuf) != 0) e(0);
1900
1901 if (statbuf[sizeof(statbuf) - 1] != 0x5a) e(0);
1902
1903 if (semctl(id, 0, IPC_STAT, NULL) != -1) e(0);
1904 if (errno != EFAULT) e(0);
1905
1906 if (semctl(id, 0, IPC_STAT, bad_ptr) != -1) e(0);
1907 if (errno != EFAULT) e(0);
1908
1909 if (semctl(id, 0, IPC_STAT, ((struct semid_ds *)bad_ptr) - 1) != 0)
1910 e(0);
1911
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);
1915
1916 /*
1917 * Test SEM_STAT.
1918 */
1919 if ((id2 = semget(KEY_A, seminfo.semmsl, IPC_CREAT | 0642)) < 0) e(0);
1920
1921 memset(statbuf, 0x5a, sizeof(statbuf));
1922
1923 if (semctl(-1, 0, SEM_STAT, statbuf) != -1) e(0);
1924 if (errno != EINVAL) e(0);
1925
1926 if (semctl(seminfo.semmni, 0, SEM_STAT, statbuf) != -1) e(0);
1927 if (errno != EINVAL) e(0);
1928
1929 for (i = 0; i < sizeof(statbuf); i++)
1930 if (statbuf[i] != 0x5a) e(0);
1931
1932 memset(seen, 0, sizeof(seen));
1933
1934 for (i = 0; i < seminfo.semmni; i++) {
1935 errno = 0;
1936 if ((r = semctl(i, i / 2 - 1, SEM_STAT, statbuf)) == -1) {
1937 if (errno != EINVAL) e(0);
1938 continue;
1939 }
1940 if (r < 0) 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);
1945 if (r == id) {
1946 seen[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);
1955
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);
1959
1960 if (semctl(i, 0, SEM_STAT, bad_ptr) != -1) e(0);
1961 if (errno != EFAULT) e(0);
1962 } else if (r == id2) {
1963 seen[1]++;
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);
1971 }
1972 }
1973
1974 if (seen[0] != 1) e(0);
1975 if (seen[1] != 1) e(0);
1976
1977 if (statbuf[sizeof(statbuf) - 1] != 0x5a) e(0);
1978
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);
1982
1983 /*
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.
1986 */
1987 if (semctl(badid1, 0, SETVAL, 1) != -1) e(0);
1988 if (errno != EINVAL) e(0);
1989
1990 if (semctl(badid2, 0, SETVAL, 1) != -1) e(0);
1991 if (errno != EINVAL) e(0);
1992
1993 if (semctl(-1, 0, SETVAL, 1) != -1) e(0);
1994 if (errno != EINVAL) e(0);
1995
1996 if (semctl(INT_MIN, 0, SETVAL, 1) != -1) e(0);
1997 if (errno != EINVAL) e(0);
1998
1999 if (semctl(id, -1, SETVAL, 1) != -1) e(0);
2000 if (errno != EINVAL) e(0);
2001
2002 if (semctl(id, 3, SETVAL, 1) != -1) e(0);
2003 if (errno != EINVAL) e(0);
2004
2005 if (semctl(id, 0, SETVAL, -1) != -1) e(0);
2006 if (errno != ERANGE) e(0);
2007
2008 if (semctl(id, 0, SETVAL, seminfo.semvmx + 1) != -1) e(0);
2009 if (errno != ERANGE) e(0);
2010
2011 TEST_SEM(id, 0, 0, 0, 0, 0);
2012
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);
2016
2017 /* Alright, there we go.. */
2018 if (semctl(id, 1, SETVAL, 0) != 0) e(0);
2019
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);
2023
2024 TEST_SEM(id, 1, 0, 0, 0, 0);
2025
2026 if (semctl(id, 2, SETVAL, seminfo.semvmx) != 0) e(0);
2027
2028 TEST_SEM(id, 2, seminfo.semvmx, 0, 0, 0);
2029
2030 if (semctl(id, 0, SETVAL, 1) != 0) e(0);
2031
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);
2035
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);
2040
2041 if (semctl(id, 0, IPC_STAT, &semds) != 0) e(0);
2042
2043 while (time(&now) == semds.sem_ctime)
2044 usleep(250000);
2045
2046 /*
2047 * Test SETALL. Same idea: failure cases first.
2048 */
2049 if (semctl(badid1, 0, SETALL, 1) != -1) e(0);
2050 if (errno != EINVAL) e(0);
2051
2052 if (semctl(badid2, 0, SETALL, 1) != -1) e(0);
2053 if (errno != EINVAL) e(0);
2054
2055 if (semctl(-1, 0, SETALL, 1) != -1) e(0);
2056 if (errno != EINVAL) e(0);
2057
2058 if (semctl(INT_MIN, 0, SETALL, 1) != -1) e(0);
2059 if (errno != EINVAL) e(0);
2060
2061 val[0] = seminfo.semvmx + 1;
2062 val[1] = 0;
2063 val[2] = 0;
2064 if (semctl(id, 0, SETALL, val) != -1) e(0);
2065 if (errno != ERANGE) e(0);
2066
2067 val[0] = 0;
2068 val[1] = 1;
2069 val[2] = seminfo.semvmx + 1;
2070 if (semctl(id, 0, SETALL, val) != -1) e(0);
2071 if (errno != ERANGE) e(0);
2072
2073 if (semctl(id, 0, SETALL, NULL) != -1) e(0);
2074 if (errno != EFAULT) e(0);
2075
2076 if (semctl(id, 0, SETALL, bad_ptr) != -1) e(0);
2077 if (errno != EFAULT) e(0);
2078
2079 if (semctl(id, 0, SETALL, ((unsigned short *)bad_ptr) - 2) != -1) e(0);
2080 if (errno != EFAULT) e(0);
2081
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);
2085
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);
2089
2090 val[0] = seminfo.semvmx;
2091 val[1] = 0;
2092 val[2] = 0;
2093 if (semctl(id, 0, SETALL, val) != 0) e(0);
2094
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);
2098
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);
2102
2103 val[0] = 0;
2104 val[1] = 1;
2105 val[2] = seminfo.semvmx;
2106 if (semctl(id, INT_MAX, SETALL, val) != 0) e(0);
2107
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);
2111
2112 memset(page_ptr, 0, page_size);
2113 if (semctl(id, 0, SETALL, ((unsigned short *)bad_ptr) - 3) != 0) e(0);
2114
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);
2118
2119 while (time(&now) == semds.sem_ctime)
2120 usleep(250000);
2121
2122 /*
2123 * Test IPC_SET. Its core functionality has already been tested
2124 * thoroughly as part of the permission tests.
2125 */
2126 if (semctl(badid1, 0, IPC_SET, &semds) != -1) e(0);
2127 if (errno != EINVAL) e(0);
2128
2129 if (semctl(badid2, 0, IPC_SET, &semds) != -1) e(0);
2130 if (errno != EINVAL) e(0);
2131
2132 if (semctl(-1, 0, IPC_SET, &semds) != -1) e(0);
2133 if (errno != EINVAL) e(0);
2134
2135 if (semctl(INT_MIN, 0, IPC_SET, &semds) != -1) e(0);
2136 if (errno != EINVAL) e(0);
2137
2138 if (semctl(id, 0, IPC_SET, NULL) != -1) e(0);
2139 if (errno != EFAULT) e(0);
2140
2141 if (semctl(id, 0, IPC_SET, bad_ptr) != -1) e(0);
2142 if (errno != EFAULT) e(0);
2143
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);
2147
2148 /*
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.
2154 */
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);
2160
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);
2172
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);
2179
2180 if (semctl(id, i / 2 - 2, IPC_STAT, &semds) != 0) e(0);
2181 if (semds.sem_perm.mode != (SEM_ALLOC | i)) e(0);
2182
2183 semds.sem_perm.mode = ~0777 | i;
2184 if (semctl(id, i / 2 - 3, IPC_SET, &semds) != 0) e(0);
2185
2186 if (semctl(id, i / 2 - 4, IPC_STAT, &semds) != 0) e(0);
2187 if (semds.sem_perm.mode != (SEM_ALLOC | i)) e(0);
2188 }
2189 if (semds.sem_perm.uid != osemds.sem_perm.uid) e(0);
2190 if (semds.sem_perm.gid != osemds.sem_perm.gid) e(0);
2191
2192 if (semctl(id, 0, IPC_SET, ((struct semid_ds *)bad_ptr) - 1) != 0)
2193 e(0);
2194
2195 /*
2196 * Test IPC_RMID. Its basic functionality has already been tested
2197 * multiple times over, so there is not much left to do here.
2198 */
2199 if (semctl(badid1, 0, IPC_RMID) != -1) e(0);
2200 if (errno != EINVAL) e(0);
2201
2202 if (semctl(badid2, 0, IPC_RMID) != -1) e(0);
2203 if (errno != EINVAL) e(0);
2204
2205 if (semctl(-1, 0, IPC_RMID) != -1) e(0);
2206 if (errno != EINVAL) e(0);
2207
2208 if (semctl(INT_MIN, 0, IPC_RMID) != -1) e(0);
2209 if (errno != EINVAL) e(0);
2210
2211 if (semctl(id, 0, IPC_RMID) != 0) e(0);
2212
2213 if (semctl(id, 0, IPC_RMID) != -1) e(0);
2214 if (errno != EINVAL) e(0);
2215
2216 if (semctl(id, 0, IPC_STAT, &semds) != -1) e(0);
2217 if (errno != EINVAL) e(0);
2218
2219 if (semctl(id2, 1, IPC_RMID) != 0) e(0);
2220
2221 if (semctl(id2, 1, IPC_RMID) != -1) e(0);
2222 if (errno != EINVAL) e(0);
2223
2224 /*
2225 * Test IPC_INFO and SEM_INFO. Right now, for all practical purposes,
2226 * these identifiers behave pretty much the same.
2227 */
2228 if ((id = semget(IPC_PRIVATE, 3, 0600)) == -1) e(0);
2229 if ((id2 = semget(IPC_PRIVATE, 1, 0600)) == -1) e(0);
2230
2231 for (i = 0; i <= 1; i++) {
2232 cmd = (i == 0) ? IPC_INFO : SEM_INFO;
2233
2234 memset(&seminfo, 0xff, sizeof(seminfo));
2235
2236 if ((r = semctl(0, 0, cmd, &seminfo)) == -1) e(0);
2237
2238 /*
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.
2245 */
2246 if (r < 1 || r >= seminfo.semmni) e(0);
2247
2248 /*
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.
2252 */
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);
2262 } else
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);
2267 } else
2268 if (seminfo.semaem < 0) e(0);
2269
2270 if (semctl(INT_MAX, -1, cmd, &seminfo) == -1) e(0);
2271 if (semctl(-1, INT_MAX, cmd, &seminfo) == -1) e(0);
2272
2273 if (semctl(0, 0, cmd, NULL) != -1) e(0);
2274 if (errno != EFAULT) e(0);
2275
2276 if (semctl(0, 0, cmd, bad_ptr) != -1) e(0);
2277 if (errno != EFAULT) e(0);
2278
2279 if (semctl(0, 0, cmd, ((struct seminfo *)bad_ptr) - 1) == -1)
2280 e(0);
2281 }
2282
2283 if (semctl(id2, 0, IPC_RMID) != 0) e(0);
2284
2285 /*
2286 * Finally, test invalid commands. Well, hopefully invalid commands,
2287 * anyway.
2288 */
2289 if (semctl(id, 0, INT_MIN) != -1) e(0);
2290 if (errno != EINVAL) e(0);
2291
2292 if (semctl(id, 0, INT_MAX) != -1) e(0);
2293 if (errno != EINVAL) e(0);
2294
2295 if (semctl(id, 0, IPC_RMID) != 0) e(0);
2296 }
2297
2298 /*
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.
2301 */
2302 static void
test88d(void)2303 test88d(void)
2304 {
2305 struct sembuf sop;
2306 int id;
2307
2308 subtest = 3;
2309
2310 if ((id = semget(IPC_PRIVATE, 1, 0600)) == -1) e(0);
2311
2312 /*
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.
2315 */
2316 if (!(SHRT_MAX & SEM_UNDO)) e(0);
2317 sop.sem_num = 0;
2318 sop.sem_op = 1;
2319 sop.sem_flg = SHRT_MAX;
2320 if (semop(id, &sop, 1) != -1) e(0);
2321 if (errno != EINVAL) e(0);
2322
2323 if (semctl(id, 0, IPC_RMID) != 0) e(0);
2324 }
2325
2326 enum {
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 */
2330 NR_RESUMES
2331 };
2332
2333 enum {
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 */
2340 NR_MATCHES
2341 };
2342
2343 /*
2344 * Auxiliary child procedure. The auxiliary children will deadlock until the
2345 * semaphore set is removed.
2346 */
2347 static void
test88e_childaux(struct link * parent)2348 test88e_childaux(struct link * parent)
2349 {
2350 struct sembuf sops[3];
2351 struct seminfo seminfo;
2352 int child, id, num;
2353
2354 child = rcv(parent);
2355 id = rcv(parent);
2356 num = rcv(parent);
2357
2358 memset(sops, 0, sizeof(sops));
2359
2360 /* These operations are guaranteed to never return successfully. */
2361 switch (child) {
2362 case 1:
2363 sops[0].sem_num = num;
2364 sops[0].sem_op = 1;
2365 sops[1].sem_num = num;
2366 sops[1].sem_op = 0;
2367 sops[2].sem_num = 0;
2368 sops[2].sem_op = 1;
2369 break;
2370 case 2:
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;
2377 sops[2].sem_op = 1;
2378 break;
2379 default:
2380 e(0);
2381 }
2382
2383 snd(parent, 0);
2384
2385 if (semop(id, sops, 3) != -1) e(0);
2386 if (errno != EIDRM) e(0);
2387 }
2388
2389 /*
2390 * First child procedure.
2391 */
2392 static void
test88e_child1(struct link * parent)2393 test88e_child1(struct link * parent)
2394 {
2395 struct sembuf sops[3];
2396 size_t nsops;
2397 int match, id, expect;
2398
2399 match = rcv(parent);
2400 id = rcv(parent);
2401
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;
2406 nsops = 2;
2407 expect = 0;
2408 switch (match) {
2409 case MATCH_FIRST:
2410 sops[1].sem_num = 3;
2411 sops[1].sem_op = 1;
2412 break;
2413 case MATCH_SECOND:
2414 sops[1].sem_num = 3;
2415 sops[1].sem_op = -1;
2416 sops[2].sem_num = 0;
2417 sops[2].sem_op = 1;
2418 nsops = 3;
2419 expect = -1;
2420 break;
2421 case MATCH_KILL:
2422 sops[1].sem_num = 0;
2423 sops[1].sem_op = 1;
2424 expect = INT_MIN;
2425 break;
2426 case MATCH_BOTH:
2427 case MATCH_CASCADE:
2428 case MATCH_ALL:
2429 sops[1].sem_num = 3;
2430 sops[1].sem_op = 1;
2431 break;
2432 default:
2433 e(0);
2434 }
2435
2436 snd(parent, 0);
2437
2438 if (semop(id, sops, nsops) != expect) e(0);
2439 if (expect == -1 && errno != EIDRM) e(0);
2440 }
2441
2442 /*
2443 * Second child procedure.
2444 */
2445 static void
test88e_child2(struct link * parent)2446 test88e_child2(struct link * parent)
2447 {
2448 struct sembuf sops[2];
2449 size_t nsops;
2450 int match, id, expect;
2451
2452 match = rcv(parent);
2453 id = rcv(parent);
2454
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;
2459 nsops = 2;
2460 expect = 0;
2461 switch (match) {
2462 case MATCH_FIRST:
2463 sops[1].sem_num = 0;
2464 sops[1].sem_op = 1;
2465 expect = -1;
2466 break;
2467 case MATCH_SECOND:
2468 case MATCH_KILL:
2469 nsops = 1;
2470 break;
2471 case MATCH_BOTH:
2472 case MATCH_ALL:
2473 sops[1].sem_num = 3;
2474 sops[1].sem_op = 1;
2475 break;
2476 case MATCH_CASCADE:
2477 sops[0].sem_num = 3;
2478 nsops = 1;
2479 break;
2480 default:
2481 e(0);
2482 }
2483
2484 snd(parent, 0);
2485
2486 if (semop(id, sops, nsops) != expect) e(0);
2487 if (expect == -1 && errno != EIDRM) e(0);
2488 }
2489
2490 /*
2491 * Third child procedure.
2492 */
2493 static void
test88e_child3(struct link * parent)2494 test88e_child3(struct link * parent)
2495 {
2496 struct sembuf sops[1];
2497 size_t nsops;
2498 int match, id;
2499
2500 match = rcv(parent);
2501 id = rcv(parent);
2502
2503 /* Things are a bit simpler here. */
2504 memset(sops, 0, sizeof(sops));
2505 nsops = 1;
2506 switch (match) {
2507 case MATCH_ALL:
2508 sops[0].sem_num = 3;
2509 sops[0].sem_op = -2;
2510 break;
2511 default:
2512 e(0);
2513 }
2514
2515 snd(parent, 0);
2516
2517 if (semop(id, sops, nsops) != 0) e(0);
2518 }
2519
2520 /*
2521 * Perform one test for operations affecting multiple processes.
2522 */
2523 static void
sub88e(unsigned int match,unsigned int resume,unsigned int aux)2524 sub88e(unsigned int match, unsigned int resume, unsigned int aux)
2525 {
2526 struct link aux1, aux2, child1, child2, child3;
2527 struct sembuf sop;
2528 unsigned short val[4];
2529 int id, inc, aux_zcnt, aux_ncnt;
2530
2531 /*
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.
2538 */
2539 if ((id = semget(IPC_PRIVATE, __arraycount(val), 0666)) == -1) e(0);
2540
2541 aux_zcnt = aux_ncnt = 0;
2542
2543 /* Start the first auxiliary child if desired, before all others. */
2544 if (aux & 1) {
2545 spawn(&aux1, test88e_childaux, DROP_ALL);
2546
2547 snd(&aux1, 1);
2548 snd(&aux1, id);
2549 snd(&aux1, (aux & 4) ? 2 : 1);
2550
2551 if (rcv(&aux1) != 0) e(0);
2552
2553 if (aux & 4)
2554 aux_zcnt++;
2555 }
2556
2557 /* Start and configure all children for this specific match test. */
2558 spawn(&child1, test88e_child1, DROP_ALL);
2559
2560 snd(&child1, match);
2561 snd(&child1, id);
2562
2563 if (rcv(&child1) != 0) e(0);
2564
2565 /*
2566 * For fairness tests, we must ensure that the first child blocks on
2567 * the semaphore before the second child does.
2568 */
2569 switch (match) {
2570 case MATCH_FIRST:
2571 case MATCH_SECOND:
2572 case MATCH_KILL:
2573 usleep(WAIT_USECS);
2574 break;
2575 }
2576
2577 spawn(&child2, test88e_child2, DROP_NONE);
2578
2579 snd(&child2, match);
2580 snd(&child2, id);
2581
2582 if (rcv(&child2) != 0) e(0);
2583
2584 if (match == MATCH_ALL) {
2585 spawn(&child3, test88e_child3, DROP_USER);
2586
2587 snd(&child3, match);
2588 snd(&child3, id);
2589
2590 if (rcv(&child3) != 0) e(0);
2591 }
2592
2593 /* Start the second auxiliary child if desired, after all others. */
2594 if (aux & 2) {
2595 spawn(&aux2, test88e_childaux, DROP_NONE);
2596
2597 snd(&aux2, 2);
2598 snd(&aux2, id);
2599 snd(&aux2, (aux & 4) ? 2 : 1);
2600
2601 if (rcv(&aux2) != 0) e(0);
2602
2603 if (aux & 4)
2604 aux_ncnt++;
2605 }
2606
2607 usleep(WAIT_USECS);
2608
2609 /*
2610 * Test semaphore values and determine the value with which to increase
2611 * the third semaphore. For MATCH_KILL, also kill the first child.
2612 */
2613 inc = 1;
2614 switch (match) {
2615 case MATCH_FIRST:
2616 case MATCH_SECOND:
2617 TEST_SEM(id, 2, 0, 0, 2 + aux_ncnt, aux_zcnt);
2618 TEST_SEM(id, 3, 0, 0, 0, 0);
2619 break;
2620 case MATCH_KILL:
2621 TEST_SEM(id, 2, 0, 0, 2 + aux_ncnt, aux_zcnt);
2622
2623 terminate(&child1);
2624
2625 /* As stated before, non-self kills need not be instant. */
2626 usleep(WAIT_USECS);
2627
2628 TEST_SEM(id, 2, 0, 0, 1 + aux_ncnt, aux_zcnt);
2629 TEST_SEM(id, 3, 0, 0, 0, 0);
2630 break;
2631 case MATCH_BOTH:
2632 TEST_SEM(id, 2, 0, 0, 2 + aux_ncnt, aux_zcnt);
2633 TEST_SEM(id, 3, 0, 0, 0, 0);
2634 inc = 2;
2635 break;
2636 case MATCH_CASCADE:
2637 TEST_SEM(id, 2, 0, 0, 1 + aux_ncnt, aux_zcnt);
2638 TEST_SEM(id, 3, 0, 0, 1, 0);
2639 break;
2640 case MATCH_ALL:
2641 TEST_SEM(id, 2, 0, 0, 2 + aux_ncnt, aux_zcnt);
2642 TEST_SEM(id, 3, 0, 0, 1, 0);
2643 inc = 2;
2644 break;
2645 default:
2646 e(0);
2647 }
2648
2649 TEST_SEM(id, 0, 0, 0, 0, 0);
2650 TEST_SEM(id, 1, 0, 0, -1, -1);
2651
2652 /* Resume the appropriate set of children. */
2653 switch (resume) {
2654 case RESUME_SEMOP:
2655 memset(&sop, 0, sizeof(sop));
2656 sop.sem_num = 2;
2657 sop.sem_op = inc;
2658 if (semop(id, &sop, 1) != 0) e(0);
2659 break;
2660 case RESUME_SETVAL:
2661 if (semctl(id, 2, SETVAL, inc) != 0) e(0);
2662 break;
2663 case RESUME_SETALL:
2664 memset(val, 0, sizeof(val));
2665 val[2] = inc;
2666 if (semctl(id, 0, SETALL, val) != 0) e(0);
2667 break;
2668 default:
2669 e(0);
2670 }
2671
2672 /*
2673 * See if the right children were indeed resumed, and retest the
2674 * semaphore values.
2675 */
2676 switch (match) {
2677 case MATCH_FIRST:
2678 TEST_SEM(id, 2, 0, child1.pid, 1 + aux_ncnt, aux_zcnt);
2679 TEST_SEM(id, 3, 1, child1.pid, 0, 0);
2680 collect(&child1);
2681 break;
2682 case MATCH_SECOND:
2683 TEST_SEM(id, 2, 0, child2.pid, 1 + aux_ncnt, aux_zcnt);
2684 TEST_SEM(id, 3, 0, 0, 0, 0);
2685 collect(&child2);
2686 break;
2687 case MATCH_KILL:
2688 TEST_SEM(id, 2, 0, child2.pid, aux_ncnt, aux_zcnt);
2689 TEST_SEM(id, 3, 0, 0, 0, 0);
2690 collect(&child2);
2691 break;
2692 case MATCH_BOTH:
2693 /*
2694 * The children are not ordered in this case, so we do not know
2695 * which one gets access to the semaphores last.
2696 */
2697 TEST_SEM(id, 2, 0, -1, aux_ncnt, aux_zcnt);
2698 TEST_SEM(id, 3, 2, -1, 0, 0);
2699 collect(&child1);
2700 collect(&child2);
2701 break;
2702 case MATCH_CASCADE:
2703 TEST_SEM(id, 2, 0, child1.pid, aux_ncnt, aux_zcnt);
2704 TEST_SEM(id, 3, 0, child2.pid, 0, 0);
2705 collect(&child1);
2706 collect(&child2);
2707 break;
2708 case MATCH_ALL:
2709 TEST_SEM(id, 2, 0, -1, aux_ncnt, aux_zcnt);
2710 TEST_SEM(id, 3, 0, child3.pid, 0, 0);
2711 collect(&child1);
2712 collect(&child2);
2713 collect(&child3);
2714 break;
2715 default:
2716 e(0);
2717 }
2718
2719 TEST_SEM(id, 0, 0, 0, 0, 0);
2720 TEST_SEM(id, 1, 0, 0, -1, -1);
2721
2722 /* Remove the semaphore set. This should unblock remaining callers. */
2723 if (semctl(id, 0, IPC_RMID) != 0) e(0);
2724
2725 /* Wait for the children that were not resumed, but should be now. */
2726 switch (match) {
2727 case MATCH_FIRST:
2728 collect(&child2);
2729 break;
2730 case MATCH_SECOND:
2731 collect(&child1);
2732 break;
2733 case MATCH_KILL:
2734 case MATCH_BOTH:
2735 case MATCH_CASCADE:
2736 case MATCH_ALL:
2737 break;
2738 default:
2739 e(0);
2740 }
2741
2742 /* Wait for the auxiliary children as well. */
2743 if (aux & 1)
2744 collect(&aux1);
2745 if (aux & 2)
2746 collect(&aux2);
2747 }
2748
2749 /*
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.
2756 */
2757 static void
test88e(void)2758 test88e(void)
2759 {
2760 unsigned int resume, match, aux;
2761
2762 subtest = 4;
2763
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);
2768 }
2769
2770 /*
2771 * Verify that non-root processes can use sysctl(2) to see semaphore sets
2772 * created by root.
2773 */
2774 static void
test88f_child(struct link * parent)2775 test88f_child(struct link * parent)
2776 {
2777 static const int mib[] = { CTL_KERN, KERN_SYSVIPC, KERN_SYSVIPC_INFO,
2778 KERN_SYSVIPC_SEM_INFO };
2779 struct sem_sysctl_info *semsi;
2780 size_t len;
2781 int id[2], id2, seen[2];
2782 int32_t i;
2783
2784 id[0] = rcv(parent);
2785 id[1] = rcv(parent);
2786
2787 if (sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0) != 0) e(0);
2788
2789 if ((semsi = malloc(len)) == NULL) e(0);
2790
2791 if (sysctl(mib, __arraycount(mib), semsi, &len, NULL, 0) != 0) e(0);
2792
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))
2796 continue;
2797
2798 id2 = IXSEQ_TO_IPCID(i, semsi->semids[i].sem_perm);
2799 if (id2 == id[0])
2800 seen[0]++;
2801 else if (id2 == id[1])
2802 seen[1]++;
2803 }
2804
2805 free(semsi);
2806
2807 if (seen[0] != 1) e(0);
2808 if (seen[1] != 1) e(0);
2809 }
2810
2811 /*
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.
2814 */
2815 static void
test88f(void)2816 test88f(void)
2817 {
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;
2823 struct link child;
2824 size_t len, size;
2825 int id[2], id2;
2826 int32_t i, slot[2];
2827
2828 /*
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.
2833 */
2834 len = sizeof(seminfo);
2835 if (sysctl(mib, __arraycount(mib), &seminfo, &len, NULL, 0) != 0) e(0);
2836 if (len != sizeof(seminfo)) e(0);
2837
2838 if (semctl(0, 0, IPC_INFO, &seminfo2) == -1) e(0);
2839
2840 if (memcmp(&seminfo, &seminfo2, sizeof(seminfo)) != 0) e(0);
2841
2842 /* Verify that the correct size estimation is returned. */
2843 if (seminfo.semmni <= 0) e(0);
2844 if (seminfo.semmni > SHRT_MAX) e(0);
2845
2846 size = sizeof(*semsi) +
2847 sizeof(semsi->semids[0]) * (seminfo.semmni - 1);
2848
2849 len = 0;
2850 if (sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0) != 0) e(0);
2851 if (len != size) e(0);
2852
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);
2855
2856 if ((id[1] = semget(IPC_PRIVATE, 3, 0650)) < 0) e(0);
2857
2858 /*
2859 * Retrieve the entire semaphore array, and verify that the general
2860 * semaphore information is still correct.
2861 */
2862 if ((semsi = malloc(size)) == NULL) e(0);
2863
2864 len = size;
2865 if (sysctl(mib, __arraycount(mib), semsi, &len, NULL, 0) != 0) e(0);
2866 if (len != size) e(0);
2867
2868 if (sizeof(semsi->seminfo) != sizeof(seminfo)) e(0);
2869 if (memcmp(&semsi->seminfo, &seminfo, sizeof(semsi->seminfo)) != 0)
2870 e(0);
2871
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))
2876 continue;
2877
2878 id2 = IXSEQ_TO_IPCID(i, semsi->semids[i].sem_perm);
2879 if (id2 == id[0]) {
2880 if (slot[0] != -1) e(0);
2881 slot[0] = i;
2882 } else if (id2 == id[1]) {
2883 if (slot[1] != -1) e(0);
2884 slot[1] = i;
2885 }
2886 }
2887
2888 if (slot[0] < 0) e(0);
2889 if (slot[1] < 0) e(0);
2890
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);
2902
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);
2913
2914 /* Make sure that non-root users can see them as well. */
2915 spawn(&child, test88f_child, DROP_ALL);
2916
2917 snd(&child, id[0]);
2918 snd(&child, id[1]);
2919
2920 collect(&child);
2921
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);
2925
2926 len = size;
2927 if (sysctl(mib, __arraycount(mib), semsi, &len, NULL, 0) != 0) e(0);
2928 if (len != size) e(0);
2929
2930 for (i = 0; i < seminfo.semmni; i++) {
2931 if (!(semsi->semids[i].sem_perm.mode & SEM_ALLOC))
2932 continue;
2933
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);
2937 }
2938
2939 free(semsi);
2940 }
2941
2942 /*
2943 * Initialize the test.
2944 */
2945 static void
test88_init(void)2946 test88_init(void)
2947 {
2948 static const int mib[] = { CTL_KERN, KERN_SYSVIPC, KERN_SYSVIPC_SEM };
2949 struct group *gr;
2950 size_t len;
2951 int i;
2952
2953 /* Start with full root privileges. */
2954 setuid(geteuid());
2955
2956 if ((gr = getgrnam(ROOT_GROUP)) == NULL) e(0);
2957
2958 setgid(gr->gr_gid);
2959 setegid(gr->gr_gid);
2960
2961 /*
2962 * Verify that the IPC service is running at all. If not, there is
2963 * obviously no point in running this test.
2964 */
2965 len = sizeof(i);
2966 if (sysctl(mib, __arraycount(mib), &i, &len, NULL, 0) != 0) e(0);
2967 if (len != sizeof(i)) e(0);
2968
2969 if (i == 0) {
2970 printf("skipped\n");
2971 cleanup();
2972 exit(0);
2973 }
2974
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);
2982 }
2983
2984 /*
2985 * Test program for SysV IPC semaphores.
2986 */
2987 int
main(int argc,char ** argv)2988 main(int argc, char ** argv)
2989 {
2990 int i, m;
2991
2992 start(88);
2993
2994 test88_init();
2995
2996 if (argc == 2)
2997 m = atoi(argv[1]);
2998 else
2999 m = 0xFF;
3000
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();
3008 }
3009
3010 quit();
3011 }
3012