um: remove copy_context_skas0

The kernel flushes the memory ranges anyway for CoW and does not assume
that the userspace process has anything set up already. So, start with a
fresh process for the new mm context.

Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Link: https://patch.msgid.link/20240703134536.1161108-8-benjamin@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Benjamin Berg 2024-07-03 15:45:31 +02:00 committed by Johannes Berg
parent 7911b650a0
commit a5d2cfe749
9 changed files with 10 additions and 229 deletions

View File

@ -285,7 +285,6 @@ void protect(struct mm_id *mm_idp, unsigned long addr,
/* skas/process.c */
extern int is_skas_winch(int pid, int fd, void *data);
extern int start_userspace(unsigned long stub_stack);
extern int copy_context_skas0(unsigned long stack, int pid);
extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs);
extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void));
extern void switch_threads(jmp_buf *me, jmp_buf *you);

View File

@ -36,7 +36,6 @@ struct stub_syscall {
struct stub_data {
unsigned long offset;
int fd;
long err, child_err;
int syscall_data_len;

View File

@ -3,16 +3,14 @@
# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
#
obj-y := clone.o stub.o mmu.o process.o syscall.o uaccess.o
obj-y := stub.o mmu.o process.o syscall.o uaccess.o
# clone.o and stub.o are in the stub, so it can't be built with profiling
# stub.o is in the stub, so it can't be built with profiling
# GCC hardened also auto-enables -fpic, but we need %ebx so it can't work ->
# disable it
CFLAGS_clone.o := $(CFLAGS_NO_HARDENING)
CFLAGS_stub.o := $(CFLAGS_NO_HARDENING)
UNPROFILE_OBJS := clone.o stub.o
UNPROFILE_OBJS := stub.o
KCOV_INSTRUMENT := n
include $(srctree)/arch/um/scripts/Makefile.rules

View File

@ -1,50 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#include <signal.h>
#include <sched.h>
#include <asm/unistd.h>
#include <sys/time.h>
#include <as-layout.h>
#include <ptrace_user.h>
#include <stub-data.h>
#include <sysdep/stub.h>
/*
* This is in a separate file because it needs to be compiled with any
* extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled
*
* Use UM_KERN_PAGE_SIZE instead of PAGE_SIZE because that calls getpagesize
* on some systems.
*/
void __attribute__ ((__section__ (".__syscall_stub")))
stub_clone_handler(void)
{
struct stub_data *data = get_stub_data();
long err;
/* syscall data as a temporary stack area (bottom half). */
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
(unsigned long) data->syscall_data +
sizeof(data->syscall_data) / 2 -
sizeof(void *));
if (err) {
data->err = err;
goto done;
}
err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0);
if (err) {
data->child_err = err;
goto done;
}
remap_stack_and_trap();
done:
trap_myself();
}

View File

