Skip to content

Commit cd96acc

Browse files
committed
test/zdtm/static: add maps11 test for MAP_DROPPABLE/MADV_WIPEONFORK
In this test we want to ensure that contents of droppable mappings and mappings with MADV_WIPEONFORK is properly restored in parent/child processes. Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
1 parent 3f045e0 commit cd96acc

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

test/zdtm/static/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ TST_NOFILE := \
150150
maps05 \
151151
maps09 \
152152
maps10 \
153+
maps11 \
153154
mlock_setuid \
154155
xids00 \
155156
groups \

test/zdtm/static/maps11.c

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#include <stdint.h>
2+
#include <signal.h>
3+
#include <sys/mman.h>
4+
#include <sys/types.h>
5+
#include <sys/wait.h>
6+
#include "zdtmtst.h"
7+
8+
#ifndef MAP_DROPPABLE
9+
#define MAP_DROPPABLE 0x08
10+
#endif
11+
12+
#ifndef MADV_WIPEONFORK
13+
#define MADV_WIPEONFORK 18
14+
#endif
15+
16+
const char *test_doc = "Test MAP_DROPPABLE/MADV_WIPEONFORK mappings with 2 processes";
17+
const char *test_author = "Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>";
18+
19+
int main(int argc, char **argv)
20+
{
21+
uint8_t *p1, *p2;
22+
task_waiter_t t;
23+
pid_t pid;
24+
int status;
25+
const char data[] = "MADV_WIPEONFORK vma data";
26+
27+
test_init(argc, argv);
28+
task_waiter_init(&t);
29+
30+
p1 = mmap(NULL, sizeof(data), PROT_READ | PROT_WRITE, MAP_DROPPABLE | MAP_ANONYMOUS, 0, 0);
31+
if (p1 == MAP_FAILED) {
32+
if (errno == EINVAL) {
33+
skip("mmap failed, no kernel support for MAP_DROPPABLE\n");
34+
goto skip;
35+
} else {
36+
pr_perror("mmap failed");
37+
return -1;
38+
}
39+
}
40+
41+
p2 = mmap(NULL, sizeof(data), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
42+
if (p2 == MAP_FAILED) {
43+
pr_perror("mmap failed");
44+
return 1;
45+
}
46+
47+
if (madvise(p2, sizeof(data), MADV_WIPEONFORK)) {
48+
pr_perror("madvise failed");
49+
return -1;
50+
}
51+
52+
memcpy(p1, data, sizeof(data));
53+
memcpy(p2, data, sizeof(data));
54+
55+
pid = test_fork();
56+
if (pid < 0) {
57+
pr_perror("fork failed");
58+
return 1;
59+
}
60+
61+
if (pid == 0) {
62+
task_waiter_complete(&t, 1);
63+
test_waitsig();
64+
65+
/*
66+
* MAP_DROPPABLE mappings have VM_WIPEONFORK flag set,
67+
* so we expect to have it null-ified after fork().
68+
*/
69+
if (*p1 != 0)
70+
return 1;
71+
72+
if (*p2 != 0)
73+
return 1;
74+
75+
return 0;
76+
}
77+
78+
task_waiter_wait4(&t, 1);
79+
80+
test_daemon();
81+
test_waitsig();
82+
83+
kill(pid, SIGTERM);
84+
wait(&status);
85+
if (WIFEXITED(status)) {
86+
if (WEXITSTATUS(status))
87+
goto err;
88+
} else {
89+
goto err;
90+
}
91+
92+
if (memcmp(p1, data, sizeof(data)) || memcmp(p2, data, sizeof(data))) {
93+
fail("Data mismatch");
94+
return 1;
95+
}
96+
97+
pass();
98+
99+
return 0;
100+
err:
101+
if (waitpid(-1, NULL, WNOHANG) == 0) {
102+
kill(pid, SIGTERM);
103+
wait(NULL);
104+
}
105+
return 1;
106+
107+
skip:
108+
test_daemon();
109+
test_waitsig();
110+
pass();
111+
return 0;
112+
}

0 commit comments

Comments
 (0)