• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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