summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/features/seccomp/seccomp-filter/arch-support.txt2
-rw-r--r--arch/tile/Kconfig17
-rw-r--r--arch/tile/include/asm/Kbuild1
-rw-r--r--arch/tile/include/asm/elf.h4
-rw-r--r--arch/tile/include/asm/syscall.h28
-rw-r--r--arch/tile/include/uapi/arch/opcode_tilegx.h6
-rw-r--r--arch/tile/kernel/intvec_32.S1
-rw-r--r--arch/tile/kernel/intvec_64.S1
-rw-r--r--arch/tile/kernel/ptrace.c3
-rw-r--r--arch/tile/kernel/time.c8
-rw-r--r--arch/tile/kernel/vdso/Makefile4
-rw-r--r--include/uapi/linux/audit.h3
-rw-r--r--include/uapi/linux/elf-em.h2
13 files changed, 67 insertions, 13 deletions
diff --git a/Documentation/features/seccomp/seccomp-filter/arch-support.txt b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
index bea800910342..76d39d66a5d7 100644
--- a/Documentation/features/seccomp/seccomp-filter/arch-support.txt
+++ b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
@@ -32,7 +32,7 @@
| score: | TODO |
| sh: | TODO |
| sparc: | TODO |
- | tile: | TODO |
+ | tile: | ok |
| um: | TODO |
| unicore32: | TODO |
| x86: | ok |
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 9def1f52d03a..2ba12d761723 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -32,6 +32,7 @@ config TILE
select EDAC_SUPPORT
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
+ select HAVE_ARCH_SECCOMP_FILTER
# FIXME: investigate whether we need/want these options.
# select HAVE_IOREMAP_PROT
@@ -221,6 +222,22 @@ config COMPAT
If enabled, the kernel will support running TILE-Gx binaries
that were built with the -m32 option.
+config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ depends on PROC_FS
+ help
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via prctl, it cannot be disabled and the task is only
+ allowed to execute a few safe syscalls defined by each seccomp
+ mode.
+
+ If unsure, say N.
+
config SYSVIPC_COMPAT
def_bool y
depends on COMPAT && SYSVIPC
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index d8a843163471..ba35c41c71ff 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -28,6 +28,7 @@ generic-y += poll.h
generic-y += posix_types.h
generic-y += preempt.h
generic-y += resource.h
+generic-y += seccomp.h
generic-y += sembuf.h
generic-y += serial.h
generic-y += shmbuf.h
diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h
index 41d9878a9686..c505d77e4d06 100644
--- a/arch/tile/include/asm/elf.h
+++ b/arch/tile/include/asm/elf.h
@@ -22,6 +22,7 @@
#include <arch/chip.h>
#include <linux/ptrace.h>
+#include <linux/elf-em.h>
#include <asm/byteorder.h>
#include <asm/page.h>
@@ -30,9 +31,6 @@ typedef unsigned long elf_greg_t;
#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-#define EM_TILEPRO 188
-#define EM_TILEGX 191
-
/* Provide a nominal data structure. */
#define ELF_NFPREG 0
typedef double elf_fpreg_t;
diff --git a/arch/tile/include/asm/syscall.h b/arch/tile/include/asm/syscall.h
index 9644b88f133d..373d73064ea1 100644
--- a/arch/tile/include/asm/syscall.h
+++ b/arch/tile/include/asm/syscall.h
@@ -20,6 +20,8 @@
#include <linux/sched.h>
#include <linux/err.h>
+#include <linux/audit.h>
+#include <linux/compat.h>
#include <arch/abi.h>
/* The array of function pointers for syscalls. */
@@ -61,7 +63,15 @@ static inline void syscall_set_return_value(struct task_struct *task,
struct pt_regs *regs,
int error, long val)
{
- regs->regs[0] = (long) error ?: val;
+ if (error) {
+ /* R0 is the passed-in negative error, R1 is positive. */
+ regs->regs[0] = error;
+ regs->regs[1] = -error;
+ } else {
+ /* R1 set to zero to indicate no error. */
+ regs->regs[0] = val;
+ regs->regs[1] = 0;
+ }
}
static inline void syscall_get_arguments(struct task_struct *task,
@@ -82,4 +92,20 @@ static inline void syscall_set_arguments(struct task_struct *task,
memcpy(&regs[i], args, n * sizeof(args[0]));
}
+/*
+ * We don't care about endianness (__AUDIT_ARCH_LE bit) here because
+ * tile has the same system calls both on little- and big- endian.
+ */
+static inline int syscall_get_arch(void)
+{
+ if (is_compat_task())
+ return AUDIT_ARCH_TILEGX32;
+
+#ifdef CONFIG_TILEGX
+ return AUDIT_ARCH_TILEGX;
+#else
+ return AUDIT_ARCH_TILEPRO;
+#endif
+}
+
#endif /* _ASM_TILE_SYSCALL_H */
diff --git a/arch/tile/include/uapi/arch/opcode_tilegx.h b/arch/tile/include/uapi/arch/opcode_tilegx.h
index d76ff2db745e..9e46eaa847d4 100644
--- a/arch/tile/include/uapi/arch/opcode_tilegx.h
+++ b/arch/tile/include/uapi/arch/opcode_tilegx.h
@@ -830,11 +830,11 @@ enum
ADDX_RRR_0_OPCODE_X0 = 2,
ADDX_RRR_0_OPCODE_X1 = 2,
ADDX_RRR_0_OPCODE_Y0 = 0,
- ADDX_SPECIAL_0_OPCODE_Y1 = 0,
+ ADDX_RRR_0_OPCODE_Y1 = 0,
ADD_RRR_0_OPCODE_X0 = 3,
ADD_RRR_0_OPCODE_X1 = 3,
ADD_RRR_0_OPCODE_Y0 = 1,
- ADD_SPECIAL_0_OPCODE_Y1 = 1,
+ ADD_RRR_0_OPCODE_Y1 = 1,
ANDI_IMM8_OPCODE_X0 = 3,
ANDI_IMM8_OPCODE_X1 = 3,
ANDI_OPCODE_Y0 = 2,
@@ -995,6 +995,7 @@ enum
LD4U_ADD_IMM8_OPCODE_X1 = 12,
LD4U_OPCODE_Y2 = 2,
LD4U_UNARY_OPCODE_X1 = 20,
+ LDNA_ADD_IMM8_OPCODE_X1 = 21,
LDNA_UNARY_OPCODE_X1 = 21,
LDNT1S_ADD_IMM8_OPCODE_X1 = 13,
LDNT1S_UNARY_OPCODE_X1 = 22,
@@ -1015,7 +1016,6 @@ enum
LD_UNARY_OPCODE_X1 = 29,
LNK_UNARY_OPCODE_X1 = 30,
LNK_UNARY_OPCODE_Y1 = 14,
- LWNA_ADD_IMM8_OPCODE_X1 = 21,
MFSPR_IMM8_OPCODE_X1 = 22,
MF_UNARY_OPCODE_X1 = 31,
MM_BF_OPCODE_X0 = 7,
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
index cdbda45a4e4b..fbbe2ea882ea 100644
--- a/arch/tile/kernel/intvec_32.S
+++ b/arch/tile/kernel/intvec_32.S
@@ -1224,6 +1224,7 @@ handle_syscall:
jal do_syscall_trace_enter
}
FEEDBACK_REENTER(handle_syscall)
+ blz r0, .Lsyscall_sigreturn_skip
/*
* We always reload our registers from the stack at this
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S
index 800b91d3f9dc..58964d209d4d 100644
--- a/arch/tile/kernel/intvec_64.S
+++ b/arch/tile/kernel/intvec_64.S
@@ -1247,6 +1247,7 @@ handle_syscall:
jal do_syscall_trace_enter
}
FEEDBACK_REENTER(handle_syscall)
+ bltz r0, .Lsyscall_sigreturn_skip
/*
* We always reload our registers from the stack at this
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c
index f84eed8243da..bdc126faf741 100644
--- a/arch/tile/kernel/ptrace.c
+++ b/arch/tile/kernel/ptrace.c
@@ -262,6 +262,9 @@ int do_syscall_trace_enter(struct pt_regs *regs)
if (work & _TIF_NOHZ)
user_exit();
+ if (secure_computing() == -1)
+ return -1;
+
if (work & _TIF_SYSCALL_TRACE) {
if (tracehook_report_syscall_entry(regs))
regs->regs[TREG_SYSCALL_NR] = -1;
diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c
index 00178ecf9aea..178989e6d3e3 100644
--- a/arch/tile/kernel/time.c
+++ b/arch/tile/kernel/time.c
@@ -140,10 +140,10 @@ static int tile_timer_set_next_event(unsigned long ticks,
* Whenever anyone tries to change modes, we just mask interrupts
* and wait for the next event to get set.
*/
-static void tile_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
+static int tile_timer_shutdown(struct clock_event_device *evt)
{
arch_local_irq_mask_now(INT_TILE_TIMER);
+ return 0;
}
/*
@@ -157,7 +157,9 @@ static DEFINE_PER_CPU(struct clock_event_device, tile_timer) = {
.rating = 100,
.irq = -1,
.set_next_event = tile_timer_set_next_event,
- .set_mode = tile_timer_set_mode,
+ .set_state_shutdown = tile_timer_shutdown,
+ .set_state_oneshot = tile_timer_shutdown,
+ .tick_resume = tile_timer_shutdown,
};
void setup_tile_timer(void)
diff --git a/arch/tile/kernel/vdso/Makefile b/arch/tile/kernel/vdso/Makefile
index a025f63d54cd..c54fff37b5ff 100644
--- a/arch/tile/kernel/vdso/Makefile
+++ b/arch/tile/kernel/vdso/Makefile
@@ -54,7 +54,7 @@ $(obj)/built-in.o: $(obj)/vdso-syms.o
$(obj)/built-in.o: ld_flags += -R $(obj)/vdso-syms.o
SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \
- $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+ $(call cc-ldoption, -Wl$(comma)--hash-style=both)
SYSCFLAGS_vdso_syms.o = -r
$(obj)/vdso-syms.o: $(src)/vdso.lds $(obj)/vrt_sigreturn.o FORCE
$(call if_changed,vdsold)
@@ -113,6 +113,6 @@ $(obj)/vrt_sigreturn32.o: $(obj)/vrt_sigreturn.S
$(obj)/vdso32.o: $(obj)/vdso32.so
SYSCFLAGS_vdso32.so.dbg = -m32 -shared -s -Wl,-soname=linux-vdso32.so.1 \
- $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+ $(call cc-ldoption, -Wl$(comma)--hash-style=both)
$(obj)/vdso32.so.dbg: $(src)/vdso.lds $(obj-vdso32)
$(call if_changed,vdsold)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index d3475e1f15ec..1f977dd4c370 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -382,6 +382,9 @@ enum {
#define AUDIT_ARCH_SHEL64 (EM_SH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_SPARC (EM_SPARC)
#define AUDIT_ARCH_SPARC64 (EM_SPARCV9|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_TILEGX (EM_TILEGX|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_TILEGX32 (EM_TILEGX|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_TILEPRO (EM_TILEPRO|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_PERM_EXEC 1
diff --git a/include/uapi/linux/elf-em.h b/include/uapi/linux/elf-em.h
index b08829667ed7..3429a3ba382b 100644
--- a/include/uapi/linux/elf-em.h
+++ b/include/uapi/linux/elf-em.h
@@ -38,6 +38,8 @@
#define EM_ALTERA_NIOS2 113 /* Altera Nios II soft-core processor */
#define EM_TI_C6000 140 /* TI C6X DSPs */
#define EM_AARCH64 183 /* ARM 64 bit */
+#define EM_TILEPRO 188 /* Tilera TILEPro */
+#define EM_TILEGX 191 /* Tilera TILE-Gx */
#define EM_FRV 0x5441 /* Fujitsu FR-V */
#define EM_AVR32 0x18ad /* Atmel AVR32 */