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