From 293c5bd13f124c325f74f89ad26edf5612ce7235 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 25 Jul 2007 16:19:33 +0100 Subject: [PATCH] [MIPS] Fixup secure computing stuff. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 +- arch/mips/kernel/asm-offsets.c | 1 - arch/mips/kernel/mips-mt-fpaff.c | 9 ++++---- arch/mips/kernel/process.c | 2 +- arch/mips/kernel/ptrace.c | 14 ++++++++---- arch/mips/kernel/syscall.c | 18 +++++++++++----- arch/mips/kernel/traps.c | 2 +- arch/mips/kernel/unaligned.c | 2 +- drivers/input/evdev.c | 2 +- include/asm-mips/a.out.h | 3 ++- include/asm-mips/elf.h | 13 +++++------ include/asm-mips/processor.h | 20 +++-------------- include/asm-mips/seccomp.h | 37 ++++++++++++++++++++++++++++++++ include/asm-mips/system.h | 8 ++++--- include/asm-mips/thread_info.h | 12 ++++++++++- 15 files changed, 98 insertions(+), 47 deletions(-) create mode 100644 include/asm-mips/seccomp.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1e3aeccd7322..410b9d185739 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1772,7 +1772,7 @@ config KEXEC config SECCOMP bool "Enable seccomp to safely compute untrusted bytecode" - depends on PROC_FS && BROKEN + depends on PROC_FS default y help This kernel feature is useful for number crunching applications diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 3b27309d54b1..013327286c26 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -132,7 +132,6 @@ void output_thread_defines(void) offset("#define THREAD_ECODE ", struct task_struct, \ thread.error_code); offset("#define THREAD_TRAPNO ", struct task_struct, thread.trap_no); - offset("#define THREAD_MFLAGS ", struct task_struct, thread.mflags); offset("#define THREAD_TRAMP ", struct task_struct, \ thread.irix_trampoline); offset("#define THREAD_OLDCTX ", struct task_struct, \ diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index ede5d73d652e..892665bb12b1 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -50,6 +50,7 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, cpumask_t effective_mask; int retval; struct task_struct *p; + struct thread_info *ti; if (len < sizeof(new_mask)) return -EINVAL; @@ -93,16 +94,16 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, read_unlock(&tasklist_lock); /* Compute new global allowed CPU set if necessary */ - if ((p->thread.mflags & MF_FPUBOUND) - && cpus_intersects(new_mask, mt_fpu_cpumask)) { + ti = task_thread_info(p); + if (test_ti_thread_flag(ti, TIF_FPUBOUND) && + cpus_intersects(new_mask, mt_fpu_cpumask)) { cpus_and(effective_mask, new_mask, mt_fpu_cpumask); retval = set_cpus_allowed(p, effective_mask); } else { - p->thread.mflags &= ~MF_FPUBOUND; + clear_ti_thread_flag(ti, TIF_FPUBOUND); retval = set_cpus_allowed(p, new_mask); } - out_unlock: put_task_struct(p); unlock_cpu_hotplug(); diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index bd05f5a927ea..e6ce943099a0 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -77,7 +77,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|KU_MASK); #ifdef CONFIG_64BIT status &= ~ST0_FR; - status |= (current->thread.mflags & MF_32BIT_REGS) ? 0 : ST0_FR; + status |= test_thread_flag(TIF_32BIT_REGS) ? 0 : ST0_FR; #endif status |= KU_USER; regs->cp0_status = status; diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 893e7bccf226..bbd57b20b43e 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -20,11 +20,11 @@ #include #include #include -#include #include #include #include -#include +#include +#include #include #include @@ -470,12 +470,17 @@ static inline int audit_arch(void) */ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) { + /* do the secure computing check first */ + if (!entryexit) + secure_computing(regs->regs[0]); + if (unlikely(current->audit_context) && entryexit) audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]), regs->regs[2]); if (!(current->ptrace & PT_PTRACED)) goto out; + if (!test_thread_flag(TIF_SYSCALL_TRACE)) goto out; @@ -493,9 +498,10 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) send_sig(current->exit_code, current, 1); current->exit_code = 0; } - out: + +out: if (unlikely(current->audit_context) && !entryexit) - audit_syscall_entry(audit_arch(), regs->regs[2], + audit_syscall_entry(audit_arch(), regs->regs[0], regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); } diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 541b5005957e..7c800ec3ff55 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -281,16 +281,24 @@ asmlinkage int sys_set_thread_area(unsigned long addr) asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) { - int tmp; - - switch(cmd) { + switch (cmd) { case MIPS_ATOMIC_SET: printk(KERN_CRIT "How did I get here?\n"); return -EINVAL; case MIPS_FIXADE: - tmp = current->thread.mflags & ~3; - current->thread.mflags = tmp | (arg1 & 3); + if (arg1 & ~3) + return -EINVAL; + + if (arg1 & 1) + set_thread_flag(TIF_FIXADE); + else + clear_thread_flag(TIF_FIXADE); + if (arg1 & 2) + set_thread_flag(TIF_LOGADE); + else + clear_thread_flag(TIF_FIXADE); + return 0; case FLUSH_CACHE: diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index ce277cb34dd0..c8e291c83057 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -775,7 +775,7 @@ static void mt_ase_fp_affinity(void) cpus_and(tmask, current->thread.user_cpus_allowed, mt_fpu_cpumask); set_cpus_allowed(current, tmask); - current->thread.mflags |= MF_FPUBOUND; + set_thread_flag(TIF_FPUBOUND); } } #endif /* CONFIG_MIPS_MT_FPAFF */ diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 8b9c34ffae18..5565b89b98e6 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -524,7 +524,7 @@ asmlinkage void do_ade(struct pt_regs *regs) goto sigbus; pc = (unsigned int __user *) exception_epc(regs); - if (user_mode(regs) && (current->thread.mflags & MF_FIXADE) == 0) + if (user_mode(regs) && !test_thread_flag(TIF_FIXADE)) goto sigbus; if (unaligned_action == UNALIGNED_ACTION_SIGNAL) goto sigbus; diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index ab4b2d9b5327..f1c3d6cebd58 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -186,7 +186,7 @@ struct input_event_compat { #elif defined(CONFIG_S390) # define COMPAT_TEST test_thread_flag(TIF_31BIT) #elif defined(CONFIG_MIPS) -# define COMPAT_TEST (current->thread.mflags & MF_32BIT_ADDR) +# define COMPAT_TEST test_thread_flag(TIF_32BIT_ADDR) #else # define COMPAT_TEST test_thread_flag(TIF_32BIT) #endif diff --git a/include/asm-mips/a.out.h b/include/asm-mips/a.out.h index 1ad60ba186d0..bf55a5b34bef 100644 --- a/include/asm-mips/a.out.h +++ b/include/asm-mips/a.out.h @@ -38,7 +38,8 @@ struct exec #define STACK_TOP TASK_SIZE #endif #ifdef CONFIG_64BIT -#define STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE) +#define STACK_TOP \ + (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE) #endif #define STACK_TOP_MAX TASK_SIZE diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h index ebd6bfb19d66..e7d95d48177d 100644 --- a/include/asm-mips/elf.h +++ b/include/asm-mips/elf.h @@ -265,7 +265,7 @@ do { \ #ifdef CONFIG_MIPS32_N32 #define __SET_PERSONALITY32_N32() \ do { \ - current->thread.mflags |= MF_N32; \ + set_thread_flag(TIF_32BIT_ADDR); \ current->thread.abi = &mips_abi_n32; \ } while (0) #else @@ -276,7 +276,8 @@ do { \ #ifdef CONFIG_MIPS32_O32 #define __SET_PERSONALITY32_O32() \ do { \ - current->thread.mflags |= MF_O32; \ + set_thread_flag(TIF_32BIT_REGS); \ + set_thread_flag(TIF_32BIT_ADDR); \ current->thread.abi = &mips_abi_32; \ } while (0) #else @@ -299,13 +300,13 @@ do { \ #define SET_PERSONALITY(ex, ibcs2) \ do { \ - current->thread.mflags &= ~MF_ABI_MASK; \ + clear_thread_flag(TIF_32BIT_REGS); \ + clear_thread_flag(TIF_32BIT_ADDR); \ + \ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ __SET_PERSONALITY32(ex); \ - else { \ - current->thread.mflags |= MF_N64; \ + else \ current->thread.abi = &mips_abi; \ - } \ \ if (ibcs2) \ set_personality(PER_SVR4); \ diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 1d8b9a8ae324..83bc94534084 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -62,8 +62,9 @@ extern unsigned int vced_count, vcei_count; * This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? \ - PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3)) +#define TASK_UNMAPPED_BASE \ + (test_thread_flag(TIF_32BIT_ADDR) ? \ + PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3)) #endif #define NUM_FPU_REGS 32 @@ -132,22 +133,11 @@ struct thread_struct { unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */ unsigned long error_code; unsigned long trap_no; -#define MF_FIXADE 1 /* Fix address errors in software */ -#define MF_LOGADE 2 /* Log address errors to syslog */ -#define MF_32BIT_REGS 4 /* also implies 16/32 fprs */ -#define MF_32BIT_ADDR 8 /* 32-bit address space (o32/n32) */ -#define MF_FPUBOUND 0x10 /* thread bound to FPU-full CPU set */ - unsigned long mflags; unsigned long irix_trampoline; /* Wheee... */ unsigned long irix_oldctx; struct mips_abi *abi; }; -#define MF_ABI_MASK (MF_32BIT_REGS | MF_32BIT_ADDR) -#define MF_O32 (MF_32BIT_REGS | MF_32BIT_ADDR) -#define MF_N32 MF_32BIT_ADDR -#define MF_N64 0 - #ifdef CONFIG_MIPS_MT_FPAFF #define FPAFF_INIT \ .emulated_fp = 0, \ @@ -200,10 +190,6 @@ struct thread_struct { .cp0_baduaddr = 0, \ .error_code = 0, \ .trap_no = 0, \ - /* \ - * For now the default is to fix address errors \ - */ \ - .mflags = MF_FIXADE, \ .irix_trampoline = 0, \ .irix_oldctx = 0, \ } diff --git a/include/asm-mips/seccomp.h b/include/asm-mips/seccomp.h new file mode 100644 index 000000000000..36ed44070256 --- /dev/null +++ b/include/asm-mips/seccomp.h @@ -0,0 +1,37 @@ +#ifndef __ASM_SECCOMP_H + +#include +#include + +#define __NR_seccomp_read __NR_read +#define __NR_seccomp_write __NR_write +#define __NR_seccomp_exit __NR_exit +#define __NR_seccomp_sigreturn __NR_rt_sigreturn + +/* + * Kludge alert: + * + * The generic seccomp code currently allows only a single compat ABI. Until + * this is fixed we priorize O32 as the compat ABI over N32. + */ +#ifdef CONFIG_MIPS32_O32 + +#define TIF_32BIT TIF_32BIT_REGS + +#define __NR_seccomp_read_32 4003 +#define __NR_seccomp_write_32 4004 +#define __NR_seccomp_exit_32 4001 +#define __NR_seccomp_sigreturn_32 4193 /* rt_sigreturn */ + +#elif defined(CONFIG_MIPS32_N32) + +#define TIF_32BIT _TIF_32BIT_ADDR + +#define __NR_seccomp_read_32 6000 +#define __NR_seccomp_write_32 6001 +#define __NR_seccomp_exit_32 6058 +#define __NR_seccomp_sigreturn_32 6211 /* rt_sigreturn */ + +#endif /* CONFIG_MIPS32_O32 */ + +#endif /* __ASM_SECCOMP_H */ diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 8d0b1cd4a45e..357251f42518 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -46,10 +46,12 @@ struct task_struct; #define __mips_mt_fpaff_switch_to(prev) \ do { \ + struct thread_info *__prev_ti = task_thread_info(prev); \ + \ if (cpu_has_fpu && \ - (prev->thread.mflags & MF_FPUBOUND) && \ - (!(KSTK_STATUS(prev) & ST0_CU1))) { \ - prev->thread.mflags &= ~MF_FPUBOUND; \ + test_ti_thread_flag(__prev_ti, TIF_FPUBOUND) && \ + (!(KSTK_STATUS(prev) & ST0_CU1))) { \ + clear_ti_thread_flag(__prev_ti, TIF_FPUBOUND); \ prev->cpus_allowed = prev->thread.user_cpus_allowed; \ } \ next->thread.emulated_fp = 0; \ diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h index fbcda8204473..9676e7d9f52d 100644 --- a/include/asm-mips/thread_info.h +++ b/include/asm-mips/thread_info.h @@ -46,7 +46,7 @@ struct thread_info { { \ .task = &tsk, \ .exec_domain = &default_exec_domain, \ - .flags = 0, \ + .flags = _TIF_FIXADE, \ .cpu = 0, \ .preempt_count = 1, \ .addr_limit = KERNEL_DS, \ @@ -119,6 +119,11 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 18 #define TIF_FREEZE 19 +#define TIF_FIXADE 20 /* Fix address errors in software */ +#define TIF_LOGADE 21 /* Log address errors to syslog */ +#define TIF_32BIT_REGS 22 /* also implies 16/32 fprs */ +#define TIF_32BIT_ADDR 23 /* 32-bit address space (o32/n32) */ +#define TIF_FPUBOUND 24 /* thread bound to FPU-full CPU set */ #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ #define _TIF_SYSCALL_TRACE (1<