• 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  * Test case to check that kill() fails when passed a pid owned by another user.
6  *
7  * HISTORY
8  *	07/2001 Ported by Wayne Boyer
9  *
10  *      26/02/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
11  *      - Fix wrong return value check on shmat system call (leading to
12  *        segfault in case of error with this syscall).
13  *      - Fix deletion of IPC memory segment. Segment was not correctly
14  *        deleted due to the change of uid during the test.
15  *
16  * RESTRICTIONS
17  *	This test must be run as root.
18  */
19 
20 #include <sys/wait.h>
21 #include <pwd.h>
22 #include <stdlib.h>
23 #include "tst_test.h"
24 #include "libnewipc.h"
25 #include "tst_safe_sysv_ipc.h"
26 #include "tst_safe_macros.h"
27 #include "tst_uid.h"
28 
29 static uid_t test_users[2];
30 static int *flag;
31 static int shm_id = -1;
32 static key_t shm_key;
33 
wait_for_flag(int value)34 static void wait_for_flag(int value)
35 {
36 	while (1) {
37 		if (*flag == value)
38 			break;
39 
40 		usleep(100);
41 	}
42 }
43 
do_master_child(void)44 static void do_master_child(void)
45 {
46 	pid_t pid1;
47 
48 	*flag = 0;
49 	pid1 = SAFE_FORK();
50 	if (pid1 == 0) {
51 		SAFE_SETREUID(test_users[0], test_users[0]);
52 		*flag = 1;
53 		wait_for_flag(2);
54 
55 		exit(0);
56 	}
57 
58 	SAFE_SETREUID(test_users[1], test_users[1]);
59 	wait_for_flag(1);
60 	TEST(kill(pid1, SIGKILL));
61 
62 	*flag = 2;
63 	SAFE_WAITPID(pid1, NULL, 0);
64 
65 	if (TST_RET == 0)
66 		tst_brk(TFAIL, "kill succeeded unexpectedly");
67 
68 	if (TST_ERR == EPERM)
69 		tst_res(TPASS, "kill failed with EPERM");
70 	else
71 		tst_res(TFAIL | TTERRNO, "kill failed expected EPERM, but got");
72 }
73 
verify_kill(void)74 static void verify_kill(void)
75 {
76 	pid_t pid;
77 
78 	pid = SAFE_FORK();
79 	if (pid == 0) {
80 		do_master_child();
81 		exit(0);
82 	}
83 
84 	tst_reap_children();
85 }
86 
setup(void)87 static void setup(void)
88 {
89 	shm_key = GETIPCKEY();
90 	shm_id = SAFE_SHMGET(shm_key, getpagesize(), 0666 | IPC_CREAT);
91 	flag = SAFE_SHMAT(shm_id, 0, 0);
92 	tst_get_uids(test_users, 0, 2);
93 }
94 
cleanup(void)95 static void cleanup(void)
96 {
97 	if (shm_id != -1)
98 		SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
99 }
100 
101 static struct tst_test test = {
102 	.setup = setup,
103 	.cleanup = cleanup,
104 	.test_all = verify_kill,
105 	.needs_root = 1,
106 	.forks_child = 1,
107 };
108