core/linux-odroid-c2 to 3.16.57-2

This commit is contained in:
Kevin Mihelich 2018-09-03 00:09:40 +00:00
parent f949a389e2
commit 9f3d19f7ee
18 changed files with 2796 additions and 13 deletions

View file

@ -1,14 +1,14 @@
From 11a0d059489c71a07c4a40b5c1f8cfe5cda96b51 Mon Sep 17 00:00:00 2001 From 967dd9cfe3e038b5e38ea402728f985e931d170f Mon Sep 17 00:00:00 2001
From: Kevin Mihelich <kevin@archlinuxarm.org> From: Kevin Mihelich <kevin@archlinuxarm.org>
Date: Thu, 26 May 2016 06:29:07 -0600 Date: Thu, 26 May 2016 06:29:07 -0600
Subject: [PATCH] add extra errata 843419 build flags Subject: [PATCH 01/16] add extra errata 843419 build flags
--- ---
arch/arm64/Makefile | 1 + arch/arm64/Makefile | 1 +
1 file changed, 1 insertion(+) 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 18ea69f55402..59c5e48458d6 100644 index b92f401c3a86..733aedf927c7 100644
--- a/arch/arm64/Makefile --- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile +++ b/arch/arm64/Makefile
@@ -37,6 +37,7 @@ CHECKFLAGS += -D__aarch64__ @@ -37,6 +37,7 @@ CHECKFLAGS += -D__aarch64__
@ -20,5 +20,5 @@ index 18ea69f55402..59c5e48458d6 100644
# Default value # Default value
-- --
2.11.0 2.18.0

View file

@ -0,0 +1,83 @@
From 32e551d35640bb67e9f7655a499ffa9bf3a5ff69 Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
Date: Fri, 4 Jul 2014 08:28:30 +0100
Subject: [PATCH 02/16] arm64: Add audit support
On AArch64, audit is supported through generic lib/audit.c and
compat_audit.c, and so this patch adds arch specific definitions required.
Acked-by Will Deacon <will.deacon@arm.com>
Acked-by: Richard Guy Briggs <rgb@redhat.com>
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/Kconfig | 2 ++
arch/arm64/include/asm/syscall.h | 14 ++++++++++++++
include/uapi/linux/audit.h | 1 +
3 files changed, 17 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index abed91857926..a3f9d227d179 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -12,6 +12,7 @@ config ARM64
select ARM_AMBA
select ARM_ARCH_TIMER
select ARM_GIC
+ select AUDIT_ARCH_COMPAT_GENERIC
select BUILDTIME_EXTABLE_SORT
select CLONE_BACKWARDS
select COMMON_CLK
@@ -30,6 +31,7 @@ config ARM64
select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
select HARDIRQS_SW_RESEND
+ select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 383771eb0b87..709a574468f0 100644
--- 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(struct task_struct *task,
memcpy(&regs->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 */
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 6f94bf3f28a9..c460caf7221d 100644
--- 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)
--
2.18.0

View file

@ -0,0 +1,58 @@
From 73a08be22f457df505b9d2346b1e94b96e1ffae6 Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
Date: Wed, 21 May 2014 15:02:11 -0700
Subject: [PATCH 03/16] seccomp: create internal mode-setting function
In preparation for having other callers of the seccomp mode setting
logic, split the prctl entry point away from the core logic that performs
seccomp mode setting.
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
(cherry picked from commit d78ab02c2c194257a03355fbb79eb721b381d105)
---
kernel/seccomp.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index e2eb71b1e970..ef24e22c3d14 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -473,7 +473,7 @@ long prctl_get_seccomp(void)
}
/**
- * prctl_set_seccomp: configures current->seccomp.mode
+ * seccomp_set_mode: internal function for setting seccomp mode
* @seccomp_mode: requested mode to use
* @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER
*
@@ -486,7 +486,7 @@ long prctl_get_seccomp(void)
*
* Returns 0 on success or -EINVAL on failure.
*/
-long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter)
+static long seccomp_set_mode(unsigned long seccomp_mode, char __user *filter)
{
long ret = -EINVAL;
@@ -517,3 +517,15 @@ long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter)
out:
return ret;
}
+
+/**
+ * prctl_set_seccomp: configures current->seccomp.mode
+ * @seccomp_mode: requested mode to use
+ * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER
+ *
+ * Returns 0 on success or -EINVAL on failure.
+ */
+long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter)
+{
+ return seccomp_set_mode(seccomp_mode, filter);
+}
--
2.18.0

View file

