[linux] 03/04: [arm64] Add support for SECCOMP, backported from 3.19
debian-kernel at lists.debian.org
debian-kernel at lists.debian.org
Mon Dec 12 06:38:25 UTC 2016
This is an automated email from the git hooks/post-receive script.
benh pushed a commit to branch benh/jessie-security-backports
in repository linux.
commit de90be20f7f056bd0ecc76d5ae37c48746f0202c
Author: Ben Hutchings <ben at decadent.org.uk>
Date: Sun Dec 11 19:30:41 2016 +0000
[arm64] Add support for SECCOMP, backported from 3.19
---
debian/changelog | 1 +
.../arm64/seccomp/arm64-add-seccomp-support.patch | 116 +++++++++++++++++++++
.../arm64-add-sigsys-siginfo-for-compat-task.patch | 49 +++++++++
.../arm64/seccomp/arm64-add-syscall_get_arch.patch | 48 +++++++++
...rm64-ptrace-add-nt_arm_system_call-regset.patch | 96 +++++++++++++++++
...ptrace-allow-tracer-to-skip-a-system-call.patch | 55 ++++++++++
...-add-generic-seccomp.h-for-secure-computi.patch | 55 ++++++++++
debian/patches/series | 8 ++
8 files changed, 428 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index fdc505c..1ad5730 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -489,6 +489,7 @@ linux (3.16.39-1) UNRELEASED; urgency=medium
* security,perf: Allow unprivileged use of perf_event_open to be disabled
(sysctl: kernel.perf_event_paranoid=3)
* [arm64] Add __NR_* definitions for compat syscalls
+ * [arm64] Add support for SECCOMP, backported from 3.19
[ Julien Cristau ]
* hwrng: Add chaoskey driver, backported from 4.8 (Closes: #839616)
diff --git a/debian/patches/features/arm64/seccomp/arm64-add-seccomp-support.patch b/debian/patches/features/arm64/seccomp/arm64-add-seccomp-support.patch
new file mode 100644
index 0000000..9e2d960
--- /dev/null
+++ b/debian/patches/features/arm64/seccomp/arm64-add-seccomp-support.patch
@@ -0,0 +1,116 @@
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Fri, 28 Nov 2014 05:26:39 +0000
+Subject: [6/6] arm64: add seccomp support
+Origin: https://git.kernel.org/linus/a1ae65b219416a72c15577bd4c8c11174fffbb8b
+Bug-Debian: https://bugs.debian.org/833183
+
+secure_computing() is called first in syscall_trace_enter() so that
+a system call will be aborted quickly without doing succeeding syscall
+tracing if seccomp rules want to deny that system call.
+
+On compat task, syscall numbers for system calls allowed in seccomp mode 1
+are different from those on normal tasks, and so _NR_seccomp_xxx_32's need
+to be redefined.
+
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: Will Deacon <will.deacon at arm.com>
+[bwh: Backported to jessie: pass syscall number to secure_computing()]
+---
+ arch/arm64/Kconfig | 14 ++++++++++++++
+ arch/arm64/include/asm/seccomp.h | 25 +++++++++++++++++++++++++
+ arch/arm64/include/asm/unistd.h | 3 +++
+ arch/arm64/kernel/ptrace.c | 5 +++++
+ 4 files changed, 47 insertions(+)
+ create mode 100644 arch/arm64/include/asm/seccomp.h
+
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -31,6 +31,7 @@ config ARM64
+ select HARDIRQS_SW_RESEND
+ select HAVE_ARCH_JUMP_LABEL
+ select HAVE_ARCH_KGDB
++ select HAVE_ARCH_SECCOMP_FILTER
+ select HAVE_ARCH_TRACEHOOK
+ select HAVE_C_RECORDMCOUNT
+ select HAVE_DEBUG_BUGVERBOSE
+@@ -278,6 +279,19 @@ config ARCH_HAS_CACHE_LINE_SIZE
+
+ source "mm/Kconfig"
+
++config SECCOMP
++ bool "Enable seccomp to safely compute untrusted bytecode"
++ ---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(PR_SET_SECCOMP), it cannot be disabled
++ and the task is only allowed to execute a few safe syscalls
++ defined by each seccomp mode.
++
+ config XEN_DOM0
+ def_bool y
+ depends on XEN
+--- /dev/null
++++ b/arch/arm64/include/asm/seccomp.h
+@@ -0,0 +1,25 @@
++/*
++ * arch/arm64/include/asm/seccomp.h
++ *
++ * Copyright (C) 2014 Linaro Limited
++ * Author: AKASHI Takahiro <takahiro.akashi at linaro.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#ifndef _ASM_SECCOMP_H
++#define _ASM_SECCOMP_H
++
++#include <asm/unistd.h>
++
++#ifdef CONFIG_COMPAT
++#define __NR_seccomp_read_32 __NR_compat_read
++#define __NR_seccomp_write_32 __NR_compat_write
++#define __NR_seccomp_exit_32 __NR_compat_exit
++#define __NR_seccomp_sigreturn_32 __NR_compat_rt_sigreturn
++#endif /* CONFIG_COMPAT */
++
++#include <asm-generic/seccomp.h>
++
++#endif /* _ASM_SECCOMP_H */
+--- a/arch/arm64/include/asm/unistd.h
++++ b/arch/arm64/include/asm/unistd.h
+@@ -31,6 +31,9 @@
+ * Compat syscall numbers used by the AArch64 kernel.
+ */
+ #define __NR_compat_restart_syscall 0
++#define __NR_compat_exit 1
++#define __NR_compat_read 3
++#define __NR_compat_write 4
+ #define __NR_compat_sigreturn 119
+ #define __NR_compat_rt_sigreturn 173
+
+--- a/arch/arm64/kernel/ptrace.c
++++ b/arch/arm64/kernel/ptrace.c
+@@ -26,6 +26,7 @@
+ #include <linux/smp.h>
+ #include <linux/ptrace.h>
+ #include <linux/user.h>
++#include <linux/seccomp.h>
+ #include <linux/security.h>
+ #include <linux/init.h>
+ #include <linux/signal.h>
+@@ -1149,6 +1150,10 @@ static void tracehook_report_syscall(str
+
+ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
+ {
++ /* Do the secure computing check first; failures should be fast. */
++ if (secure_computing(regs->syscallno) == -1)
++ return -1;
++
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+
diff --git a/debian/patches/features/arm64/seccomp/arm64-add-sigsys-siginfo-for-compat-task.patch b/debian/patches/features/arm64/seccomp/arm64-add-sigsys-siginfo-for-compat-task.patch
new file mode 100644
index 0000000..ada4a49
--- /dev/null
+++ b/debian/patches/features/arm64/seccomp/arm64-add-sigsys-siginfo-for-compat-task.patch
@@ -0,0 +1,49 @@
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Fri, 28 Nov 2014 05:26:38 +0000
+Subject: [5/6] arm64: add SIGSYS siginfo for compat task
+Origin: https://git.kernel.org/linus/cc5e9097c9aad6b186a568c534e26746d6bfa483
+Bug-Debian: https://bugs.debian.org/833183
+
+SIGSYS is primarily used in secure computing to notify tracer of syscall
+events. This patch allows signal handler on compat task to get correct
+information with SA_SIGINFO specified when this signal is delivered.
+
+Reviewed-by: Kees Cook <keescook at chromium.org>
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: Will Deacon <will.deacon at arm.com>
+---
+ arch/arm64/include/asm/compat.h | 7 +++++++
+ arch/arm64/kernel/signal32.c | 6 ++++++
+ 2 files changed, 13 insertions(+)
+
+--- a/arch/arm64/include/asm/compat.h
++++ b/arch/arm64/include/asm/compat.h
+@@ -205,6 +205,13 @@ typedef struct compat_siginfo {
+ compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
++
++ /* SIGSYS */
++ struct {
++ compat_uptr_t _call_addr; /* calling user insn */
++ int _syscall; /* triggering system call number */
++ compat_uint_t _arch; /* AUDIT_ARCH_* of syscall */
++ } _sigsys;
+ } _sifields;
+ } compat_siginfo_t;
+
+--- a/arch/arm64/kernel/signal32.c
++++ b/arch/arm64/kernel/signal32.c
+@@ -186,6 +186,12 @@ int copy_siginfo_to_user32(compat_siginf
+ err |= __put_user(from->si_uid, &to->si_uid);
+ err |= __put_user(from->si_int, &to->si_int);
+ break;
++ case __SI_SYS:
++ err |= __put_user((compat_uptr_t)(unsigned long)
++ from->si_call_addr, &to->si_call_addr);
++ err |= __put_user(from->si_syscall, &to->si_syscall);
++ err |= __put_user(from->si_arch, &to->si_arch);
++ break;
+ default: /* this is just in case for now ... */
+ err |= __put_user(from->si_pid, &to->si_pid);
+ err |= __put_user(from->si_uid, &to->si_uid);
diff --git a/debian/patches/features/arm64/seccomp/arm64-add-syscall_get_arch.patch b/debian/patches/features/arm64/seccomp/arm64-add-syscall_get_arch.patch
new file mode 100644
index 0000000..5afb41b
--- /dev/null
+++ b/debian/patches/features/arm64/seccomp/arm64-add-syscall_get_arch.patch
@@ -0,0 +1,48 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Sun, 11 Dec 2016 21:38:32 +0000
+Subject: arm64: Add syscall_get_arch()
+Forwarded: not-needed
+Bug-Debian: https://bugs.debian.org/833183
+
+Extracted from commit 875cbf3e4614 ("arm64: Add audit support").
+
+---
+
+--- a/arch/arm64/include/asm/syscall.h
++++ b/arch/arm64/include/asm/syscall.h
+@@ -16,6 +16,8 @@
+ #ifndef __ASM_SYSCALL_H
+ #define __ASM_SYSCALL_H
+
++#include <uapi/linux/audit.h>
++#include <linux/compat.h>
+ #include <linux/err.h>
+
+ extern const void *sys_call_table[];
+@@ -105,4 +107,16 @@ static inline void syscall_set_arguments
+ memcpy(®s->regs[i], args, n * sizeof(args[0]));
+ }
+
++/*
++ * We don't care about endianness (__AUDIT_ARCH_LE bit) here because
++ * AArch64 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_ARM;
++
++ return AUDIT_ARCH_AARCH64;
++}
++
+ #endif /* __ASM_SYSCALL_H */
+--- a/include/uapi/linux/audit.h
++++ b/include/uapi/linux/audit.h
+@@ -342,6 +342,7 @@ enum {
+ #define __AUDIT_ARCH_64BIT 0x80000000
+ #define __AUDIT_ARCH_LE 0x40000000
+
++#define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+ #define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+ #define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE)
+ #define AUDIT_ARCH_ARMEB (EM_ARM)
diff --git a/debian/patches/features/arm64/seccomp/arm64-ptrace-add-nt_arm_system_call-regset.patch b/debian/patches/features/arm64/seccomp/arm64-ptrace-add-nt_arm_system_call-regset.patch
new file mode 100644
index 0000000..6c67c68
--- /dev/null
+++ b/debian/patches/features/arm64/seccomp/arm64-ptrace-add-nt_arm_system_call-regset.patch
@@ -0,0 +1,96 @@
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Fri, 28 Nov 2014 05:26:34 +0000
+Subject: [1/6] arm64: ptrace: add NT_ARM_SYSTEM_CALL regset
+Origin: https://git.kernel.org/linus/766a85d7bc5d7f1ddd6de28bdb844eae45ec63b0
+Bug-Debian: https://bugs.debian.org/833183
+
+This regeset is intended to be used to get and set a system call number
+while tracing.
+There was some discussion about possible approaches to do so:
+
+(1) modify x8 register with ptrace(PTRACE_SETREGSET) indirectly,
+ and update regs->syscallno later on in syscall_trace_enter(), or
+(2) define a dedicated regset for this purpose as on s390, or
+(3) support ptrace(PTRACE_SET_SYSCALL) as on arch/arm
+
+Thinking of the fact that user_pt_regs doesn't expose 'syscallno' to
+tracer as well as that secure_computing() expects a changed syscall number,
+especially case of -1, to be visible before this function returns in
+syscall_trace_enter(), (1) doesn't work well.
+We will take (2) since it looks much cleaner.
+
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: Will Deacon <will.deacon at arm.com>
+---
+ arch/arm64/kernel/ptrace.c | 35 +++++++++++++++++++++++++++++++++++
+ include/uapi/linux/elf.h | 1 +
+ 2 files changed, 36 insertions(+)
+
+--- a/arch/arm64/kernel/ptrace.c
++++ b/arch/arm64/kernel/ptrace.c
+@@ -555,6 +555,32 @@ static int tls_set(struct task_struct *t
+ return ret;
+ }
+
++static int system_call_get(struct task_struct *target,
++ const struct user_regset *regset,
++ unsigned int pos, unsigned int count,
++ void *kbuf, void __user *ubuf)
++{
++ int syscallno = task_pt_regs(target)->syscallno;
++
++ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
++ &syscallno, 0, -1);
++}
++
++static int system_call_set(struct task_struct *target,
++ const struct user_regset *regset,
++ unsigned int pos, unsigned int count,
++ const void *kbuf, const void __user *ubuf)
++{
++ int syscallno, ret;
++
++ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &syscallno, 0, -1);
++ if (ret)
++ return ret;
++
++ task_pt_regs(target)->syscallno = syscallno;
++ return ret;
++}
++
+ enum aarch64_regset {
+ REGSET_GPR,
+ REGSET_FPR,
+@@ -563,6 +589,7 @@ enum aarch64_regset {
+ REGSET_HW_BREAK,
+ REGSET_HW_WATCH,
+ #endif
++ REGSET_SYSTEM_CALL,
+ };
+
+ static const struct user_regset aarch64_regsets[] = {
+@@ -612,6 +639,14 @@ static const struct user_regset aarch64_
+ .set = hw_break_set,
+ },
+ #endif
++ [REGSET_SYSTEM_CALL] = {
++ .core_note_type = NT_ARM_SYSTEM_CALL,
++ .n = 1,
++ .size = sizeof(int),
++ .align = sizeof(int),
++ .get = system_call_get,
++ .set = system_call_set,
++ },
+ };
+
+ static const struct user_regset_view user_aarch64_view = {
+--- a/include/uapi/linux/elf.h
++++ b/include/uapi/linux/elf.h
+@@ -395,6 +395,7 @@ typedef struct elf64_shdr {
+ #define NT_ARM_TLS 0x401 /* ARM TLS register */
+ #define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
+ #define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
++#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
+ #define NT_METAG_CBUF 0x500 /* Metag catch buffer registers */
+ #define NT_METAG_RPIPE 0x501 /* Metag read pipeline state */
+ #define NT_METAG_TLS 0x502 /* Metag TLS pointer */
diff --git a/debian/patches/features/arm64/seccomp/arm64-ptrace-allow-tracer-to-skip-a-system-call.patch b/debian/patches/features/arm64/seccomp/arm64-ptrace-allow-tracer-to-skip-a-system-call.patch
new file mode 100644
index 0000000..01789da
--- /dev/null
+++ b/debian/patches/features/arm64/seccomp/arm64-ptrace-allow-tracer-to-skip-a-system-call.patch
@@ -0,0 +1,55 @@
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Fri, 28 Nov 2014 05:26:35 +0000
+Subject: [2/6] arm64: ptrace: allow tracer to skip a system call
+Origin: https://git.kernel.org/linus/1014c81d9a5546b64352c04cdb93494aceb317fc
+Bug-Debian: https://bugs.debian.org/833183
+
+If tracer modifies a syscall number to -1, this traced system call should
+be skipped with a return value specified in x0.
+This patch implements this semantics.
+
+Please note:
+* syscall entry tracing and syscall exit tracing (ftrace tracepoint and
+ audit) are always executed, if enabled, even when skipping a system call
+ (that is, -1).
+ In this way, we can avoid a potential bug where audit_syscall_entry()
+ might be called without audit_syscall_exit() at the previous system call
+ being called, that would cause OOPs in audit_syscall_entry().
+
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+[will: fixed up conflict with blr rework]
+Signed-off-by: Will Deacon <will.deacon at arm.com>
+[bwh: Backported to jessie: adjust context]
+---
+ arch/arm64/kernel/entry.S | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/kernel/entry.S
++++ b/arch/arm64/kernel/entry.S
+@@ -626,8 +626,15 @@ ENDPROC(el0_svc)
+ * switches, and waiting for our parent to respond.
+ */
+ __sys_trace:
+- mov x0, sp
++ mov w0, #-1 // set default errno for
++ cmp scno, x0 // user-issued syscall(-1)
++ b.ne 1f
++ mov x0, #-ENOSYS
++ str x0, [sp, #S_X0]
++1: mov x0, sp
+ bl syscall_trace_enter
++ cmp w0, #-1 // skip the syscall?
++ b.eq __sys_trace_return_skipped
+ adr lr, __sys_trace_return // return address
+ uxtw scno, w0 // syscall number (possibly new)
+ mov x1, sp // pointer to regs
+@@ -641,7 +648,8 @@ __sys_trace:
+ br x16 // call sys_* routine
+
+ __sys_trace_return:
+- str x0, [sp] // save returned x0
++ str x0, [sp, #S_X0] // save returned x0
++__sys_trace_return_skipped:
+ mov x0, sp
+ bl syscall_trace_exit
+ b ret_to_user
diff --git a/debian/patches/features/arm64/seccomp/asm-generic-add-generic-seccomp.h-for-secure-computi.patch b/debian/patches/features/arm64/seccomp/asm-generic-add-generic-seccomp.h-for-secure-computi.patch
new file mode 100644
index 0000000..6e01a6d
--- /dev/null
+++ b/debian/patches/features/arm64/seccomp/asm-generic-add-generic-seccomp.h-for-secure-computi.patch
@@ -0,0 +1,55 @@
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Fri, 28 Nov 2014 05:26:36 +0000
+Subject: [3/6] asm-generic: add generic seccomp.h for secure computing mode 1
+Origin: https://git.kernel.org/linus/65a2ae8d5bd0ab9fb5846c0223d5dcf74e87f9d2
+Bug-Debian: https://bugs.debian.org/833183
+
+Those values (__NR_seccomp_*) are used solely in secure_computing()
+to identify mode 1 system calls. If compat system calls have different
+syscall numbers, asm/seccomp.h may override them.
+
+Acked-by: Arnd Bergmann <arnd at arndb.de>
+Reviewed-by: Kees Cook <keescook at chromium.org>
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: Will Deacon <will.deacon at arm.com>
+---
+ include/asm-generic/seccomp.h | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+ create mode 100644 include/asm-generic/seccomp.h
+
+diff --git a/include/asm-generic/seccomp.h b/include/asm-generic/seccomp.h
+new file mode 100644
+index 000000000000..9fa1f653ed3b
+--- /dev/null
++++ b/include/asm-generic/seccomp.h
+@@ -0,0 +1,30 @@
++/*
++ * include/asm-generic/seccomp.h
++ *
++ * Copyright (C) 2014 Linaro Limited
++ * Author: AKASHI Takahiro <takahiro.akashi at linaro.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#ifndef _ASM_GENERIC_SECCOMP_H
++#define _ASM_GENERIC_SECCOMP_H
++
++#include <linux/unistd.h>
++
++#if defined(CONFIG_COMPAT) && !defined(__NR_seccomp_read_32)
++#define __NR_seccomp_read_32 __NR_read
++#define __NR_seccomp_write_32 __NR_write
++#define __NR_seccomp_exit_32 __NR_exit
++#define __NR_seccomp_sigreturn_32 __NR_rt_sigreturn
++#endif /* CONFIG_COMPAT && ! already defined */
++
++#define __NR_seccomp_read __NR_read
++#define __NR_seccomp_write __NR_write
++#define __NR_seccomp_exit __NR_exit
++#ifndef __NR_seccomp_sigreturn
++#define __NR_seccomp_sigreturn __NR_rt_sigreturn
++#endif
++
++#endif /* _ASM_GENERIC_SECCOMP_H */
diff --git a/debian/patches/series b/debian/patches/series
index cc43c09..3b768ee 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -654,6 +654,14 @@ features/all/chaoskey/hwrng-chaoskey-Add-support-for-Araneus-Alea-I-USB-RN.patch
features/all/chaoskey/hwrng-chaoskey-Fix-URB-warning-due-to-timeout-on-Ale.patch
features/all/chaoskey/chaoskey-3.16-no-hwrng-quality.patch
+# seccomp for arm64
+features/arm64/seccomp/arm64-add-syscall_get_arch.patch
+features/arm64/seccomp/arm64-ptrace-add-nt_arm_system_call-regset.patch
+features/arm64/seccomp/arm64-ptrace-allow-tracer-to-skip-a-system-call.patch
+features/arm64/seccomp/asm-generic-add-generic-seccomp.h-for-secure-computi.patch
+features/arm64/seccomp/arm64-add-sigsys-siginfo-for-compat-task.patch
+features/arm64/seccomp/arm64-add-seccomp-support.patch
+
# Security fixes
# Fix ABI changes
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git
More information about the Kernel-svn-changes
mailing list