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>
This commit is contained in:
parent
ce82f19fd5
commit
17415606f9
|
@ -29,6 +29,7 @@
|
|||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -36,11 +37,14 @@
|
|||
#include <sys/mount.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
static inline long sys_execveat(int dirfd, const char *pathname, char **argv, char **envp, int flags)
|
||||
{
|
||||
|
@ -205,12 +209,44 @@ static int make_exe(const uint8_t *payload, size_t len)
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool g_vsyscall = false;
|
||||
|
||||
static const char str_vsyscall[] =
|
||||
"ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n";
|
||||
|
||||
#ifdef __x86_64__
|
||||
/*
|
||||
* vsyscall page can't be unmapped, probe it with memory load.
|
||||
*/
|
||||
static void vsyscall(void)
|
||||
{
|
||||
pid_t pid;
|
||||
int wstatus;
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
fprintf(stderr, "fork, errno %d\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
if (pid == 0) {
|
||||
struct rlimit rlim = {0, 0};
|
||||
(void)setrlimit(RLIMIT_CORE, &rlim);
|
||||
*(volatile int *)0xffffffffff600000UL;
|
||||
exit(0);
|
||||
}
|
||||
wait(&wstatus);
|
||||
if (WIFEXITED(wstatus)) {
|
||||
g_vsyscall = true;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int pipefd[2];
|
||||
int exec_fd;
|
||||
|
||||
vsyscall();
|
||||
|
||||
atexit(ate);
|
||||
|
||||
make_private_tmp();
|
||||
|
@ -261,9 +297,9 @@ int main(void)
|
|||
snprintf(buf0 + MAPS_OFFSET, sizeof(buf0) - MAPS_OFFSET,
|
||||
"/tmp/#%llu (deleted)\n", (unsigned long long)st.st_ino);
|
||||
|
||||
|
||||
/* Test /proc/$PID/maps */
|
||||
{
|
||||
const size_t len = strlen(buf0) + (g_vsyscall ? strlen(str_vsyscall) : 0);
|
||||
char buf[256];
|
||||
ssize_t rv;
|
||||
int fd;
|
||||
|
@ -274,13 +310,16 @@ int main(void)
|
|||
return 1;
|
||||
}
|
||||
rv = read(fd, buf, sizeof(buf));
|
||||
assert(rv == strlen(buf0));
|
||||
assert(rv == len);
|
||||
assert(memcmp(buf, buf0, strlen(buf0)) == 0);
|
||||
if (g_vsyscall) {
|
||||
assert(memcmp(buf + strlen(buf0), str_vsyscall, strlen(str_vsyscall)) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test /proc/$PID/smaps */
|
||||
{
|
||||
char buf[1024];
|
||||
char buf[4096];
|
||||
ssize_t rv;
|
||||
int fd;
|
||||
|
||||
|
@ -319,6 +358,10 @@ int main(void)
|
|||
for (i = 0; i < sizeof(S)/sizeof(S[0]); i++) {
|
||||
assert(memmem(buf, rv, S[i], strlen(S[i])));
|
||||
}
|
||||
|
||||
if (g_vsyscall) {
|
||||
assert(memmem(buf, rv, str_vsyscall, strlen(str_vsyscall)));
|
||||
}
|
||||
}
|
||||
|
||||
/* Test /proc/$PID/smaps_rollup */
|
||||
|
|
Loading…
Reference in New Issue