@ -0,0 +1,67 @@
From 3a8c560eb7c461639a6d2310c32be6434b962cf0 Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
Date: Wed, 25 Jun 2014 15:38:02 -0700
Subject: [PATCH 04/16] seccomp: extract check/assign mode helpers
To support splitting mode 1 from mode 2, extract the mode checking and
assignment logic into common functions.
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
(cherry picked from commit 1f41b450416e689b9b7c8bfb750a98604f687a9b)
---
kernel/seccomp.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index ef24e22c3d14..8ddb252835aa 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -194,7 +194,23 @@ static u32 seccomp_run_filters(int syscall)
}
return ret;
}
+#endif /* CONFIG_SECCOMP_FILTER */
+static inline bool seccomp_may_assign_mode(unsigned long seccomp_mode)
+{
+ if (current->seccomp.mode && current->seccomp.mode != seccomp_mode)
+ return false;
+
+ return true;
+}
+
+static inline void seccomp_assign_mode(unsigned long seccomp_mode)
+{
+ current->seccomp.mode = seccomp_mode;
+ set_tsk_thread_flag(current, TIF_SECCOMP);
+}
+
+#ifdef CONFIG_SECCOMP_FILTER
/**
* seccomp_attach_filter: Attaches a seccomp filter to current.
* @fprog: BPF program to install
@@ -490,8 +506,7 @@ static long seccomp_set_mode(unsigned long seccomp_mode, char __user *filter)
{
long ret = -EINVAL;
- if (current->seccomp.mode &&
- current->seccomp.mode != seccomp_mode)
+ if (!seccomp_may_assign_mode(seccomp_mode))
goto out;
switch (seccomp_mode) {
@@ -512,8 +527,7 @@ static long seccomp_set_mode(unsigned long seccomp_mode, char __user *filter)
goto out;
}
- current->seccomp.mode = seccomp_mode;
- set_thread_flag(TIF_SECCOMP);
+ seccomp_assign_mode(seccomp_mode);
out:
return ret;
}
--
2.18.0

View file

@ -0,0 +1,126 @@
From a4c3f708e3c96d147ec318eb7f5742fbe7cfb536 Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
Date: Wed, 25 Jun 2014 15:55:25 -0700
Subject: [PATCH 05/16] seccomp: split mode setting routines
Separates the two mode setting paths to make things more readable with
fewer #ifdefs within function bodies.
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
(cherry picked from commit 3b23dd12846215eff4afb073366b80c0c4d7543e)
---
kernel/seccomp.c | 71 ++++++++++++++++++++++++++++++++----------------
1 file changed, 48 insertions(+), 23 deletions(-)
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 8ddb252835aa..d82359968d57 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -489,48 +489,66 @@ long prctl_get_seccomp(void)
}
/**
- * seccomp_set_mode: internal function for setting seccomp mode
- * @seccomp_mode: requested mode to use
- * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER
- *
- * This function may be called repeatedly with a @seccomp_mode of
- * SECCOMP_MODE_FILTER to install additional filters. Every filter
- * successfully installed will be evaluated (in reverse order) for each system
- * call the task makes.
+ * seccomp_set_mode_strict: internal function for setting strict seccomp
*
* Once current->seccomp.mode is non-zero, it may not be changed.
*
* Returns 0 on success or -EINVAL on failure.
*/
-static long seccomp_set_mode(unsigned long seccomp_mode, char __user *filter)
+static long seccomp_set_mode_strict(void)
{
+ const unsigned long seccomp_mode = SECCOMP_MODE_STRICT;
long ret = -EINVAL;
if (!seccomp_may_assign_mode(seccomp_mode))
goto out;
- switch (seccomp_mode) {
- case SECCOMP_MODE_STRICT:
- ret = 0;
#ifdef TIF_NOTSC
- disable_TSC();
+ disable_TSC();
#endif
- break;
+ seccomp_assign_mode(seccomp_mode);
+ ret = 0;
+
+out:
+
+ return ret;
+}
+
#ifdef CONFIG_SECCOMP_FILTER
- case SECCOMP_MODE_FILTER:
- ret = seccomp_attach_user_filter(filter);
- if (ret)
- goto out;
- break;
-#endif
- default:
+/**
+ * seccomp_set_mode_filter: internal function for setting seccomp filter
+ * @filter: struct sock_fprog containing filter
+ *
+ * This function may be called repeatedly to install additional filters.
+ * Every filter successfully installed will be evaluated (in reverse order)
+ * for each system call the task makes.
+ *
+ * Once current->seccomp.mode is non-zero, it may not be changed.
+ *
+ * Returns 0 on success or -EINVAL on failure.
+ */
+static long seccomp_set_mode_filter(char __user *filter)
+{
+ const unsigned long seccomp_mode = SECCOMP_MODE_FILTER;
+ long ret = -EINVAL;
+
+ if (!seccomp_may_assign_mode(seccomp_mode))
+ goto out;
+
+ ret = seccomp_attach_user_filter(filter);
+ if (ret)
goto out;
- }
seccomp_assign_mode(seccomp_mode);
out:
return ret;
}
+#else
+static inline long seccomp_set_mode_filter(char __user *filter)
+{
+ return -EINVAL;
+}
+#endif
/**
* prctl_set_seccomp: configures current->seccomp.mode
@@ -541,5 +559,12 @@ out:
*/
long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter)
{
- return seccomp_set_mode(seccomp_mode, filter);
+ switch (seccomp_mode) {
+ case SECCOMP_MODE_STRICT:
+ return seccomp_set_mode_strict();
+ case SECCOMP_MODE_FILTER:
+ return seccomp_set_mode_filter(filter);
+ default:
+ return -EINVAL;
+ }
}
--
2.18.0

View file

