1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * HISTORY
6 * 03/2001 - Written by Wayne Boyer
7 */
8 /*\
9 * [Description]
10 *
11 * Test for semctl() EPERM error
12 *
13 * Runs IPC_SET and IPC_RMID from unprivileged child process.
14 *
15 */
16
17 #include <pwd.h>
18 #include <sys/wait.h>
19 #include "tst_safe_sysv_ipc.h"
20 #include "tst_test.h"
21 #include "lapi/sem.h"
22 #include "libnewipc.h"
23
24 static uid_t ltp_uid;
25 static int sem_id = -1;
26
27 static int tcases[] = { IPC_SET, IPC_RMID };
28
do_child(void)29 static void do_child(void)
30 {
31 int i;
32 union semun arg;
33 struct semid_ds perm;
34
35 for (i = 0; i < 2; i++) {
36 if (tcases[i] == IPC_SET) {
37 arg.buf = &perm;
38 memset(&perm, 0, sizeof(perm));
39 perm.sem_perm.uid = getuid() + 1;
40 perm.sem_perm.gid = getgid() + 1;
41 perm.sem_perm.mode = 0666;
42 }
43
44 TST_EXP_FAIL(semctl(sem_id, 0, tcases[i], arg), EPERM,
45 "semctl() with nobody user in child");
46 }
47 }
48
verify_semctl(void)49 static void verify_semctl(void)
50 {
51 pid_t pid;
52
53 pid = SAFE_FORK();
54
55 if (pid == 0) {
56 SAFE_SETEUID(ltp_uid);
57 do_child();
58 } else {
59 SAFE_WAITPID(pid, NULL, 0);
60 }
61 }
62
setup(void)63 static void setup(void)
64 {
65 static key_t semkey;
66
67 semkey = GETIPCKEY();
68
69 sem_id = SAFE_SEMGET(semkey, PSEMS, IPC_CREAT | IPC_EXCL);
70
71 struct passwd *ltpuser = SAFE_GETPWNAM("nobody");
72 ltp_uid = ltpuser->pw_uid;
73 }
74
cleanup(void)75 static void cleanup(void)
76 {
77 if (sem_id != -1)
78 SAFE_SEMCTL(sem_id, 0, IPC_RMID);
79 }
80
81 static struct tst_test test = {
82 .setup = setup,
83 .cleanup = cleanup,
84 .forks_child = 1,
85 .needs_root = 1,
86 .test_all = verify_semctl,
87 };
88