All of lore.kernel.org
 help / color / mirror / Atom feed
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


  parent reply	other threads:[~2021-06-11 18:04 UTC|newest]

Thread overview: 47+ 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-11 18:02   ` Dmitry Safonov
2021-06-15 10:21   ` Will Deacon
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.