@ -0,0 +1,236 @@
From 1d7729de997ef9ecb1c9eef1ccf8d191197f984c Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
Date: Wed, 25 Jun 2014 16:08:24 -0700
Subject: [PATCH 06/16] seccomp: add "seccomp" syscall
This adds the new "seccomp" syscall with both an "operation" and "flags"
parameter for future expansion. The third argument is a pointer value,
used with the SECCOMP_SET_MODE_FILTER operation. Currently, flags must
be 0. This is functionally equivalent to prctl(PR_SET_SECCOMP, ...).
In addition to the TSYNC flag later in this patch series, there is a
non-zero chance that this syscall could be used for configuring a fixed
argument area for seccomp-tracer-aware processes to pass syscall arguments
in the future. Hence, the use of "seccomp" not simply "seccomp_add_filter"
for this syscall. Additionally, this syscall uses operation, flags,
and user pointer for arguments because strictly passing arguments via
a user pointer would mean seccomp itself would be unable to trivially
filter the seccomp syscall itself.
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
(cherry picked from commit 48dc92b9fc3926844257316e75ba11eb5c742b2c)
---
arch/Kconfig | 1 +
arch/x86/syscalls/syscall_32.tbl | 1 +
arch/x86/syscalls/syscall_64.tbl | 1 +
include/linux/syscalls.h | 2 ++
include/uapi/asm-generic/unistd.h | 3 +-
include/uapi/linux/seccomp.h | 4 +++
kernel/seccomp.c | 55 ++++++++++++++++++++++++++++---
kernel/sys_ni.c | 3 ++
8 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index 94e811ef45f5..6ba80554149c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -321,6 +321,7 @@ config HAVE_ARCH_SECCOMP_FILTER
- secure_computing is called from a ptrace_event()-safe context
- secure_computing return value is checked and a return value of -1
results in the system call being skipped immediately.
+ - seccomp syscall wired up
config SECCOMP_FILTER
def_bool y
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index 16209a990be7..cc4c8b448867 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -360,4 +360,5 @@
351 i386 sched_setattr sys_sched_setattr
352 i386 sched_getattr sys_sched_getattr
353 i386 renameat2 sys_renameat2
+354 i386 seccomp sys_seccomp
356 i386 memfd_create sys_memfd_create
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
index 9fdc507c0641..a22cd271b891 100644
--- a/arch/x86/syscalls/syscall_64.tbl
+++ b/arch/x86/syscalls/syscall_64.tbl
@@ -323,6 +323,7 @@
314 common sched_setattr sys_sched_setattr
315 common sched_getattr sys_sched_getattr
316 common renameat2 sys_renameat2
+317 common seccomp sys_seccomp
319 common memfd_create sys_memfd_create
#
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 9836e157fc5e..1e6977f03277 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -867,4 +867,6 @@ asmlinkage long sys_process_vm_writev(pid_t pid,
asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type,
unsigned long idx1, unsigned long idx2);
asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags);
+asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
+ const char __user *uargs);
#endif
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index b4588752d50f..4f1d521e0af3 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -699,7 +699,8 @@ __SYSCALL(__NR_sched_setattr, sys_sched_setattr)
__SYSCALL(__NR_sched_getattr, sys_sched_getattr)
#define __NR_renameat2 276
__SYSCALL(__NR_renameat2, sys_renameat2)
-__SYSCALL(277, sys_ni_syscall)
+#define __NR_seccomp 277
+__SYSCALL(__NR_seccomp, sys_seccomp)
__SYSCALL(278, sys_ni_syscall)
#define __NR_memfd_create 279
__SYSCALL(__NR_memfd_create, sys_memfd_create)
diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h
index ac2dc9f72973..b258878ba754 100644
--- a/include/uapi/linux/seccomp.h
+++ b/include/uapi/linux/seccomp.h
@@ -10,6 +10,10 @@
#define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */
#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */
+/* Valid operations for seccomp syscall. */
+#define SECCOMP_SET_MODE_STRICT 0
+#define SECCOMP_SET_MODE_FILTER 1
+
/*
* All BPF programs must return a 32-bit value.
* The bottom 16-bits are for optional return data.
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index d82359968d57..d2596136b0d1 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -18,6 +18,7 @@
#include <linux/compat.h>
#include <linux/sched.h>
#include <linux/seccomp.h>
+#include <linux/syscalls.h>
/* #define SECCOMP_DEBUG 1 */
@@ -314,7 +315,7 @@ free_prog:
*
* Returns 0 on success and non-zero otherwise.
*/
-static long seccomp_attach_user_filter(char __user *user_filter)
+static long seccomp_attach_user_filter(const char __user *user_filter)
{
struct sock_fprog fprog;
long ret = -EFAULT;
@@ -517,6 +518,7 @@ out:
#ifdef CONFIG_SECCOMP_FILTER
/**
* seccomp_set_mode_filter: internal function for setting seccomp filter
+ * @flags: flags to change filter behavior
* @filter: struct sock_fprog containing filter
*
* This function may be called repeatedly to install additional filters.
@@ -527,11 +529,16 @@ out:
*
* Returns 0 on success or -EINVAL on failure.
*/
-static long seccomp_set_mode_filter(char __user *filter)
+static long seccomp_set_mode_filter(unsigned int flags,
+ const char __user *filter)
{
const unsigned long seccomp_mode = SECCOMP_MODE_FILTER;
long ret = -EINVAL;
+ /* Validate flags. */
+ if (flags != 0)
+ goto out;
+
if (!seccomp_may_assign_mode(seccomp_mode))
goto out;
@@ -544,12 +551,35 @@ out:
return ret;
}
#else
-static inline long seccomp_set_mode_filter(char __user *filter)
+static inline long seccomp_set_mode_filter(unsigned int flags,
+ const char __user *filter)
{
return -EINVAL;
}
#endif
+/* Common entry point for both prctl and syscall. */
+static long do_seccomp(unsigned int op, unsigned int flags,
+ const char __user *uargs)
+{
+ switch (op) {
+ case SECCOMP_SET_MODE_STRICT:
+ if (flags != 0 || uargs != NULL)
+ return -EINVAL;
+ return seccomp_set_mode_strict();
+ case SECCOMP_SET_MODE_FILTER:
+ return seccomp_set_mode_filter(flags, uargs);
+ default:
+ return -EINVAL;
+ }
+}
+
+SYSCALL_DEFINE3(seccomp, unsigned int, op, unsigned int, flags,
+ const char __user *, uargs)
+{
+ return do_seccomp(op, flags, uargs);
+}
+
/**
* prctl_set_seccomp: configures current->seccomp.mode
* @seccomp_mode: requested mode to use
@@ -559,12 +589,27 @@ static inline long seccomp_set_mode_filter(char __user *filter)
*/
long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter)
{
+ unsigned int op;
+ char __user *uargs;
+
switch (seccomp_mode) {
case SECCOMP_MODE_STRICT:
- return seccomp_set_mode_strict();
+ op = SECCOMP_SET_MODE_STRICT;
+ /*
+ * Setting strict mode through prctl always ignored filter,
+ * so make sure it is always NULL here to pass the internal
+ * check in do_seccomp().
+ */
+ uargs = NULL;
+ break;
case SECCOMP_MODE_FILTER:
- return seccomp_set_mode_filter(filter);
+ op = SECCOMP_SET_MODE_FILTER;
+ uargs = filter;
+ break;
default:
return -EINVAL;
}
+
+ /* prctl interface doesn't have flags, so they are always zero. */
+ return do_seccomp(op, 0, uargs);
}
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 489a4e6498c7..1f79e3714533 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -214,3 +214,6 @@ cond_syscall(compat_sys_open_by_handle_at);
/* compare kernel pointers */
cond_syscall(sys_kcmp);
+
+/* operate on Secure Computing state */
+cond_syscall(sys_seccomp);
--
2.18.0

View file

