diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2019-03-13 14:44:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-14 17:36:20 -0400 |
commit | 17415606f9d8be06580cc0a873e27a6e4309ba2e (patch) | |
tree | fa2255fed25111a8bdf3ad712e4b5ea3f4212270 /tools | |
parent | ce82f19fd5809f0cf87ea9f753c5cc65ca0673d6 (diff) |
tools/testing/selftests/proc/proc-pid-vm.c: test with vsyscall in mind
: selftests: proc: proc-pid-vm
: ========================================
: proc-pid-vm: proc-pid-vm.c:277: main: Assertion `rv == strlen(buf0)' failed.
: Aborted
Because the vsyscall mapping is enabled. Read from vsyscall page to tell
if vsyscall is being used.
Link: http://lkml.kernel.org/r/20190307183204.GA11405@avx2
Link: http://lkml.kernel.org/r/20190219094722.GB28258@shao2-debian
Fixes: 34aab6bec23e7e9 ("proc: test /proc/*/maps, smaps, smaps_rollup, statm")
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Reported-by: kernel test robot <rong.a.chen@intel.com>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/proc/proc-pid-vm.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c index bbe8150d18aa..7202bbac976e 100644 --- a/tools/testing/selftests/proc/proc-pid-vm.c +++ b/tools/testing/selftests/proc/proc-pid-vm.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <errno.h> | 29 | #include <errno.h> |
30 | #include <sched.h> | 30 | #include <sched.h> |
31 | #include <signal.h> | 31 | #include <signal.h> |
32 | #include <stdbool.h> | ||
32 | #include <stdint.h> | 33 | #include <stdint.h> |
33 | #include <stdio.h> | 34 | #include <stdio.h> |
34 | #include <string.h> | 35 | #include <string.h> |
@@ -36,11 +37,14 @@ | |||
36 | #include <sys/mount.h> | 37 | #include <sys/mount.h> |
37 | #include <sys/types.h> | 38 | #include <sys/types.h> |
38 | #include <sys/stat.h> | 39 | #include <sys/stat.h> |
40 | #include <sys/wait.h> | ||
39 | #include <fcntl.h> | 41 | #include <fcntl.h> |
40 | #include <unistd.h> | 42 | #include <unistd.h> |
41 | #include <sys/syscall.h> | 43 | #include <sys/syscall.h> |
42 | #include <sys/uio.h> | 44 | #include <sys/uio.h> |
43 | #include <linux/kdev_t.h> | 45 | #include <linux/kdev_t.h> |
46 | #include <sys/time.h> | ||
47 | #include <sys/resource.h> | ||
44 | 48 | ||
45 | static inline long sys_execveat(int dirfd, const char *pathname, char **argv, char **envp, int flags) | 49 | static inline long sys_execveat(int dirfd, const char *pathname, char **argv, char **envp, int flags) |
46 | { | 50 | { |
@@ -205,12 +209,44 @@ static int make_exe(const uint8_t *payload, size_t len) | |||
205 | } | 209 | } |
206 | #endif | 210 | #endif |
207 | 211 | ||
212 | static bool g_vsyscall = false; | ||
213 | |||
214 | static const char str_vsyscall[] = | ||
215 | "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n"; | ||
216 | |||
208 | #ifdef __x86_64__ | 217 | #ifdef __x86_64__ |
218 | /* | ||
219 | * vsyscall page can't be unmapped, probe it with memory load. | ||
220 | */ | ||
221 | static void vsyscall(void) | ||
222 | { | ||
223 | pid_t pid; | ||
224 | int wstatus; | ||
225 | |||
226 | pid = fork(); | ||
227 | if (pid < 0) { | ||
228 | fprintf(stderr, "fork, errno %d\n", errno); | ||
229 | exit(1); | ||
230 | } | ||
231 | if (pid == 0) { | ||
232 | struct rlimit rlim = {0, 0}; | ||
233 | (void)setrlimit(RLIMIT_CORE, &rlim); | ||
234 | *(volatile int *)0xffffffffff600000UL; | ||
235 | exit(0); | ||
236 | } | ||
237 | wait(&wstatus); | ||
238 | if (WIFEXITED(wstatus)) { | ||
239 | g_vsyscall = true; | ||
240 | } | ||
241 | } | ||
242 | |||
209 | int main(void) | 243 | int main(void) |
210 | { | 244 | { |
211 | int pipefd[2]; | 245 | int pipefd[2]; |
212 | int exec_fd; | 246 | int exec_fd; |
213 | 247 | ||
248 | vsyscall(); | ||
249 | |||
214 | atexit(ate); | 250 | atexit(ate); |
215 | 251 | ||
216 | make_private_tmp(); | 252 | make_private_tmp(); |
@@ -261,9 +297,9 @@ int main(void) | |||
261 | snprintf(buf0 + MAPS_OFFSET, sizeof(buf0) - MAPS_OFFSET, | 297 | snprintf(buf0 + MAPS_OFFSET, sizeof(buf0) - MAPS_OFFSET, |
262 | "/tmp/#%llu (deleted)\n", (unsigned long long)st.st_ino); | 298 | "/tmp/#%llu (deleted)\n", (unsigned long long)st.st_ino); |
263 | 299 | ||
264 | |||
265 | /* Test /proc/$PID/maps */ | 300 | /* Test /proc/$PID/maps */ |
266 | { | 301 | { |
302 | const size_t len = strlen(buf0) + (g_vsyscall ? strlen(str_vsyscall) : 0); | ||
267 | char buf[256]; | 303 | char buf[256]; |
268 | ssize_t rv; | 304 | ssize_t rv; |
269 | int fd; | 305 | int fd; |
@@ -274,13 +310,16 @@ int main(void) | |||
274 | return 1; | 310 | return 1; |
275 | } | 311 | } |
276 | rv = read(fd, buf, sizeof(buf)); | 312 | rv = read(fd, buf, sizeof(buf)); |
277 | assert(rv == strlen(buf0)); | 313 | assert(rv == len); |
278 | assert(memcmp(buf, buf0, strlen(buf0)) == 0); | 314 | assert(memcmp(buf, buf0, strlen(buf0)) == 0); |
315 | if (g_vsyscall) { | ||
316 | assert(memcmp(buf + strlen(buf0), str_vsyscall, strlen(str_vsyscall)) == 0); | ||
317 | } | ||
279 | } | 318 | } |
280 | 319 | ||
281 | /* Test /proc/$PID/smaps */ | 320 | /* Test /proc/$PID/smaps */ |
282 | { | 321 | { |
283 | char buf[1024]; | 322 | char buf[4096]; |
284 | ssize_t rv; | 323 | ssize_t rv; |
285 | int fd; | 324 | int fd; |
286 | 325 | ||
@@ -319,6 +358,10 @@ int main(void) | |||
319 | for (i = 0; i < sizeof(S)/sizeof(S[0]); i++) { | 358 | for (i = 0; i < sizeof(S)/sizeof(S[0]); i++) { |
320 | assert(memmem(buf, rv, S[i], strlen(S[i]))); | 359 | assert(memmem(buf, rv, S[i], strlen(S[i]))); |
321 | } | 360 | } |
361 | |||
362 | if (g_vsyscall) { | ||
363 | assert(memmem(buf, rv, str_vsyscall, strlen(str_vsyscall))); | ||
364 | } | ||
322 | } | 365 | } |
323 | 366 | ||
324 | /* Test /proc/$PID/smaps_rollup */ | 367 | /* Test /proc/$PID/smaps_rollup */ |