@ -21,8 +21,7 @@ static_assert(sizeof(struct stub_data) == STUB_DATA_PAGES * UM_KERN_PAGE_SIZE);
int init_new_context(struct task_struct *task, struct mm_struct *mm)
{
struct mm_context *from_mm = NULL;
struct mm_context *to_mm = &mm->context;
struct mm_id *new_id = &mm->context.id;
unsigned long stack = 0;
int ret = -ENOMEM;
@ -30,27 +29,22 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
if (stack == 0)
goto out;
to_mm->id.stack = stack;
if (current->mm != NULL && current->mm != &init_mm)
from_mm = &current->mm->context;
new_id->stack = stack;
block_signals_trace();
if (from_mm)
to_mm->id.u.pid = copy_context_skas0(stack,
from_mm->id.u.pid);
else to_mm->id.u.pid = start_userspace(stack);
new_id->u.pid = start_userspace(stack);
unblock_signals_trace();
if (to_mm->id.u.pid < 0) {
ret = to_mm->id.u.pid;
if (new_id->u.pid < 0) {
ret = new_id->u.pid;
goto out_free;
}
return 0;
out_free:
if (to_mm->id.stack != 0)
free_pages(to_mm->id.stack, ilog2(STUB_DATA_PAGES));
if (new_id->stack != 0)
free_pages(new_id->stack, ilog2(STUB_DATA_PAGES));
out:
return ret;
}

View File

@ -464,114 +464,6 @@ void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs)
}
}
static unsigned long thread_regs[MAX_REG_NR];
static unsigned long thread_fp_regs[FP_SIZE];
static int __init init_thread_regs(void)
{
get_safe_registers(thread_regs, thread_fp_regs);
/* Set parent's instruction pointer to start of clone-stub */
thread_regs[REGS_IP_INDEX] = STUB_CODE +
(unsigned long) stub_clone_handler -
(unsigned long) __syscall_stub_start;
/* 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;
}
__initcall(init_thread_regs);
int copy_context_skas0(unsigned long new_stack, int pid)
{
int err;
unsigned long current_stack = current_stub_stack();
struct stub_data *data = (struct stub_data *) current_stack;
struct stub_data *child_data = (struct stub_data *) new_stack;
unsigned long long new_offset;
int new_fd = phys_mapping(uml_to_phys((void *)new_stack), &new_offset);
/*
* prepare offset and fd of child's stack as argument for parent's
* and child's mmap2 calls
*/
*data = ((struct stub_data) {
.offset = MMAP_OFFSET(new_offset),
.fd = new_fd,
.err = -ESRCH,
.child_err = 0,
});
*child_data = ((struct stub_data) {
.child_err = -ESRCH,
});
err = ptrace_setregs(pid, thread_regs);
if (err < 0) {
err = -errno;
printk(UM_KERN_ERR "%s : PTRACE_SETREGS failed, pid = %d, errno = %d\n",
__func__, pid, -err);
return err;
}
err = put_fp_registers(pid, thread_fp_regs);
if (err < 0) {
printk(UM_KERN_ERR "%s : put_fp_registers failed, pid = %d, err = %d\n",
__func__, pid, err);
return err;
}
/*
* Wait, until parent has finished its work: read child's pid from
* parent's stack, and check, if bad result.
*/
err = ptrace(PTRACE_CONT, pid, 0, 0);
if (err) {
err = -errno;
printk(UM_KERN_ERR "Failed to continue new process, pid = %d, errno = %d\n",
pid, errno);
return err;
}
wait_stub_done(pid);
pid = data->err;
if (pid < 0) {
printk(UM_KERN_ERR "%s - stub-parent reports error %d\n",
__func__, -pid);
return pid;
}
/*
* Wait, until child has finished too: read child's result from
* child's stack and check it.
*/
wait_stub_done(pid);
if (child_data->child_err != STUB_DATA) {
printk(UM_KERN_ERR "%s - stub-child %d reports error %ld\n",
__func__, pid, data->child_err);
err = data->child_err;
goto out_kill;
}
if (ptrace(PTRACE_SETOPTIONS, pid, NULL,
(void *)PTRACE_O_TRACESYSGOOD) < 0) {
err = -errno;
printk(UM_KERN_ERR "%s : PTRACE_SETOPTIONS failed, errno = %d\n",
__func__, errno);
goto out_kill;
}
return pid;
out_kill:
os_kill_ptraced_process(pid, 1);
return err;
}
void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
{
(*buf)[0].JB_IP = (unsigned long) handler;

View File

@ -13,4 +13,3 @@
extern void stub_segv_handler(int, siginfo_t *, void *);
extern void stub_syscall_handler(void);
extern void stub_clone_handler(void);

View File

@ -107,30 +107,6 @@ static __always_inline void trap_myself(void)
__asm("int3");
}
static __always_inline void remap_stack_and_trap(void)
{
__asm__ volatile (
"movl %%esp,%%ebx ;"
"andl %0,%%ebx ;"
"movl %1,%%eax ;"
"movl %%ebx,%%edi ; addl %2,%%edi ; movl (%%edi),%%edi ;"
"movl %%ebx,%%ebp ; addl %3,%%ebp ; movl (%%ebp),%%ebp ;"
"int $0x80 ;"
"addl %4,%%ebx ; movl %%eax, (%%ebx) ;"
"int $3"
: :
"g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
"g" (STUB_MMAP_NR),
"g" (offsetof(struct stub_data, fd)),
"g" (offsetof(struct stub_data, offset)),
"g" (offsetof(struct stub_data, child_err)),
"c" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
"d" (PROT_READ | PROT_WRITE),
"S" (MAP_FIXED | MAP_SHARED)
:
"memory");
}
static __always_inline void *get_stub_data(void)
{
unsigned long ret;

View File

@ -101,32 +101,6 @@ static __always_inline void trap_myself(void)
__asm("int3");
}
static __always_inline void remap_stack_and_trap(void)
{
__asm__ volatile (
"movq %0,%%rax ;"
"movq %%rsp,%%rdi ;"
"andq %1,%%rdi ;"
"movq %2,%%r10 ;"
"movq %%rdi,%%r8 ; addq %3,%%r8 ; movq (%%r8),%%r8 ;"
"movq %%rdi,%%r9 ; addq %4,%%r9 ; movq (%%r9),%%r9 ;"
__syscall ";"
"movq %%rsp,%%rdi ; andq %1,%%rdi ;"
"addq %5,%%rdi ; movq %%rax, (%%rdi) ;"
"int3"
: :
"g" (STUB_MMAP_NR),
"g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
"g" (MAP_FIXED | MAP_SHARED),
"g" (offsetof(struct stub_data, fd)),
"g" (offsetof(struct stub_data, offset)),
"g" (offsetof(struct stub_data, child_err)),
"S" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
"d" (PROT_READ | PROT_WRITE)
:
__syscall_clobber, "r10", "r8", "r9");
}
static __always_inline void *get_stub_data(void)
{
unsigned long ret;