All of lore.kernel.org
 help / color / mirror / Atom feed
From: benjamin@sipsolutions.net
To: linux-um@lists.infradead.org
Cc: Benjamin Berg <benjamin@sipsolutions.net>
Subject: [PATCH v2 15/28] um: Create signal stack memory assignment in stub_data
Date: Tue, 22 Nov 2022 11:07:46 +0100	[thread overview]
Message-ID: <20221122100759.208290-16-benjamin@sipsolutions.net> (raw)
In-Reply-To: <20221122100759.208290-1-benjamin@sipsolutions.net>

From: Benjamin Berg <benjamin@sipsolutions.net>

When we switch to use seccomp, we need both the signal stack and other
data (i.e. syscall information) to co-exist in the stub data. To
facilitate this, start by defining separate memory areas for the stack
and syscall data.

This moves the signal stack onto a new page as the memory area is not
sufficient to hold both signal stack and syscall information.

Only change the signal stack setup for now, as the syscall code will be
reworked later.

Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net>
---
 arch/um/include/shared/as-layout.h      |  2 +-
 arch/um/include/shared/skas/stub-data.h | 12 ++++++++++++
 arch/um/kernel/skas/clone.c             |  7 +++++--
 arch/um/kernel/skas/mmu.c               |  6 +++---
 arch/um/os-Linux/skas/process.c         | 17 ++++++++++-------
 arch/x86/um/shared/sysdep/stub_32.h     |  3 ++-
 arch/x86/um/shared/sysdep/stub_64.h     |  5 +++--
 7 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h
index 9a0bd648d872..70d3df8ae814 100644
--- a/arch/um/include/shared/as-layout.h
+++ b/arch/um/include/shared/as-layout.h
@@ -23,7 +23,7 @@
 #define STUB_START stub_start
 #define STUB_CODE STUB_START
 #define STUB_DATA (STUB_CODE + UM_KERN_PAGE_SIZE)
-#define STUB_END (STUB_DATA + UM_KERN_PAGE_SIZE)
+#define STUB_END (STUB_DATA + 2*UM_KERN_PAGE_SIZE)
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/um/include/shared/skas/stub-data.h b/arch/um/include/shared/skas/stub-data.h
index 5e3ade3fb38b..3281809a7272 100644
--- a/arch/um/include/shared/skas/stub-data.h
+++ b/arch/um/include/shared/skas/stub-data.h
@@ -8,10 +8,22 @@
 #ifndef __STUB_DATA_H
 #define __STUB_DATA_H
 
+#include <linux/compiler_types.h>
+#include <as-layout.h>
+
 struct stub_data {
 	unsigned long offset;
 	int fd;
 	long parent_err, child_err;
+
+	/* 128 leaves enough room for additional fields in the struct */
+	unsigned char syscall_data[UM_KERN_PAGE_SIZE - 128] __aligned(16);
+
+	/* Stack for our signal handlers and for calling into . */
+	unsigned char sigstack[UM_KERN_PAGE_SIZE] __aligned(UM_KERN_PAGE_SIZE);
 };
 
+typedef char stub_data_sizecheck
+	[sizeof(struct stub_data) == 2*UM_KERN_PAGE_SIZE ? 1 : -1] __always_unused;
+
 #endif
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
index ff5061f29167..a631566e4a20 100644
--- a/arch/um/kernel/skas/clone.c
+++ b/arch/um/kernel/skas/clone.c
@@ -24,11 +24,14 @@
 void __attribute__ ((__section__ (".__syscall_stub")))
 stub_clone_handler(void)
 {
-	struct stub_data *data = get_stub_page();
+	struct stub_data *data = get_stub_page() + UM_KERN_PAGE_SIZE;
 	long err;
 
+	/* syscall data as a temporary stack area (bottom half). */
 	err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
-			    (unsigned long)data + UM_KERN_PAGE_SIZE / 2);
+			    (unsigned long) data->syscall_data +
+					    sizeof(data->syscall_data) / 2 -
+					    sizeof(void *));
 	if (err) {
 		data->parent_err = err;
 		goto done;
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 125df465e8ea..6ccb561b4373 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -21,7 +21,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
 	unsigned long stack = 0;
 	int ret = -ENOMEM;
 
-	stack = get_zeroed_page(GFP_KERNEL);
+	stack = __get_free_pages(GFP_KERNEL|__GFP_ZERO, 1);
 	if (stack == 0)
 		goto out;
 
@@ -52,7 +52,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
 
  out_free:
 	if (to_mm->id.stack != 0)
-		free_page(to_mm->id.stack);
+		free_pages(to_mm->id.stack, 1);
  out:
 	return ret;
 }
