Skip to content

Commit 6bf8ab1

Browse files
bsach64avagin
authored andcommitted
zdtm: Check pidfd can kill descendant processes
Validate that pidfds can been used to send signals to different processes after C/R using the `pidfd_send_signal()` syscall. Signed-off-by: Bhavik Sachdev <[email protected]>
1 parent 4cec03a commit 6bf8ab1

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed

test/zdtm/static/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ TST_NOFILE := \
5555
ptrace_sig \
5656
pidfd_self \
5757
pidfd_child \
58+
pidfd_kill \
5859
pipe00 \
5960
pipe01 \
6061
pipe02 \

test/zdtm/static/pidfd_kill.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#include <sys/syscall.h>
2+
#include <unistd.h>
3+
#include <sys/wait.h>
4+
5+
#include "zdtmtst.h"
6+
7+
const char *test_doc = "Kill child and grandchild process using pidfds\n";
8+
const char *test_author = "Bhavik Sachdev <[email protected]>";
9+
10+
static int pidfd_open(pid_t pid, unsigned int flags)
11+
{
12+
return syscall(__NR_pidfd_open, pid, flags);
13+
}
14+
15+
static int pidfd_send_signal(int pidfd, int sig, siginfo_t* info, unsigned int flags)
16+
{
17+
return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
18+
}
19+
20+
static int wait_for_child(int child)
21+
{
22+
int status;
23+
if (waitpid(child, &status, 0) != child) {
24+
pr_perror("waitpid()");
25+
return 1;
26+
}
27+
28+
if (status != 0) {
29+
test_msg("%d:%d:%d:%d", WIFEXITED(status), WEXITSTATUS(status),
30+
WIFSIGNALED(status), WTERMSIG(status));
31+
}
32+
33+
return 0;
34+
}
35+
36+
int main(int argc, char* argv[])
37+
{
38+
#define READ 0
39+
#define WRITE 1
40+
41+
int child, gchild, cpidfd, gpidfd, gchild_pid, ret;
42+
int p[2];
43+
44+
if (pipe(p)) {
45+
pr_perror("pipe");
46+
return 1;
47+
}
48+
49+
test_init(argc, argv);
50+
51+
child = fork();
52+
if (child < 0) {
53+
pr_perror("fork");
54+
return 1;
55+
}
56+
57+
if (child == 0) {
58+
gchild = fork();
59+
if (gchild < 0) {
60+
pr_perror("fork");
61+
return 1;
62+
}
63+
64+
if (gchild == 0) {
65+
test_waitsig();
66+
return 0;
67+
}
68+
69+
close(p[READ]);
70+
if (write(p[WRITE], &gchild, sizeof(gchild))
71+
!= sizeof(gchild)) {
72+
pr_perror("write");
73+
return 1;
74+
}
75+
close(p[WRITE]);
76+
77+
test_waitsig();
78+
return wait_for_child(gchild);
79+
}
80+
81+
cpidfd = pidfd_open(child, 0);
82+
if (cpidfd < 0) {
83+
pr_perror("pidfd_open");
84+
return 1;
85+
}
86+
87+
close(p[WRITE]);
88+
if (read(p[READ], &gchild_pid, sizeof(gchild_pid))
89+
!= sizeof(gchild_pid)) {
90+
pr_perror("read");
91+
return 1;
92+
}
93+
close(p[READ]);
94+
95+
gpidfd = pidfd_open(gchild_pid, 0);
96+
if (gpidfd < 0) {
97+
pr_perror("pidfd_open");
98+
return 1;
99+
}
100+
101+
test_daemon();
102+
test_waitsig();
103+
104+
if (pidfd_send_signal(gpidfd, SIGKILL, NULL, 0)) {
105+
pr_perror("Could not send signal");
106+
goto fail_close;
107+
}
108+
109+
if (pidfd_send_signal(cpidfd, SIGKILL, NULL, 0)) {
110+
pr_perror("Could not send signal");
111+
goto fail_close;
112+
}
113+
114+
ret = wait_for_child(child);
115+
if (ret)
116+
goto fail_close;
117+
118+
pass();
119+
close(cpidfd);
120+
close(gpidfd);
121+
return 0;
122+
123+
fail_close:
124+
fail();
125+
close(cpidfd);
126+
close(gpidfd);
127+
return 1;
128+
}

0 commit comments

Comments
 (0)