@ -0,0 +1,328 @@
From 086a08b553a9c276154772f717cb586c636d6b49 Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Thu, 17 Jul 2014 04:13:05 -0400
Subject: [PATCH 07/16] random: introduce getrandom(2) system call
The getrandom(2) system call was requested by the LibreSSL Portable
developers. It is analoguous to the getentropy(2) system call in
OpenBSD.
The rationale of this system call is to provide resiliance against
file descriptor exhaustion attacks, where the attacker consumes all
available file descriptors, forcing the use of the fallback code where
/dev/[u]random is not available. Since the fallback code is often not
well-tested, it is better to eliminate this potential failure mode
entirely.
The other feature provided by this new system call is the ability to
request randomness from the /dev/urandom entropy pool, but to block
until at least 128 bits of entropy has been accumulated in the
/dev/urandom entropy pool. Historically, the emphasis in the
/dev/urandom development has been to ensure that urandom pool is
initialized as quickly as possible after system boot, and preferably
before the init scripts start execution.
This is because changing /dev/urandom reads to block represents an
interface change that could potentially break userspace which is not
acceptable. In practice, on most x86 desktop and server systems, in
general the entropy pool can be initialized before it is needed (and
in modern kernels, we will printk a warning message if not). However,
on an embedded system, this may not be the case. And so with this new
interface, we can provide the functionality of blocking until the
urandom pool has been initialized. Any userspace program which uses
this new functionality must take care to assure that if it is used
during the boot process, that it will not cause the init scripts or
other portions of the system startup to hang indefinitely.
SYNOPSIS
#include <linux/random.h>
int getrandom(void *buf, size_t buflen, unsigned int flags);
DESCRIPTION
The system call getrandom() fills the buffer pointed to by buf
with up to buflen random bytes which can be used to seed user
space random number generators (i.e., DRBG's) or for other
cryptographic uses. It should not be used for Monte Carlo
simulations or other programs/algorithms which are doing
probabilistic sampling.
If the GRND_RANDOM flags bit is set, then draw from the
/dev/random pool instead of the /dev/urandom pool. The
/dev/random pool is limited based on the entropy that can be
obtained from environmental noise, so if there is insufficient
entropy, the requested number of bytes may not be returned.
If there is no entropy available at all, getrandom(2) will
either block, or return an error with errno set to EAGAIN if
the GRND_NONBLOCK bit is set in flags.
If the GRND_RANDOM bit is not set, then the /dev/urandom pool
will be used. Unlike using read(2) to fetch data from
/dev/urandom, if the urandom pool has not been sufficiently
initialized, getrandom(2) will block (or return -1 with the
errno set to EAGAIN if the GRND_NONBLOCK bit is set in flags).
The getentropy(2) system call in OpenBSD can be emulated using
the following function:
int getentropy(void *buf, size_t buflen)
{
int ret;
if (buflen > 256)
goto failure;
ret = getrandom(buf, buflen, 0);
if (ret < 0)
return ret;
if (ret == buflen)
return 0;
failure:
errno = EIO;
return -1;
}
RETURN VALUE
On success, the number of bytes that was filled in the buf is
returned. This may not be all the bytes requested by the
caller via buflen if insufficient entropy was present in the
/dev/random pool, or if the system call was interrupted by a
signal.
On error, -1 is returned, and errno is set appropriately.
ERRORS
EINVAL An invalid flag was passed to getrandom(2)
EFAULT buf is outside the accessible address space.
EAGAIN The requested entropy was not available, and
getentropy(2) would have blocked if the
GRND_NONBLOCK flag was not set.
EINTR While blocked waiting for entropy, the call was
interrupted by a signal handler; see the description
of how interrupted read(2) calls on "slow" devices
are handled with and without the SA_RESTART flag
in the signal(7) man page.
NOTES
For small requests (buflen <= 256) getrandom(2) will not
return EINTR when reading from the urandom pool once the
entropy pool has been initialized, and it will return all of
the bytes that have been requested. This is the recommended
way to use getrandom(2), and is designed for compatibility
with OpenBSD's getentropy() system call.
However, if you are using GRND_RANDOM, then getrandom(2) may
block until the entropy accounting determines that sufficient
environmental noise has been gathered such that getrandom(2)
will be operating as a NRBG instead of a DRBG for those people
who are working in the NIST SP 800-90 regime. Since it may
block for a long time, these guarantees do *not* apply. The
user may want to interrupt a hanging process using a signal,
so blocking until all of the requested bytes are returned
would be unfriendly.
For this reason, the user of getrandom(2) MUST always check
the return value, in case it returns some error, or if fewer
bytes than requested was returned. In the case of
!GRND_RANDOM and small request, the latter should never
happen, but the careful userspace code (and all crypto code
should be careful) should check for this anyway!
Finally, unless you are doing long-term key generation (and
perhaps not even then), you probably shouldn't be using
GRND_RANDOM. The cryptographic algorithms used for
/dev/urandom are quite conservative, and so should be
sufficient for all purposes. The disadvantage of GRND_RANDOM
is that it can block, and the increased complexity required to
deal with partially fulfilled getrandom(2) requests.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Zach Brown <zab@zabbo.net>
---
arch/x86/syscalls/syscall_32.tbl | 1 +
arch/x86/syscalls/syscall_64.tbl | 1 +
drivers/char/random.c | 40 ++++++++++++++++++++++++++++---
include/linux/syscalls.h | 3 +++
include/uapi/asm-generic/unistd.h | 3 ++-
include/uapi/linux/random.h | 9 +++++++
6 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index cc4c8b448867..617d15fa1d6d 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -361,4 +361,5 @@
352 i386 sched_getattr sys_sched_getattr
353 i386 renameat2 sys_renameat2
354 i386 seccomp sys_seccomp
+355 i386 getrandom sys_getrandom
356 i386 memfd_create sys_memfd_create
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
index a22cd271b891..ca2b9aa78c81 100644
--- a/arch/x86/syscalls/syscall_64.tbl
+++ b/arch/x86/syscalls/syscall_64.tbl
@@ -324,6 +324,7 @@
315 common sched_getattr sys_sched_getattr
316 common renameat2 sys_renameat2
317 common seccomp sys_seccomp
+318 common getrandom sys_getrandom
319 common memfd_create sys_memfd_create
#
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 692482b7c2fb..5d7e2b1cb09b 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -257,6 +257,8 @@
#include <linux/kmemcheck.h>
#include <linux/workqueue.h>
#include <linux/irq.h>
+#include <linux/syscalls.h>
+#include <linux/completion.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
@@ -401,6 +403,7 @@ static struct poolinfo {
*/
static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
+static DECLARE_WAIT_QUEUE_HEAD(urandom_init_wait);
static struct fasync_struct *fasync;
/**********************************************************************
@@ -657,6 +660,7 @@ retry:
r->entropy_total = 0;
if (r == &nonblocking_pool) {
prandom_reseed_late();
+ wake_up_interruptible(&urandom_init_wait);
pr_notice("random: %s pool is initialized\n", r->name);
}
}
@@ -1161,13 +1165,14 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
{
ssize_t ret = 0, i;
__u8 tmp[EXTRACT_SIZE];
+ int large_request = (nbytes > 256);
trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
xfer_secondary_pool(r, nbytes);
nbytes = account(r, nbytes, 0, 0);
while (nbytes) {
- if (need_resched()) {
+ if (large_request && need_resched()) {
if (signal_pending(current)) {
if (ret == 0)
ret = -ERESTARTSYS;
@@ -1342,7 +1347,7 @@ static int arch_random_refill(void)
}
static ssize_t
-random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+_random_read(int nonblock, char __user *buf, size_t nbytes)
{
ssize_t n;
@@ -1366,7 +1371,7 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
if (arch_random_refill())
continue;
- if (file->f_flags & O_NONBLOCK)
+ if (nonblock)
return -EAGAIN;
wait_event_interruptible(random_read_wait,
@@ -1377,6 +1382,12 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
}
}
+static ssize_t
+random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+{
+ return _random_read(file->f_flags & O_NONBLOCK, buf, nbytes);
+}
+
static ssize_t
urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
@@ -1525,6 +1536,29 @@ const struct file_operations urandom_fops = {
.llseek = noop_llseek,
};
+SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
+ unsigned int, flags)
+{
+ if (flags & ~(GRND_NONBLOCK|GRND_RANDOM))
+ return -EINVAL;
+
+ if (count > INT_MAX)
+ count = INT_MAX;
+
+ if (flags & GRND_RANDOM)
+ return _random_read(flags & GRND_NONBLOCK, buf, count);
+
+ if (unlikely(nonblocking_pool.initialized == 0)) {
+ if (flags & GRND_NONBLOCK)
+ return -EAGAIN;
+ wait_event_interruptible(urandom_init_wait,
+ nonblocking_pool.initialized);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ }
+ return urandom_read(NULL, buf, count, NULL);
+}
+
/***************************************************************
* Random UUID interface
*
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 1e6977f03277..8597786ea362 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -866,6 +866,9 @@ asmlinkage long sys_process_vm_writev(pid_t pid,
asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type,
unsigned long idx1, unsigned long idx2);
+asmlinkage long sys_getrandom(char __user *buf, size_t count,
+ unsigned int flags);
+
asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags);
asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
const char __user *uargs);
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 4f1d521e0af3..11d11bc5c78f 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -701,7 +701,8 @@ __SYSCALL(__NR_sched_getattr, sys_sched_getattr)
__SYSCALL(__NR_renameat2, sys_renameat2)
#define __NR_seccomp 277
__SYSCALL(__NR_seccomp, sys_seccomp)
-__SYSCALL(278, sys_ni_syscall)
+#define __NR_getrandom 278
+__SYSCALL(__NR_getrandom, sys_getrandom)
#define __NR_memfd_create 279
__SYSCALL(__NR_memfd_create, sys_memfd_create)
diff --git a/include/uapi/linux/random.h b/include/uapi/linux/random.h
index fff3528a078f..3f93d1695e7f 100644
--- a/include/uapi/linux/random.h
+++ b/include/uapi/linux/random.h
@@ -40,4 +40,13 @@ struct rand_pool_info {
__u32 buf[0];
};
+/*
+ * Flags for getrandom(2)
+ *
+ * GRND_NONBLOCK Don't block and return EAGAIN instead
+ * GRND_RANDOM Use the /dev/random pool instead of /dev/urandom
+ */
+#define GRND_NONBLOCK 0x0001
+#define GRND_RANDOM 0x0002
+
#endif /* _UAPI_LINUX_RANDOM_H */
--
2.18.0

View file

@ -0,0 +1,31 @@
From d24768a36614bd5f547a60b9a1c64be707bd3a24 Mon Sep 17 00:00:00 2001
From: Kevin Mihelich <kevin@archlinuxarm.org>
Date: Sun, 2 Sep 2018 15:57:10 -0600
Subject: [PATCH 08/16] Revert "arm64: compat: wire up memfd_create syscall for
aarch32"
This reverts commit 92c47b1c5b173365582c61229e50dd6477b3e8a4.
---
arch/arm64/include/asm/unistd32.h | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 75eacd239848..c8d8fc17bd5a 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -404,11 +404,8 @@ __SYSCALL(379, sys_finit_module)
__SYSCALL(380, sys_sched_setattr)
__SYSCALL(381, sys_sched_getattr)
__SYSCALL(382, sys_renameat2)
-__SYSCALL(383, sys_ni_syscall) /* 383 for seccomp */
-__SYSCALL(384, sys_ni_syscall) /* 384 for getrandom */
-__SYSCALL(385, sys_memfd_create)
-#define __NR_compat_syscalls 386
+#define __NR_compat_syscalls 383
/*
* Compat syscall numbers used by the AArch64 kernel.
--
2.18.0

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,44 @@
From 5523645bcf35e6d3142bcbf91679d4523e689df5 Mon Sep 17 00:00:00 2001
From: Will Deacon <will.deacon@arm.com>
Date: Mon, 11 Aug 2014 14:23:37 +0100
Subject: [PATCH 10/16] arm64: compat: wire up memfd_create and getrandom
syscalls for aarch32
arch/arm/ just grew support for the new memfd_create and getrandom
syscalls, so add them to our compat layer too.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/unistd.h | 2 +-
arch/arm64/include/asm/unistd32.h | 5 +++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 4bc95d27e063..6d2bf419431d 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -41,7 +41,7 @@
#define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2)
#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5)
-#define __NR_compat_syscalls 383
+#define __NR_compat_syscalls 386
#endif
#define __ARCH_WANT_SYS_CLONE
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index e242600c4046..da1f06b535e3 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -787,3 +787,8 @@ __SYSCALL(__NR_sched_setattr, sys_sched_setattr)
__SYSCALL(__NR_sched_getattr, sys_sched_getattr)
#define __NR_renameat2 382
__SYSCALL(__NR_renameat2, sys_renameat2)
+ /* 383 for seccomp */
+#define __NR_getrandom 384
+__SYSCALL(__NR_getrandom, sys_getrandom)
+#define __NR_memfd_create 385
+__SYSCALL(__NR_memfd_create, sys_memfd_create)
--
2.18.0

View file

@ -0,0 +1,64 @@
From 596747f36cc455e99f5e6d1b87177e4b208c0c2b Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
Date: Thu, 21 Aug 2014 17:56:40 +0900
Subject: [PATCH 11/16] arm64: ptrace: add PTRACE_SET_SYSCALL
To allow tracer to be able to change/skip a system call by re-writing
a syscall number, there are several approaches:
(1) modify x8 register with ptrace(PTRACE_SETREGSET), and handle this case
later on in syscall_trace_enter(), or
(2) support ptrace(PTRACE_SET_SYSCALL) as on 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
to be visible, especially case of -1, before this function returns in
syscall_trace_enter(), we'd better take (2).
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
---
arch/arm64/include/uapi/asm/ptrace.h | 1 +
arch/arm64/kernel/ptrace.c | 14 +++++++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index c136fd53c847..164e2bbe9afd 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -23,6 +23,7 @@
#include <asm/hwcap.h>
+#define PTRACE_SET_SYSCALL 23
/*
* PSR bits
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 53bdc598d1c1..6ef1e17d9c5b 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1093,7 +1093,19 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
long arch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
- return ptrace_request(child, request, addr, data);
+ int ret;
+
+ switch (request) {
+ case PTRACE_SET_SYSCALL:
+ task_pt_regs(child)->syscallno = data;
+ ret = 0;
+ break;
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+
+ return ret;
}
enum ptrace_syscall_dir {
--
2.18.0

View file

@ -0,0 +1,122 @@
From 5581ff348660d98cfa0348492a0ee89749829460 Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
Date: Thu, 21 Aug 2014 17:56:41 +0900
Subject: [PATCH 12/16] arm64: ptrace: allow tracer to skip a system call
If tracer specifies -1 as a syscall number, this traced system call should
be skipped with a value in x0 used as a return value.
This patch enables this semantics, but there is a restriction here:
when syscall(-1) is issued by user, tracer cannot skip this system call
and modify a return value at syscall entry.
In order to ease this flavor, we need to treat whatever value in x0 as
a return value, but this might result in a bogus value being returned,
especially when tracer doesn't do anything at this syscall.
So we always return ENOSYS instead, while we have another chance to change
a return value at syscall exit.
Please also 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().
* syscallno may also be set to -1 if a fatal signal (SIGKILL) is detected
in tracehook_report_syscall_entry(), but since a value set to x0 (ENOSYS)
is not used in this case, we may neglect the case.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
arch/arm64/include/asm/ptrace.h | 8 ++++++++
arch/arm64/kernel/entry.S | 4 ++++
arch/arm64/kernel/ptrace.c | 20 ++++++++++++++++++++
3 files changed, 32 insertions(+)
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 300a382ed88f..8e4445719e92 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -67,6 +67,14 @@
#define COMPAT_PT_TEXT_ADDR 0x10000
#define COMPAT_PT_DATA_ADDR 0x10004
#define COMPAT_PT_TEXT_END_ADDR 0x10008
+
+/*
+ * used to skip a system call when tracer changes its number to -1
+ * with ptrace(PTRACE_SET_SYSCALL)
+ */
+#define RET_SKIP_SYSCALL -1
+#define IS_SKIP_SYSCALL(no) ((int)(no & 0xffffffff) == -1)
+
#ifndef __ASSEMBLY__
/* sizeof(struct user) for AArch32 */
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index a2cb67872c53..88fc4f84c39a 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -25,6 +25,7 @@
#include <asm/asm-offsets.h>
#include <asm/errno.h>
#include <asm/esr.h>
+#include <asm/ptrace.h>
#include <asm/thread_info.h>
#include <asm/unistd.h>
@@ -627,6 +628,8 @@ ENDPROC(el0_svc)
__sys_trace:
mov x0, sp
bl syscall_trace_enter
+ cmp w0, #RET_SKIP_SYSCALL // skip 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,6 +644,7 @@ __sys_trace:
__sys_trace_return:
str x0, [sp] // save returned x0
+__sys_trace_return_skipped: // x0 already in regs[0]
mov x0, sp
bl syscall_trace_exit
b ret_to_user
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 6ef1e17d9c5b..b29b82576f82 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1137,9 +1137,29 @@ static void tracehook_report_syscall(struct pt_regs *regs,
asmlinkage int syscall_trace_enter(struct pt_regs *regs)
{
+ unsigned int saved_syscallno = regs->syscallno;
+
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+ if (IS_SKIP_SYSCALL(regs->syscallno)) {
+ /*
+ * RESTRICTION: we can't modify a return value of user
+ * issued syscall(-1) here. In order to ease this flavor,
+ * we need to treat whatever value in x0 as a return value,
+ * but this might result in a bogus value being returned.
+ */
+ /*
+ * NOTE: syscallno may also be set to -1 if fatal signal is
+ * detected in tracehook_report_syscall_entry(), but since
+ * a value set to x0 here is not used in this case, we may
+ * neglect the case.
+ */
+ if (!test_thread_flag(TIF_SYSCALL_TRACE) ||
+ (IS_SKIP_SYSCALL(saved_syscallno)))
+ regs->regs[0] = -ENOSYS;
+ }
+
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, regs->syscallno);
--
2.18.0

View file

@ -0,0 +1,55 @@
From b8315a43bf6d555219e1e1f3120ce9a43127f6f2 Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
Date: Thu, 21 Aug 2014 17:56:42 +0900
Subject: [PATCH 13/16] asm-generic: add generic seccomp.h for secure computing
mode 1
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@arndb.de>
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
---
include/asm-generic/seccomp.h | 28 ++++++++++++++++++++++++++++
1 file changed, 28 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..5e9702219646
--- /dev/null
+++ b/include/asm-generic/seccomp.h
@@ -0,0 +1,28 @@
+/*
+ * include/asm-generic/seccomp.h
+ *
+ * Copyright (C) 2014 Linaro Limited
+ * Author: AKASHI Takahiro <takahiro.akashi@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 <asm-generic/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
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#endif /* _ASM_GENERIC_SECCOMP_H */
--
2.18.0

View file

@ -0,0 +1,30 @@
From 62586df3e9ea30c886028731b1c34f21da367b99 Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
Date: Thu, 21 Aug 2014 17:56:43 +0900
Subject: [PATCH 14/16] arm64: add seccomp syscall for compat task
This patch allows compat task to issue seccomp() system call.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
---
arch/arm64/include/asm/unistd32.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index da1f06b535e3..812f19212b23 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -787,7 +787,8 @@ __SYSCALL(__NR_sched_setattr, sys_sched_setattr)
__SYSCALL(__NR_sched_getattr, sys_sched_getattr)
#define __NR_renameat2 382
__SYSCALL(__NR_renameat2, sys_renameat2)
- /* 383 for seccomp */
+#define __NR_seccomp 383
+__SYSCALL(__NR_seccomp, sys_seccomp)
#define __NR_getrandom 384
__SYSCALL(__NR_getrandom, sys_getrandom)
#define __NR_memfd_create 385
--
2.18.0

View file

@ -0,0 +1,56 @@
From ccf3528a3dae6bf48bd83b81068d1e2550b00519 Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
Date: Thu, 21 Aug 2014 17:56:44 +0900
Subject: [PATCH 15/16] arm64: add SIGSYS siginfo for compat task
SIGSYS is primarily used in secure computing to notify tracer.
This patch allows signal handler on compat task to get correct information
with SA_SYSINFO specified when this signal is delivered.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
---
arch/arm64/include/asm/compat.h | 7 +++++++
arch/arm64/kernel/signal32.c | 8 ++++++++
2 files changed, 15 insertions(+)
diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 56de5aadede2..e94e8dde78b4 100644
--- 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 */
+ unsigned int _arch; /* AUDIT_ARCH_* of syscall */
+ } _sigsys;
} _sifields;
} compat_siginfo_t;
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index 327a68c915e2..2b53747bc87f 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -186,6 +186,14 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
err |= __put_user(from->si_uid, &to->si_uid);
err |= __put_user(from->si_int, &to->si_int);
break;
+#ifdef __ARCH_SIGSYS
+ 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;
+#endif
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);
--
2.18.0