@@ -74,6 +74,6 @@ void destroy_context(struct mm_struct *mm)
 	}
 	os_kill_ptraced_process(mmu->id.u.pid, 1);
 
-	free_page(mmu->id.stack);
+	free_pages(mmu->id.stack, 1);
 	free_ldt(mmu);
 }
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 4198ca21e4ab..3917bd862315 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -205,6 +205,7 @@ extern char __syscall_stub_start[];
 static int userspace_tramp(void *stack)
 {
 	struct sigaction sa;
+	struct stub_data *data;
 	void *addr;
 	int fd;
 	unsigned long long offset;
@@ -228,15 +229,16 @@ static int userspace_tramp(void *stack)
 
 	fd = phys_mapping(uml_to_phys(stack), &offset);
 	addr = mmap((void *) STUB_DATA,
-		    UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
+		    sizeof(struct stub_data), PROT_READ | PROT_WRITE,
 		    MAP_FIXED | MAP_SHARED, fd, offset);
 	if (addr == MAP_FAILED) {
 		os_info("mapping segfault stack at 0x%lx failed, errno = %d\n",
 			STUB_DATA, errno);
 		exit(1);
 	}
+	data = (void *) addr;
 
-	set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
+	set_sigstack((void *) &data->sigstack, sizeof(data->sigstack));
 	sigemptyset(&sa.sa_mask);
 	sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO;
 	sa.sa_sigaction = (void *) segv_handler;
@@ -470,11 +472,12 @@ static int __init init_thread_regs(void)
 	thread_regs[REGS_IP_INDEX] = STUB_CODE +
 				(unsigned long) stub_clone_handler -
 				(unsigned long) __syscall_stub_start;
-	thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE -
-		sizeof(void *);
-#ifdef __SIGNAL_FRAMESIZE
-	thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
-#endif
+
+	/* syscall data as a temporary stack area (top half). */
+	thread_regs[REGS_SP_INDEX] = STUB_DATA +
+				     offsetof(struct stub_data, syscall_data) +
+				     sizeof(((struct stub_data *) 0)->syscall_data) -
+				     sizeof(void *);
 	return 0;
 }
 
