Skip to content

Commit

Permalink
um: Remove SKAS3/4 support
Browse files Browse the repository at this point in the history
Before we had SKAS0 UML had two modes of operation
TT (tracing thread) and SKAS3/4 (separated kernel address space).
TT was known to be insecure and got removed a long time ago.
SKAS3/4 required a few (3 or 4) patches on the host side which never went
mainline. The last host patch is 10 years old.

With SKAS0 mode (separated kernel address space using 0 host patches),
default since 2005, SKAS3/4 is obsolete and can be removed.

Signed-off-by: Richard Weinberger <richard@nod.at>
  • Loading branch information
Richard Weinberger committed Apr 13, 2015
1 parent aaeac66 commit d0b5e15
Show file tree
Hide file tree
Showing 18 changed files with 148 additions and 814 deletions.
2 changes: 0 additions & 2 deletions arch/um/include/shared/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ extern unsigned long long os_makedev(unsigned major, unsigned minor);

/* start_up.c */
extern void os_early_checks(void);
extern void can_do_skas(void);
extern void os_check_bugs(void);
extern void check_host_supports_tls(int *supports_tls, int *tls_min);

Expand All @@ -187,7 +186,6 @@ extern int os_process_parent(int pid);
extern void os_stop_process(int pid);
extern void os_kill_process(int pid, int reap_child);
extern void os_kill_ptraced_process(int pid, int reap_child);
extern long os_ptrace_ldt(long pid, long addr, long data);

extern int os_getpid(void);
extern int os_getpgrp(void);
Expand Down
44 changes: 0 additions & 44 deletions arch/um/include/shared/skas/proc_mm.h

This file was deleted.

3 changes: 0 additions & 3 deletions arch/um/include/shared/skas/skas.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@
#include <sysdep/ptrace.h>

extern int userspace_pid[];
extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
extern int skas_needs_stub;

extern int user_thread(unsigned long stack, int flags);
extern void new_thread_handler(void);
extern void handle_syscall(struct uml_pt_regs *regs);
extern int new_mm(unsigned long stack);
extern long execute_syscall_skas(void *r);
extern unsigned long current_stub_stack(void);

Expand Down
14 changes: 0 additions & 14 deletions arch/um/include/shared/skas_ptrace.h

This file was deleted.

32 changes: 0 additions & 32 deletions arch/um/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
#include <linux/sched.h>
#include <linux/tracehook.h>
#include <asm/uaccess.h>
#include <skas_ptrace.h>