View file

@ -0,0 +1,152 @@
From b0654bbead447c3d21f9690ebb1f88cc176510f7 Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
Date: Thu, 21 Aug 2014 17:56:45 +0900
Subject: [PATCH 16/16] arm64: add seccomp support
secure_computing() is called first in syscall_trace_enter() so that a system
call will be aborted quickly without doing succeeding syscall tracing,
contrary to other cases, if seccomp rules 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@linaro.org>
---
arch/arm64/Kconfig | 14 ++++++++++++++
arch/arm64/include/asm/ptrace.h | 1 +
arch/arm64/include/asm/seccomp.h | 25 +++++++++++++++++++++++++
arch/arm64/include/asm/unistd.h | 3 +++
arch/arm64/kernel/entry.S | 2 ++
arch/arm64/kernel/ptrace.c | 5 +++++
6 files changed, 50 insertions(+)
create mode 100644 arch/arm64/include/asm/seccomp.h
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index a3f9d227d179..2d90708b2c8c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -34,6 +34,7 @@ config ARM64
select HAVE_ARCH_AUDITSYSCALL
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
@@ -325,6 +326,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
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 8e4445719e92..e9746486f860 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -73,6 +73,7 @@
* with ptrace(PTRACE_SET_SYSCALL)
*/
#define RET_SKIP_SYSCALL -1
+#define RET_SKIP_SYSCALL_TRACE -2
#define IS_SKIP_SYSCALL(no) ((int)(no & 0xffffffff) == -1)
#ifndef __ASSEMBLY__
diff --git a/arch/arm64/include/asm/seccomp.h b/arch/arm64/include/asm/seccomp.h
new file mode 100644
index 000000000000..c76fac979629
--- /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@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 */
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 6d2bf419431d..49c9aefd24a5 100644
--- 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
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 88fc4f84c39a..3554d6feb7da 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -628,6 +628,8 @@ ENDPROC(el0_svc)
__sys_trace:
mov x0, sp
bl syscall_trace_enter
+ cmp w0, #RET_SKIP_SYSCALL_TRACE // skip syscall and tracing?
+ b.eq ret_to_user
cmp w0, #RET_SKIP_SYSCALL // skip syscall?
b.eq __sys_trace_return_skipped
adr lr, __sys_trace_return // return address
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index b29b82576f82..984efa14d2b0 100644
--- 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>
@@ -1139,6 +1140,10 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
{
unsigned int saved_syscallno = regs->syscallno;
+ /* Do the secure computing check first; failures should be fast. */
+ if (secure_computing(regs->syscallno) == -1)
+ return RET_SKIP_SYSCALL_TRACE;
+
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
--
2.18.0

View file

@ -9,7 +9,7 @@ _srcname=linux-${_commit}
_kernelname=${pkgbase#linux} _kernelname=${pkgbase#linux}
_desc="ODROID-C2" _desc="ODROID-C2"
pkgver=3.16.57 pkgver=3.16.57
pkgrel=1 pkgrel=2
arch=('aarch64') arch=('aarch64')
url="https://github.com/hardkernel/linux/tree/odroidc2-v3.16.y" url="https://github.com/hardkernel/linux/tree/odroidc2-v3.16.y"
license=('GPL2') license=('GPL2')
@ -18,6 +18,21 @@ options=('!strip')
source=("https://github.com/hardkernel/linux/archive/${_commit}.tar.gz" source=("https://github.com/hardkernel/linux/archive/${_commit}.tar.gz"
"git+https://github.com/mdrjr/c2_bootini.git" "git+https://github.com/mdrjr/c2_bootini.git"
'0001-add-extra-errata-843419-build-flags.patch' '0001-add-extra-errata-843419-build-flags.patch'
'0002-arm64-Add-audit-support.patch'
'0003-seccomp-create-internal-mode-setting-function.patch'
'0004-seccomp-extract-check-assign-mode-helpers.patch'
'0005-seccomp-split-mode-setting-routines.patch'
'0006-seccomp-add-seccomp-syscall.patch'
'0007-random-introduce-getrandom-2-system-call.patch'
'0008-Revert-arm64-compat-wire-up-memfd_create-syscall-for.patch'
'0009-arm64-Add-__NR_-definitions-for-compat-syscalls.patch'
'0010-arm64-compat-wire-up-memfd_create-and-getrandom-sysc.patch'
'0011-arm64-ptrace-add-PTRACE_SET_SYSCALL.patch'
'0012-arm64-ptrace-allow-tracer-to-skip-a-system-call.patch'
'0013-asm-generic-add-generic-seccomp.h-for-secure-computi.patch'
'0014-arm64-add-seccomp-syscall-for-compat-task.patch'
'0015-arm64-add-SIGSYS-siginfo-for-compat-task.patch'
'0016-arm64-add-seccomp-support.patch'
'config' 'config'
'linux.preset' 'linux.preset'
'amlogic.service' 'amlogic.service'
@ -25,8 +40,23 @@ source=("https://github.com/hardkernel/linux/archive/${_commit}.tar.gz"
'90-linux.hook') '90-linux.hook')
md5sums=('4ffd9e836370aea16f80e6798b969126' md5sums=('4ffd9e836370aea16f80e6798b969126'
'SKIP' 'SKIP'
'4e11a812de6e7d749103b6a2e6bef301' '56a53a0d56aa3a5ce0216a3290330053'
'9d0b2aafec410a06e3390a1c66800206' '23faa3d2228df60055e6d97e469cda8a'
'76493c97d174f7335a06516f0a24963b'
'4b822e81df5b1fe73fdb41c9852acfcb'
'9c8ae0d353008865492127314f3d08c7'
'3917a53be38bc28bd0acb16e6b708cf2'
'9b7eaba53b7818755905520ecea48453'
'4c304791ebe3a6161607031b641d49cf'
'd2df633f89b8e71d7d26333d70402d48'
'3baef2320266f060500de675b244948d'
'1b2cb9b6b817ca7e4854505248377197'
'250a0171b48c8e8b36667b211b3e6658'
'18675fe029a96d5c6191c5253a1ec1a5'
'b575d1884647589eae89d7736d990744'
'00e5ddbaaac55e40a700c51a6756b8de'
'cf59798a64257ce44c8b928e1abf4db2'
'ea5d396fa0db628eb305eb15a72b64dc'
'86d4a35722b5410e3b29fc92dae15d4b' '86d4a35722b5410e3b29fc92dae15d4b'
'b8956789318f49cec5b8bb0b41654a9b' 'b8956789318f49cec5b8bb0b41654a9b'
'ce6c81ad1ad1f8b333fd6077d47abdaf' 'ce6c81ad1ad1f8b333fd6077d47abdaf'
@ -43,7 +73,22 @@ prepare() {
# don't run depmod on 'make install'. We'll do this ourselves in packaging # don't run depmod on 'make install'. We'll do this ourselves in packaging
sed -i '2iexit 0' scripts/depmod.sh sed -i '2iexit 0' scripts/depmod.sh
patch -p1 -i ../0001-add-extra-errata-843419-build-flags.patch git apply ../0001-add-extra-errata-843419-build-flags.patch
git apply ../0002-arm64-Add-audit-support.patch
git apply ../0003-seccomp-create-internal-mode-setting-function.patch
git apply ../0004-seccomp-extract-check-assign-mode-helpers.patch
git apply ../0005-seccomp-split-mode-setting-routines.patch
git apply ../0006-seccomp-add-seccomp-syscall.patch
git apply ../0007-random-introduce-getrandom-2-system-call.patch
git apply ../0008-Revert-arm64-compat-wire-up-memfd_create-syscall-for.patch
git apply ../0009-arm64-Add-__NR_-definitions-for-compat-syscalls.patch
git apply ../0010-arm64-compat-wire-up-memfd_create-and-getrandom-sysc.patch
git apply ../0011-arm64-ptrace-add-PTRACE_SET_SYSCALL.patch
git apply ../0012-arm64-ptrace-allow-tracer-to-skip-a-system-call.patch
git apply ../0013-asm-generic-add-generic-seccomp.h-for-secure-computi.patch
git apply ../0014-arm64-add-seccomp-syscall-for-compat-task.patch
git apply ../0015-arm64-add-SIGSYS-siginfo-for-compat-task.patch
git apply ../0016-arm64-add-seccomp-support.patch
} }
build() { build() {

View file

@ -1,6 +1,6 @@
# #
# Automatically generated file; DO NOT EDIT. # Automatically generated file; DO NOT EDIT.
# Linux/arm64 3.16.57-1 Kernel Configuration # Linux/arm64 3.16.57-2 Kernel Configuration
# #
CONFIG_ARM64=y CONFIG_ARM64=y
CONFIG_ARM64_HAS_SG_CHAIN=y CONFIG_ARM64_HAS_SG_CHAIN=y
@ -45,6 +45,8 @@ CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_FHANDLE=y CONFIG_FHANDLE=y
CONFIG_USELIB=y CONFIG_USELIB=y
CONFIG_AUDIT=y CONFIG_AUDIT=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
# CONFIG_AUDITSYSCALL is not set
# #
# IRQ subsystem # IRQ subsystem
@ -195,6 +197,8 @@ CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_SECCOMP_FILTER=y
# CONFIG_CC_STACKPROTECTOR is not set # CONFIG_CC_STACKPROTECTOR is not set
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
@ -342,6 +346,7 @@ CONFIG_CMA_AREAS=7
CONFIG_ZSMALLOC=y CONFIG_ZSMALLOC=y
# CONFIG_PGTABLE_MAPPING is not set # CONFIG_PGTABLE_MAPPING is not set
CONFIG_GENERIC_EARLY_IOREMAP=y CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_SECCOMP=y
# CONFIG_XEN is not set # CONFIG_XEN is not set
CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_FORCE_MAX_ZONEORDER=11
@ -4610,7 +4615,7 @@ CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_USER=m
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
CONFIG_CRYPTO_GF128MUL=m CONFIG_CRYPTO_GF128MUL=m
# CONFIG_CRYPTO_NULL is not set CONFIG_CRYPTO_NULL=m
# CONFIG_CRYPTO_PCRYPT is not set # CONFIG_CRYPTO_PCRYPT is not set
CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=y CONFIG_CRYPTO_CRYPTD=y
@ -4622,7 +4627,7 @@ CONFIG_CRYPTO_ABLK_HELPER=y
# Authenticated Encryption with Associated Data # Authenticated Encryption with Associated Data
# #
CONFIG_CRYPTO_CCM=y CONFIG_CRYPTO_CCM=y
# CONFIG_CRYPTO_GCM is not set CONFIG_CRYPTO_GCM=m
CONFIG_CRYPTO_SEQIV=y CONFIG_CRYPTO_SEQIV=y
# #
@ -4650,7 +4655,7 @@ CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_CRC32 is not set # CONFIG_CRYPTO_CRC32 is not set
CONFIG_CRYPTO_CRCT10DIF=y CONFIG_CRYPTO_CRCT10DIF=y
# CONFIG_CRYPTO_GHASH is not set CONFIG_CRYPTO_GHASH=m
CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_MICHAEL_MIC=m
@ -4740,7 +4745,8 @@ CONFIG_CRC7=y
CONFIG_LIBCRC32C=y CONFIG_LIBCRC32C=y
# CONFIG_CRC8 is not set # CONFIG_CRC8 is not set
CONFIG_AUDIT_GENERIC=y CONFIG_AUDIT_GENERIC=y
# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
CONFIG_AUDIT_COMPAT_GENERIC=y
# CONFIG_RANDOM32_SELFTEST is not set # CONFIG_RANDOM32_SELFTEST is not set
CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y CONFIG_ZLIB_DEFLATE=y