proc: test ProtectionKey in proc-empty-vm test
Check ProtectionKey field in /proc/*/smaps output, if system supports protection keys feature. [adobriyan@gmail.com: test support in the beginning of the program, use syscall, not glibc pkey_alloc(3) which may not compile] Link: https://lkml.kernel.org/r/ac05efa7-d2a0-48ad-b704-ffdd5450582e@p183 Signed-off-by: Swarup Laxman Kotiaklapudi <swarupkotikalapudi@gmail.com> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Reviewed-by: Swarup Laxman Kotikalapudi<swarupkotikalapudi@gmail.com> Tested-by: Swarup Laxman Kotikalapudi<swarupkotikalapudi@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
20e34aa7e0
commit
bf5add391e
@ -23,6 +23,9 @@
|
||||
* /proc/${pid}/smaps
|
||||
* /proc/${pid}/smaps_rollup
|
||||
*/
|
||||
#undef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
@ -34,6 +37,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
@ -42,6 +46,43 @@
|
||||
#define TEST_VSYSCALL
|
||||
#endif
|
||||
|
||||
#if defined __amd64__
|
||||
#ifndef SYS_pkey_alloc
|
||||
#define SYS_pkey_alloc 330
|
||||
#endif
|
||||
#ifndef SYS_pkey_free
|
||||
#define SYS_pkey_free 331
|
||||
#endif
|
||||
#elif defined __i386__
|
||||
#ifndef SYS_pkey_alloc
|
||||
#define SYS_pkey_alloc 381
|
||||
#endif
|
||||
#ifndef SYS_pkey_free
|
||||
#define SYS_pkey_free 382
|
||||
#endif
|
||||
#else
|
||||
#error "SYS_pkey_alloc"
|
||||
#endif
|
||||
|
||||
static int g_protection_key_support;
|
||||
|
||||
static int protection_key_support(void)
|
||||
{
|
||||
long rv = syscall(SYS_pkey_alloc, 0, 0);
|
||||
if (rv > 0) {
|
||||
syscall(SYS_pkey_free, (int)rv);
|
||||
return 1;
|
||||
} else if (rv == -1 && errno == ENOSYS) {
|
||||
return 0;
|
||||
} else if (rv == -1 && errno == EINVAL) {
|
||||
// ospke=n
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "%s: error: rv %ld, errno %d\n", __func__, rv, errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 0: vsyscall VMA doesn't exist vsyscall=none
|
||||
* 1: vsyscall VMA is --xp vsyscall=xonly
|
||||
@ -84,10 +125,6 @@ static const char proc_pid_smaps_vsyscall_1[] =
|
||||
"SwapPss: 0 kB\n"
|
||||
"Locked: 0 kB\n"
|
||||
"THPeligible: 0\n"
|
||||
/*
|
||||
* "ProtectionKey:" field is conditional. It is possible to check it as well,
|
||||
* but I don't have such machine.
|
||||
*/
|
||||
;
|
||||
|
||||
static const char proc_pid_smaps_vsyscall_2[] =
|
||||
@ -115,10 +152,6 @@ static const char proc_pid_smaps_vsyscall_2[] =
|
||||
"SwapPss: 0 kB\n"
|
||||
"Locked: 0 kB\n"
|
||||
"THPeligible: 0\n"
|
||||
/*
|
||||
* "ProtectionKey:" field is conditional. It is possible to check it as well,
|
||||
* but I'm too tired.
|
||||
*/
|
||||
;
|
||||
|
||||
static void sigaction_SIGSEGV(int _, siginfo_t *__, void *___)
|
||||
@ -240,19 +273,27 @@ static int test_proc_pid_smaps(pid_t pid)
|
||||
}
|
||||
perror("open /proc/${pid}/smaps");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
ssize_t rv = read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
if (g_vsyscall == 0) {
|
||||
assert(rv == 0);
|
||||
} else {
|
||||
size_t len = strlen(g_proc_pid_smaps_vsyscall);
|
||||
/* TODO "ProtectionKey:" */
|
||||
assert(rv > len);
|
||||
assert(memcmp(buf, g_proc_pid_smaps_vsyscall, len) == 0);
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
ssize_t rv = read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
|
||||
assert(0 <= rv);
|
||||
assert(rv <= sizeof(buf));
|
||||
|
||||
if (g_vsyscall == 0) {
|
||||
assert(rv == 0);
|
||||
} else {
|
||||
size_t len = strlen(g_proc_pid_smaps_vsyscall);
|
||||
assert(rv > len);
|
||||
assert(memcmp(buf, g_proc_pid_smaps_vsyscall, len) == 0);
|
||||
|
||||
if (g_protection_key_support) {
|
||||
#define PROTECTION_KEY "ProtectionKey: 0\n"
|
||||
assert(memmem(buf, rv, PROTECTION_KEY, strlen(PROTECTION_KEY)));
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static const char g_smaps_rollup[] =
|
||||
@ -419,6 +460,8 @@ int main(void)
|
||||
abort();
|
||||
}
|
||||
|
||||
g_protection_key_support = protection_key_support();
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
perror("fork");
|
||||
|
Loading…
Reference in New Issue
Block a user