void user_enable_single_step(struct task_struct *child)
{
Expand Down Expand Up @@ -104,35 +101,6 @@ long arch_ptrace(struct task_struct *child, long request,
ret = ptrace_set_thread_area(child, addr, vp);
break;

case PTRACE_FAULTINFO: {
/*
* Take the info from thread->arch->faultinfo,
* but transfer max. sizeof(struct ptrace_faultinfo).
* On i386, ptrace_faultinfo is smaller!
*/
ret = copy_to_user(p, &child->thread.arch.faultinfo,
sizeof(struct ptrace_faultinfo)) ?
-EIO : 0;
break;
}

#ifdef PTRACE_LDT
case PTRACE_LDT: {
struct ptrace_ldt ldt;

if (copy_from_user(&ldt, p, sizeof(ldt))) {
ret = -EIO;
break;
}

/*
* This one is confusing, so just punt and return -EIO for
* now
*/
ret = -EIO;
break;
}
#endif
default:
ret = ptrace_request(child, request, addr, data);
if (ret == -EIO)
Expand Down
35 changes: 14 additions & 21 deletions arch/um/kernel/reboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,21 @@ void (*pm_power_off)(void);

static void kill_off_processes(void)
{
if (proc_mm)
/*
* FIXME: need to loop over userspace_pids
*/
os_kill_ptraced_process(userspace_pid[0], 1);
else {
struct task_struct *p;
int pid;

read_lock(&tasklist_lock);
for_each_process(p) {
struct task_struct *t;

t = find_lock_task_mm(p);
if (!t)
continue;
pid = t->mm->context.id.u.pid;
task_unlock(t);
os_kill_ptraced_process(pid, 1);
}
read_unlock(&tasklist_lock);
struct task_struct *p;
int pid;

read_lock(&tasklist_lock);
for_each_process(p) {
struct task_struct *t;

t = find_lock_task_mm(p);
if (!t)
continue;
pid = t->mm->context.id.u.pid;
task_unlock(t);
os_kill_ptraced_process(pid, 1);
}
read_unlock(&tasklist_lock);
}

void uml_cleanup(void)
Expand Down
68 changes: 23 additions & 45 deletions arch/um/kernel/skas/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,35 +54,22 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
unsigned long stack = 0;
int ret = -ENOMEM;

if (skas_needs_stub) {
stack = get_zeroed_page(GFP_KERNEL);
if (stack == 0)
goto out;
}
stack = get_zeroed_page(GFP_KERNEL);
if (stack == 0)
goto out;

to_mm->id.stack = stack;
if (current->mm != NULL && current->mm != &init_mm)
from_mm = &current->mm->context;

if (proc_mm) {
ret = new_mm(stack);
if (ret < 0) {
printk(KERN_ERR "init_new_context_skas - "
"new_mm failed, errno = %d\n", ret);
goto out_free;
}
to_mm->id.u.mm_fd = ret;
}
else {
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);

if (to_mm->id.u.pid < 0) {
ret = to_mm->id.u.pid;
goto out_free;
}
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);

if (to_mm->id.u.pid < 0) {
ret = to_mm->id.u.pid;
goto out_free;
}

ret = init_new_ldt(to_mm, from_mm);
Expand All @@ -105,9 +92,6 @@ void uml_setup_stubs(struct mm_struct *mm)
{
int err, ret;

if (!skas_needs_stub)
return;

ret = init_stub_pte(mm, STUB_CODE,
(unsigned long) &__syscall_stub_start);
if (ret)
Expand Down Expand Up @@ -154,25 +138,19 @@ void destroy_context(struct mm_struct *mm)
{
struct mm_context *mmu = &mm->context;

if (proc_mm)
os_close_file(mmu->id.u.mm_fd);
else {
/*
* If init_new_context wasn't called, this will be
* zero, resulting in a kill(0), which will result in the
* whole UML suddenly dying. Also, cover negative and
* 1 cases, since they shouldn't happen either.
*/
if (mmu->id.u.pid < 2) {
printk(KERN_ERR "corrupt mm_context - pid = %d\n",
mmu->id.u.pid);
return;
}
os_kill_ptraced_process(mmu->id.u.pid, 1);
/*
* If init_new_context wasn't called, this will be
* zero, resulting in a kill(0), which will result in the
* whole UML suddenly dying. Also, cover negative and
* 1 cases, since they shouldn't happen either.
*/
if (mmu->id.u.pid < 2) {
printk(KERN_ERR "corrupt mm_context - pid = %d\n",
mmu->id.u.pid);
return;
}
os_kill_ptraced_process(mmu->id.u.pid, 1);

if (skas_needs_stub)
free_page(mmu->id.stack);

free_page(mmu->id.stack);
free_ldt(mmu);
}
27 changes: 0 additions & 27 deletions arch/um/kernel/skas/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,6 @@
#include <os.h>
#include <skas.h>

int new_mm(unsigned long stack)
{
int fd, err;

fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
if (fd < 0)
return fd;

if (skas_needs_stub) {
err = map_stub_pages(fd, STUB_CODE, STUB_DATA, stack);
if (err) {
os_close_file(fd);
return err;
}
}

return fd;
}

extern void start_kernel(void);

static int __init start_kernel_proc(void *unused)
Expand All @@ -55,14 +36,6 @@ int __init start_uml(void)
{
stack_protections((unsigned long) &cpu0_irqstack);
set_sigstack(cpu0_irqstack, THREAD_SIZE);
if (proc_mm) {
userspace_pid[0] = start_userspace(0);
if (userspace_pid[0] < 0) {
printf("start_uml - start_userspace returned %d\n",
userspace_pid[0]);
exit(1);
}
}

init_new_thread_signals();

Expand Down
2 changes: 1 addition & 1 deletion arch/um/kernel/trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
panic("Segfault with no mm");
}

if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
if (SEGV_IS_FIXABLE(&fi))
err = handle_page_fault(address, ip, is_write, is_user,
&si.si_code);
else {
Expand Down
10 changes: 0 additions & 10 deletions arch/um/kernel/um_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,6 @@ int __init linux_main(int argc, char **argv)
unsigned long stack;
unsigned int i;
int add;
char * mode;

for (i = 1; i < argc; i++) {
if ((i == 1) && (argv[i][0] == ' '))
Expand All @@ -291,15 +290,6 @@ int __init linux_main(int argc, char **argv)
/* OS sanity checks that need to happen before the kernel runs */
os_early_checks();

can_do_skas();

if (proc_mm && ptrace_faultinfo)
mode = "SKAS3";
else
mode = "SKAS0";

printf("UML running in %s mode\n", mode);

brk_start = (unsigned long) sbrk(0);

/*
Expand Down
16 changes: 0 additions & 16 deletions arch/um/os-Linux/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include <init.h>
#include <longjmp.h>
#include <os.h>
#include <skas_ptrace.h>

#define ARBITRARY_ADDR -1
#define FAILURE_PID -1
Expand Down Expand Up @@ -102,21 +101,6 @@ void os_kill_process(int pid, int reap_child)
CATCH_EINTR(waitpid(pid, NULL, __WALL));
}

/* This is here uniquely to have access to the userspace errno, i.e. the one
* used by ptrace in case of error.
*/

long os_ptrace_ldt(long pid, long addr, long data)
{
int ret;

ret = ptrace(PTRACE_LDT, pid, addr, data);

if (ret < 0)
return -errno;
return ret;
}

/* Kill off a ptraced child by all means available. kill it normally first,
* then PTRACE_KILL it, then PTRACE_CONT it in case it's in a run state from
* which it can't exit directly.
Expand Down
Loading

0 comments on commit d0b5e15

Please sign in to comment.