Skip to content

Commit

Permalink
um: defer killing userspace on page table update failures
Browse files Browse the repository at this point in the history
commit a7d4888 upstream.

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.

Cc: stable@vger.kernel.org
Fixes: 468f659 ("um: Fix hung task in fix_range_common()")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
jmberg-intel authored and gregkh committed Mar 4, 2021
1 parent 010b985 commit e7c4894
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 4 deletions.
1 change: 1 addition & 0 deletions arch/um/include/shared/skas/mm_id.h
Expand Up @@ -12,6 +12,7 @@ struct mm_id {
int pid;
} u;
unsigned long stack;
int kill;
};

#endif
7 changes: 3 additions & 4 deletions arch/um/kernel/tlb.c
Expand Up @@ -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 = &current->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(&current->thread.regs);
mm_idp->kill = 1;
}
}

Expand Down
4 changes: 4 additions & 0 deletions arch/um/os-Linux/skas/process.c
Expand Up @@ -249,6 +249,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
Expand Down Expand Up @@ -342,6 +343,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
Expand Down Expand Up @@ -663,4 +666,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;
}

0 comments on commit e7c4894

Please sign in to comment.