From: Dmitry Safonov <dima@arista.com>
To: linux-kernel@vger.kernel.org
Cc: Dmitry Safonov <0x7f454c46@gmail.com>,
Dmitry Safonov <dima@arista.com>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Andrew Morton <akpm@linux-foundation.org>,
Andy Lutomirski <luto@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
Borislav Petkov <bp@alien8.de>,
Catalin Marinas <catalin.marinas@arm.com>,
Christophe Leroy <christophe.leroy@csgroup.eu>,
Guo Ren <guoren@kernel.org>, "H. Peter Anvin" <hpa@zytor.com>,
Ingo Molnar <mingo@redhat.com>, Oleg Nesterov <oleg@redhat.com>,
Russell King <linux@armlinux.org.uk>,
Thomas Bogendoerfer <tsbogend@alpha.franken.de>,
Thomas Gleixner <tglx@linutronix.de>,
Vincenzo Frascino <vincenzo.frascino@arm.com>,
Will Deacon <will@kernel.org>,
x86@kernel.org, Shuah Khan <shuah@kernel.org>
Subject: [PATCH v3 23/23] x86/vdso/selftest: Add a test for unmapping vDSO
Date: Fri, 11 Jun 2021 19:02:42 +0100 [thread overview]
Message-ID: <20210611180242.711399-24-dima@arista.com> (raw)
In-Reply-To: <20210611180242.711399-1-dima@arista.com>
Output for landing on x86:
> [root@localhost ~]# ./test_munmap_vdso_64
> AT_SYSINFO_EHDR is 0x7fffead9f000
> [NOTE] unmapping vDSO: [0x7fffead9f000, 0x7fffeada0000]
> [NOTE] vDSO partial move failed, will try with bigger size
> [NOTE] unmapping vDSO: [0x7fffead9f000, 0x7fffeada1000]
> [OK]
> [root@localhost ~]# ./test_munmap_vdso_32
> AT_SYSINFO_EHDR is 0xf7eef000
> [NOTE] unmapping vDSO: [0xf7eef000, 0xf7ef0000]
> [NOTE] vDSO partial move failed, will try with bigger size
> [NOTE] unmapping vDSO: [0xf7eef000, 0xf7ef1000]
> [OK]
The test also can check force_sigsegv(SIGSEGV) in do_fast_syscall_32():
> [root@localhost ~]# ./test_munmap_vdso_32 sysenter
> [NOTE] Using sysenter after munmap
> AT_SYSINFO_EHDR is 0xf7efe000
> [NOTE] unmapping vDSO: [0xf7efe000, 0xf7eff000]
> [NOTE] vDSO partial move failed, will try with bigger size
> [NOTE] unmapping vDSO: [0xf7efe000, 0xf7f00000]
> [OK] 32-bit process gets segfault on fast syscall with unmapped vDSO
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Dmitry Safonov <dima@arista.com>
---
tools/testing/selftests/x86/.gitignore | 1 +
tools/testing/selftests/x86/Makefile | 11 +-
.../testing/selftests/x86/test_munmap_vdso.c | 151 ++++++++++++++++++
3 files changed, 158 insertions(+), 5 deletions(-)
create mode 100644 tools/testing/selftests/x86/test_munmap_vdso.c
diff --git a/tools/testing/selftests/x86/.gitignore b/tools/testing/selftests/x86/.gitignore
index 1aaef5bf119a..9ce8337e8fa0 100644
--- a/tools/testing/selftests/x86/.gitignore
+++ b/tools/testing/selftests/x86/.gitignore
@@ -6,6 +6,7 @@ sysret_ss_attrs
syscall_nt
ptrace_syscall
test_mremap_vdso
+test_munmap_vdso
check_initial_reg_state
sigreturn
ldt_gdt
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index 333980375bc7..43016351ddb3 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -10,12 +10,13 @@ CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32)
CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c)
CAN_BUILD_WITH_NOPIE := $(shell ./check_cc.sh $(CC) trivial_program.c -no-pie)
-TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \
- check_initial_reg_state sigreturn iopl ioperm \
- test_vsyscall mov_ss_trap \
+TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt \
+ test_mremap_vdso test_munmap_vdso \
+ check_initial_reg_state sigreturn iopl ioperm \
+ test_vsyscall mov_ss_trap \
syscall_arg_fault fsgsbase_restore
-TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \
- test_FCMOV test_FCOMI test_FISTTP \
+TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \
+ test_FCMOV test_FCOMI test_FISTTP \
vdso_restorer
TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip syscall_numbering
# Some selftests require 32bit support enabled also on 64bit systems
diff --git a/tools/testing/selftests/x86/test_munmap_vdso.c b/tools/testing/selftests/x86/test_munmap_vdso.c
new file mode 100644
index 000000000000..f56433dae279
--- /dev/null
+++ b/tools/testing/selftests/x86/test_munmap_vdso.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * 32/64-bit test to check vDSO munmap.
+ *
+ * Copyright (c) 2021 Dmitry Safonov
+ */
+/*
+ * Can be built statically:
+ * gcc -Os -Wall -static -m32 test_munmap_vdso.c
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/mman.h>
+#include <sys/auxv.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+
+#define PAGE_SIZE 4096
+
+static int try_to_unmap(void *vdso_addr, unsigned long size)
+{
+ int ret;
+
+ printf("[NOTE]\tunmapping vDSO: [%p, %#lx]\n",
+ vdso_addr, (unsigned long)vdso_addr + size);
+ fflush(stdout);
+
+#ifdef __i386__
+ /* vDSO is a landing for fast syscalls - don't use it for munmap() */
+ asm volatile ("int $0x80" : "=a" (ret)
+ : "a" (SYS_munmap),
+ "b" (vdso_addr),
+ "c" (size));
+ errno = -ret;
+#else /* __x86_64__ */
+ ret = munmap(vdso_addr, size);
+#endif
+ if (ret) {
+ if (errno == EINVAL) {
+ printf("[NOTE]\tvDSO partial move failed, will try with bigger size\n");
+ return -1; /* Retry with larger */
+ }
+ printf("[FAIL]\tmunmap failed (%d): %m\n", errno);
+ return 1;
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv, char **envp)
+{
+ pid_t child;
+
+#ifdef __i386__
+ enum syscall_type_t {
+ INT80, SYSCALL32, SYSENTER
+ } syscall_type = INT80;
+
+ if (argc > 1) {
+ if (!strcmp(argv[1], "syscall32")) {
+ syscall_type = SYSCALL32;
+ printf("[NOTE]\tUsing syscall32 after munmap\n");
+ } else if (!strcmp(argv[1], "sysenter")) {
+ syscall_type = SYSENTER;
+ printf("[NOTE]\tUsing sysenter after munmap\n");
+ }
+ }
+#endif
+
+ child = fork();
+ if (child == -1) {
+ printf("[WARN]\tfailed to fork (%d): %m\n", errno);
+ return 1;
+ }
+
+ if (child == 0) {
+ unsigned long vdso_size = PAGE_SIZE;
+ unsigned long auxval;
+ int ret = -1;
+
+ auxval = getauxval(AT_SYSINFO_EHDR);
+ printf("\tAT_SYSINFO_EHDR is %#lx\n", auxval);
+ if (!auxval || auxval == -ENOENT) {
+ printf("[WARN]\tgetauxval failed\n");
+ return 0;
+ }
+
+ /* Simpler than parsing ELF header */
+ while (ret < 0) {
+ ret = try_to_unmap((void *)auxval, vdso_size);
+ vdso_size += PAGE_SIZE;
+ }
+
+ /* Glibc is likely to explode now - exit with raw syscall */
+#ifdef __i386__
+ switch (syscall_type) {
+ case SYSCALL32:
+ asm volatile ("syscall" : : "a" (__NR_exit), "b" (!!ret));
+ case SYSENTER:
+ asm volatile ("sysenter" : : "a" (__NR_exit), "b" (!!ret));
+ default:
+ case INT80:
+ asm volatile ("int $0x80" : : "a" (__NR_exit), "b" (!!ret));
+ }
+#else /* __x86_64__ */
+ syscall(SYS_exit, ret);
+#endif
+ } else {
+ int status;
+
+ if (waitpid(child, &status, 0) != child) {
+ printf("[FAIL]\tUnexpected child, killing the expected one\n");
+ kill(child, SIGKILL);
+ return 1;
+ }
+
+
+#ifdef __i386__
+ switch (syscall_type) {
+ case SYSCALL32:
+ case SYSENTER:
+ if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV) {
+ printf("[OK]\t32-bit process gets segfault on fast syscall with unmapped vDSO\n");
+ return 0;
+ }
+ default:
+ case INT80:
+ /* same as on x86_64 */
+ }
+#endif
+
+ if (!WIFEXITED(status)) {
+ printf("[FAIL]\tmunmap() of the vDSO does not work on this kernel!\n");
+ if (WIFSIGNALED(status))
+ printf("[FAIL]\tprocess crashed with %s\n",
+ strsignal(WTERMSIG(status)));
+ return 1;
+ } else if (WEXITSTATUS(status) != 0) {
+ printf("[FAIL]\tChild failed with %d\n",
+ WEXITSTATUS(status));
+ return 1;
+ }
+ printf("[OK]\n");
+ }
+
+ return 0;
+}
--
2.31.1
next prev parent reply other threads:[~2021-06-11 18:04 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-11 18:02 [PATCH v3 00/23] Add generic vdso_base tracking Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 01/23] x86/elf: Check in_x32_syscall() in compat_arch_setup_additional_pages() Dmitry Safonov
2021-06-19 20:41 ` Thomas Gleixner
2021-06-21 20:59 ` Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 02/23] elf: Move arch_setup_additional_pages() to generic elf.h Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 03/23] arm/elf: Remove needless ifdef CONFIG_MMU Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 04/23] arm64: Use in_compat_task() in arch_setup_additional_pages() Dmitry Safonov
2021-06-15 10:21 ` Will Deacon
2021-06-11 18:02 ` [PATCH v3 05/23] x86: Remove compat_arch_setup_additional_pages() Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 06/23] elf: " Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 07/23] vdso: Set mm->context.vdso only on success of _install_special_mapping() Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 08/23] elf/vdso: Modify arch_setup_additional_pages() parameters Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 09/23] elf: Use sysinfo_ehdr in ARCH_DLINFO() Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 10/23] arm/vdso: Remove vdso pointer from mm->context Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 11/23] s390/vdso: Remove vdso_base " Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 12/23] sparc/vdso: Remove vdso " Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 13/23] mm/mmap: Make vm_special_mapping::mremap return void Dmitry Safonov
2021-06-17 7:20 ` Christophe Leroy
2021-06-21 21:12 ` Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 14/23] x86/signal: Land on &frame->retcode when vdso isn't mapped Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 15/23] x86/signal: Check if vdso_image_32 is mapped before trying to land on it Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 16/23] mm: Add vdso_base in mm_struct Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 17/23] x86/vdso: Migrate to generic vdso_base Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 18/23] arm/vdso: " Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 19/23] arm64/vdso: Migrate compat signals " Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 20/23] arm64/vdso: Migrate native " Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 21/23] mips/vdso: Migrate " Dmitry Safonov
2021-06-11 18:02 ` [PATCH v3 22/23] powerpc/vdso: Migrate native signals " Dmitry Safonov
2021-06-15 12:52 ` Michael Ellerman
2021-06-17 6:30 ` Christophe Leroy
2021-06-17 6:36 ` Christophe Leroy
2021-06-17 7:34 ` Christophe Leroy
2021-06-21 21:22 ` Dmitry Safonov
2021-06-11 18:02 ` Dmitry Safonov [this message]
2021-06-11 18:21 ` [PATCH v3 23/23] x86/vdso/selftest: Add a test for unmapping vDSO Shuah Khan
2021-06-11 18:37 ` Dmitry Safonov
2021-06-11 18:43 ` Shuah Khan
2021-06-17 9:13 ` [PATCH v3 00/23] Add generic vdso_base tracking Christophe Leroy
2021-06-21 21:57 ` Dmitry Safonov
2022-03-09 15:41 ` Christophe Leroy
2022-03-10 21:17 ` Dmitry Safonov
2022-08-19 9:17 ` Christophe Leroy
2022-08-23 19:13 ` Dmitry Safonov
2023-10-11 10:28 ` Christophe Leroy
2023-10-11 23:20 ` H. Peter Anvin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210611180242.711399-24-dima@arista.com \
--to=dima@arista.com \
--cc=0x7f454c46@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=arnd@arndb.de \
--cc=bp@alien8.de \
--cc=catalin.marinas@arm.com \
--cc=christophe.leroy@csgroup.eu \
--cc=guoren@kernel.org \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=oleg@redhat.com \
--cc=shuah@kernel.org \
--cc=tglx@linutronix.de \
--cc=tsbogend@alpha.franken.de \
--cc=vincenzo.frascino@arm.com \
--cc=viro@zeniv.linux.org.uk \
--cc=will@kernel.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).