diff --git a/arch/x86/um/shared/sysdep/stub_32.h b/arch/x86/um/shared/sysdep/stub_32.h
index c413927c6ad0..85a224506530 100644
--- a/arch/x86/um/shared/sysdep/stub_32.h
+++ b/arch/x86/um/shared/sysdep/stub_32.h
@@ -87,6 +87,7 @@ static __always_inline void trap_myself(void)
 
 static __always_inline void remap_stack_and_trap(void)
 {
+	/* The stack here is in syscall data (i.e. on the first page) */
 	__asm__ volatile (
 		"movl %%esp,%%ebx ;"
 		"andl %0,%%ebx ;"
@@ -102,7 +103,7 @@ static __always_inline void remap_stack_and_trap(void)
 		"g" (offsetof(struct stub_data, fd)),
 		"g" (offsetof(struct stub_data, offset)),
 		"g" (offsetof(struct stub_data, child_err)),
-		"c" (UM_KERN_PAGE_SIZE),
+		"c" (2*UM_KERN_PAGE_SIZE),
 		"d" (PROT_READ | PROT_WRITE),
 		"S" (MAP_FIXED | MAP_SHARED)
 		:
diff --git a/arch/x86/um/shared/sysdep/stub_64.h b/arch/x86/um/shared/sysdep/stub_64.h
index 361a6a9fe1e4..2e7acba74dc3 100644
--- a/arch/x86/um/shared/sysdep/stub_64.h
+++ b/arch/x86/um/shared/sysdep/stub_64.h
@@ -87,6 +87,7 @@ static __always_inline void trap_myself(void)
 
 static __always_inline void remap_stack_and_trap(void)
 {
+	/* The stack here is in syscall data (i.e. on the first page) */
 	__asm__ volatile (
 		"movq %0,%%rax ;"
 		"movq %%rsp,%%rdi ;"
@@ -105,7 +106,7 @@ static __always_inline void remap_stack_and_trap(void)
 		"g" (offsetof(struct stub_data, fd)),
 		"g" (offsetof(struct stub_data, offset)),
 		"g" (offsetof(struct stub_data, child_err)),
-		"S" (UM_KERN_PAGE_SIZE),
+		"S" (2*UM_KERN_PAGE_SIZE),
 		"d" (PROT_READ | PROT_WRITE)
 		:
 		__syscall_clobber, "r10", "r8", "r9");
@@ -121,6 +122,6 @@ static __always_inline void *get_stub_page(void)
 		: "=a" (ret)
 		: "g" (~(UM_KERN_PAGE_SIZE - 1)));
 
-	return (void *)ret;
+	return (void *)ret - UM_KERN_PAGE_SIZE;
 }
 #endif
-- 
2.38.1


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um

  parent reply	other threads:[~2022-11-22 10:26 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-22 10:07 [PATCH v2 00/28] Implement SECCOMP based userland benjamin
2022-11-22 10:07 ` [PATCH v2 01/28] um: Switch printk calls to adhere to correct coding style benjamin
2022-11-22 10:07 ` [PATCH v2 02/28] um: Declare fix_range_common as a static function benjamin
2022-11-22 10:07 ` [PATCH v2 03/28] um: Drop support for hosts without SYSEMU_SINGLESTEP support benjamin
2022-11-22 10:07 ` [PATCH v2 04/28] um: Drop NULL check from start_userspace benjamin
2022-11-22 10:07 ` [PATCH v2 05/28] um: Make errors to stop ptraced child fatal during startup benjamin
2022-11-22 10:07 ` [PATCH v2 06/28] um: Don't use vfprintf() for os_info() benjamin
2022-11-22 10:07 ` [PATCH v2 07/28] um: Do not use printk in SIGWINCH helper thread benjamin
2022-11-22 10:07 ` [PATCH v2 08/28] um: Reap winch thread if it fails benjamin
2022-11-22 10:07 ` [PATCH v2 09/28] um: Do not use printk in userspace trampoline benjamin
2022-11-22 10:07 ` [PATCH v2 10/28] um: Always inline stub functions benjamin
2022-11-22 10:07 ` [PATCH v2 11/28] um: Rely on PTRACE_SETREGSET to set FS/GS base registers benjamin
2022-11-22 10:07 ` [PATCH v2 12/28] um: Remove unused register save/restore functions benjamin
2022-11-22 10:07 ` [PATCH v2 13/28] um: Mark 32bit syscall helpers as clobbering memory benjamin
2022-11-22 10:07 ` [PATCH v2 14/28] um: Remove stub-data.h include from common-offsets.h benjamin
2022-11-22 10:07 ` benjamin [this message]
2022-11-22 10:07 ` [PATCH v2 16/28] um: Add generic stub_syscall6 function benjamin
2022-11-22 10:07 ` [PATCH v2 17/28] um: Rework syscall handling benjamin
2022-11-22 10:07 ` [PATCH v2 18/28] um: Store full CSGSFS and SS register from mcontext benjamin
2022-11-22 10:07 ` [PATCH v2 19/28] um: Pass full mm_id to functions creating helper processes benjamin
2022-11-22 10:07 ` [PATCH v2 20/28] um: Move faultinfo extraction into userspace routine benjamin
2022-11-22 10:07 ` [PATCH v2 21/28] um: Use struct uml_pt_regs for copy_context_skas0 benjamin
2022-11-22 10:07 ` [PATCH v2 22/28] um: Add UML_SECCOMP configuration option benjamin
2022-11-22 10:07 ` [PATCH v2 23/28] um: Add stub side of SECCOMP/futex based process handling benjamin
2022-11-22 10:07 ` [PATCH v2 24/28] um: Add helper functions to get/set state for SECCOMP benjamin
2022-11-22 10:07 ` [PATCH v2 25/28] um: Add SECCOMP support detection and initialization benjamin
2022-11-22 10:07 ` [PATCH v2 26/28] um: Die if a child dies unexpectedly in seccomp mode benjamin
2022-11-22 10:07 ` [PATCH v2 27/28] um: Implement kernel side of SECCOMP based process handling benjamin
2022-11-22 10:07 ` [PATCH v2 28/28] um: Delay flushing syscalls until the thread is restarted benjamin

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=20221122100759.208290-16-benjamin@sipsolutions.net \
    --to=benjamin@sipsolutions.net \
    --cc=linux-um@lists.infradead.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.