[MIPS] Fixup secure computing stuff.
Ralf Baechle [Wed, 25 Jul 2007 15:19:33 +0000 (16:19 +0100)]
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

15 files changed:
arch/mips/Kconfig
arch/mips/kernel/asm-offsets.c
arch/mips/kernel/mips-mt-fpaff.c
arch/mips/kernel/process.c
arch/mips/kernel/ptrace.c
arch/mips/kernel/syscall.c
arch/mips/kernel/traps.c
arch/mips/kernel/unaligned.c
drivers/input/evdev.c
include/asm-mips/a.out.h
include/asm-mips/elf.h
include/asm-mips/processor.h
include/asm-mips/seccomp.h [new file with mode: 0644]
include/asm-mips/system.h
include/asm-mips/thread_info.h

index 1e3aecc..410b9d1 100644 (file)
@@ -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
index 3b27309..0133272 100644 (file)
@@ -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, \
index ede5d73..892665b 100644 (file)
@@ -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();
index bd05f5a..e6ce943 100644 (file)
@@ -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;
index 893e7bc..bbd57b2 100644 (file)
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
-#include <linux/audit.h>
 #include <linux/smp.h>
 #include <linux/user.h>
 #include <linux/security.h>
-#include <linux/signal.h>
+#include <linux/audit.h>
+#include <linux/seccomp.h>
 
 #include <asm/byteorder.h>
 #include <asm/cpu.h>
@@ -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]);
 }
index 541b500..7c800ec 100644 (file)
@@ -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:
index ce277cb..c8e291c 100644 (file)
@@ -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 */
index 8b9c34f..5565b89 100644 (file)
@@ -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;
index ab4b2d9..f1c3d6c 100644 (file)
@@ -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
index 1ad60ba..bf55a5b 100644 (file)
@@ -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
 
index ebd6bfb..e7d95d4 100644 (file)
@@ -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);                              \
index 1d8b9a8..83bc945 100644 (file)
@@ -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 (file)
index 0000000..36ed440
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef __ASM_SECCOMP_H
+
+#include <linux/thread_info.h>
+#include <linux/unistd.h>
+
+#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 */
index 8d0b1cd..357251f 100644 (file)
@@ -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;                                   \
index fbcda82..9676e7d 100644 (file)
@@ -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<<TIF_SYSCALL_TRACE)
@@ -131,6 +136,11 @@ register struct thread_info *__current_thread_info __asm__("$28");
 #define _TIF_USEDFPU           (1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_FREEZE            (1<<TIF_FREEZE)
+#define _TIF_FIXADE            (1<<TIF_FIXADE)
+#define _TIF_LOGADE            (1<<TIF_LOGADE)
+#define _TIF_32BIT_REGS                (1<<TIF_32BIT_REGS)
+#define _TIF_32BIT_ADDR                (1<<TIF_32BIT_ADDR)
+#define _TIF_FPUBOUND          (1<<TIF_FPUBOUND)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK         (0x0000ffef & ~_TIF_SECCOMP)