FAILED: patch "[PATCH] um: defer killing userspace on page table update failures" failed to apply to 4.9-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From a7d48886cacf8b426e0079bca9639d2657cf2d38 Mon Sep 17 00:00:00 2001
From: Johannes Berg <[email protected]>
Date: Wed, 13 Jan 2021 22:08:03 +0100
Subject: [PATCH] um: defer killing userspace on page table update failures
In some cases we can get to fix_range_common() with mmap_sem held, and in others we get there without it being held. For example, we get there with it held from sys_mprotect(), and without it held from fork_handler().
Avoid any issues in this and simply defer killing the task until it runs the next time. Do it on the mm so that another task that shares the same mm can't continue running afterwards.
arch/um/include/shared/skas/mm_id.h +1 -0
@@ -12,6 +12,7 @@ struct mm_id { int pid; } u;unsigned long stack; +int kill; };#endif
arch/um/kernel/tlb.c +3 -4
@@ -352,12 +352,11 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,/* This is not an else because ret is modified above */ if (ret) { +struct mm_id *mm_idp = ¤t->mm->context.id; +printk (KERN_ERR "fix_range_common: failed, killing current " "process: %d\n" ,task_tgid_vnr (current)); -/* We are under mmap_lock, release it such that current can terminate */ -mmap_write_unlock (current->mm); -force_sig (SIGKILL ); -do_signal (¤t->thread.regs); + mm_idp->kill =1 ; } }
arch/um/os-Linux/skas/process.c +4 -0
@@ -300,6 +300,7 @@ static int userspace_tramp(void *stack) }int userspace_pid[NR_CPUS ]; +int kill_userspace_mm[NR_CPUS ];/** * start_userspace() - prepare a new userspace process
@@ -393,6 +394,8 @@ void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs)interrupt_end ();while (1 ) { +if (kill_userspace_mm[0 ]) +fatal_sigsegv ();/* * This can legitimately fail if the process loads a
@@ -714,4 +717,5 @@ void reboot_skas(void)void __switch_mm (struct mm_id *mm_idp) { userspace_pid[0 ] = mm_idp->u.pid; + kill_userspace_mm[0 ] = mm_idp->kill; }