Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH 2/2] arm64: is_compat_task is defined both in asm/compat.h and linux/compat.h

49 views
Skip to first unread message

AKASHI Takahiro

unread,
Feb 7, 2014, 5:20:02 AM2/7/14
to
kernel/seccomp.c includes linux/compat.h and, indicrectly, asm/compat.h
via asm/syscall.h. Due to the duplicated definition of is_compat_task,
compiling this file will fail in the case of !CONFIG_COMPAT.
This patch makes the definition in asm/compat.h valid only if necessary.

Signed-off-by: AKASHI Takahiro <takahir...@linaro.org>
---
arch/arm64/include/asm/compat.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index fda2704..72f3b18 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -305,10 +305,12 @@ static inline int is_compat_thread(struct thread_info *thread)

#else /* !CONFIG_COMPAT */

+#ifndef is_compat_task /* it's there in linux/compat.h */
static inline int is_compat_task(void)
{
return 0;
}
+#endif

static inline int is_compat_thread(struct thread_info *thread)
{
--
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

AKASHI Takahiro

unread,
Feb 7, 2014, 5:20:02 AM2/7/14
to
secure_computing() should always be called first in syscall_trace(), and
if it returns non-zero, we should stop further handling. Then that system
call may eventually fail, be trapped or the process itself be killed
depending on loaded rules.

This patch also defines specific system call numbers, __NR_seccomp_*,
solely used by secure_computing() for seccomp mode 1 (only read, write, exit
and sigreturn are allowd).

Signed-off-by: AKASHI Takahiro <takahir...@linaro.org>
---
arch/arm64/Kconfig | 17 +++++++++++++++++
arch/arm64/include/asm/seccomp.h | 28 ++++++++++++++++++++++++++++
arch/arm64/include/asm/unistd.h | 3 +++
arch/arm64/kernel/entry.S | 4 ++++
arch/arm64/kernel/ptrace.c | 5 +++++
5 files changed, 57 insertions(+)
create mode 100644 arch/arm64/include/asm/seccomp.h

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index a21455e..a0102f7 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -27,6 +27,7 @@ config ARM64
select HARDIRQS_SW_RESEND
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
+ select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_DEBUG_BUGVERBOSE
select HAVE_DEBUG_KMEMLEAK
@@ -222,6 +223,22 @@ config HAVE_ARCH_TRANSPARENT_HUGEPAGE

source "mm/Kconfig"

+config SECCOMP
+ def_bool y
+ prompt "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.
+
+ If unsure, say Y. Only embedded should say N here.
+
config XEN_DOM0
def_bool y
depends on XEN
diff --git a/arch/arm64/include/asm/seccomp.h b/arch/arm64/include/asm/seccomp.h
new file mode 100644
index 0000000..3482155
--- /dev/null
+++ b/arch/arm64/include/asm/seccomp.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm64/include/asm/seccomp.h
+ *
+ * Copyright (C) 2014 Linaro Limited
+ * Author: AKASHI Takahiro <takahir...@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_sigreturn
+#endif /* CONFIG_COMPAT */
+
+#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_SECCOMP_H */
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 4a09fdb..05f2db3 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -30,6 +30,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 96c2d03..55d4e6c 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -651,6 +651,10 @@ __sys_trace:
mov x1, sp
mov w0, #0 // trace entry
bl syscall_trace
+#ifdef CONFIG_SECCOMP
+ cmp w0, #0 // check seccomp result
+ b.lt ret_to_user // -1 means 'rejected'
+#endif
adr lr, __sys_trace_return // return address
uxtw scno, w0 // syscall number (possibly new)
mov x1, sp // pointer to regs
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 8cdba09..3bfe398 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>
@@ -1064,6 +1065,10 @@ asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
{
unsigned long saved_reg;

+ if (!dir && secure_computing((int)regs->syscallno))
+ /* seccomp failures shouldn't expose any additional code. */
+ return -1;
+
if (is_compat_task()) {
/* AArch32 uses ip (r12) for scratch */
saved_reg = regs->regs[12];

AKASHI Takahiro

unread,
Feb 7, 2014, 5:20:03 AM2/7/14
to
This patch enables secure computing (system call filtering) on arm64.
System calls can be allowed or denied by loaded bpf-style rules.
Architecture specific part is to run secure_computing() on syscall entry
and check the result. See [1/2]

Prerequisites are:
* "arm64: Add audit support" patch
* "arm64: make a single hook to syscall_trace() for all syscall features" patch

This code is tested on ARMv8 fast model using libseccomp v2.1.1 with
modifications for arm64 and verified by its "live" tests, 20, 21 and 24.

AKASHI Takahiro (2):
arm64: Add seccomp support
arm64: is_compat_task is defined both in asm/compat.h and
linux/compat.h

arch/arm64/Kconfig | 17 +++++++++++++++++
arch/arm64/include/asm/compat.h | 2 ++
arch/arm64/include/asm/seccomp.h | 28 ++++++++++++++++++++++++++++
arch/arm64/include/asm/unistd.h | 3 +++
arch/arm64/kernel/entry.S | 4 ++++
arch/arm64/kernel/ptrace.c | 5 +++++
6 files changed, 59 insertions(+)
create mode 100644 arch/arm64/include/asm/seccomp.h

Arnd Bergmann

unread,
Feb 7, 2014, 9:50:03 AM2/7/14
to
This file looks extremely generic and can be shared by every
architecture other than MIPS for all I can tell.

Please add it to include/asm-generic instead of arch/arm64,
and add a line to arch/arm64/include/asm/Kbuild.

Arnd

Arnd Bergmann

unread,
Feb 12, 2014, 6:10:03 AM2/12/14
to
On Wednesday 12 February 2014, Takahiro Akashi wrote:
> Thank you for your comment.
> I'm afraid that I can't do so because how compat syscall numbers
> are named varies from arch to arch. __NR_compat_read is used
> only on arm64, while __NR_ia32_read on x86. On other archs,
> __NR_read is common to 32-bit and 64-bit tasks.

It's fine, I'm the maintainer for asm-generic ;-)

All future architectures are required to do it the same way as
arm64 and use the generic syscall ABI. It just means we won't be
able to share this header with x86 or other architectures that
use a nonstandard string. We should have it in the generic place
even if arm64 is the only user for now.

Arnd Bergmann

unread,
Feb 12, 2014, 6:20:01 AM2/12/14
to
On Wednesday 12 February 2014, Arnd Bergmann wrote:
>
> On Wednesday 12 February 2014, Takahiro Akashi wrote:
> > Thank you for your comment.
> > I'm afraid that I can't do so because how compat syscall numbers
> > are named varies from arch to arch. __NR_compat_read is used
> > only on arm64, while __NR_ia32_read on x86. On other archs,
> > __NR_read is common to 32-bit and 64-bit tasks.
>
> It's fine, I'm the maintainer for asm-generic ;-)
>
> All future architectures are required to do it the same way as
> arm64 and use the generic syscall ABI. It just means we won't be
> able to share this header with x86 or other architectures that
> use a nonstandard string. We should have it in the generic place
> even if arm64 is the only user for now.
>

Ok, I was wrong. The generic header file should only be used for
architectures on which both ABIs use the generic syscall numbers,
and arm64 obviously doesn't do that for arm32 compatibility.

The proper generic header file should contain

#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

and then have arm64 override the first four by defining its
own. I would still prefer having it done this way, but it actually
doesn't gain us that much since this default wouldn't work on
any 64-bit architecture currently implementing seccomp. I'll leave
it up to you whether you want to do it or not.

Will Deacon

unread,
Feb 17, 2014, 2:40:01 PM2/17/14
to
On Fri, Feb 07, 2014 at 10:11:32AM +0000, AKASHI Takahiro wrote:
> kernel/seccomp.c includes linux/compat.h and, indicrectly, asm/compat.h
> via asm/syscall.h. Due to the duplicated definition of is_compat_task,
> compiling this file will fail in the case of !CONFIG_COMPAT.
> This patch makes the definition in asm/compat.h valid only if necessary.
>
> Signed-off-by: AKASHI Takahiro <takahir...@linaro.org>
> ---
> arch/arm64/include/asm/compat.h | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> index fda2704..72f3b18 100644
> --- a/arch/arm64/include/asm/compat.h
> +++ b/arch/arm64/include/asm/compat.h
> @@ -305,10 +305,12 @@ static inline int is_compat_thread(struct thread_info *thread)
>
> #else /* !CONFIG_COMPAT */
>
> +#ifndef is_compat_task /* it's there in linux/compat.h */
> static inline int is_compat_task(void)
> {
> return 0;
> }
> +#endif

This is horrible! Can we instead include linux/compat.h where we need this
macro and then remove this definition?

Will

Catalin Marinas

unread,
Feb 18, 2014, 10:40:03 AM2/18/14
to
On Fri, Feb 07, 2014 at 10:11:31AM +0000, AKASHI Takahiro wrote:
> --- 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>
> @@ -1064,6 +1065,10 @@ asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
> {
> unsigned long saved_reg;
>
> + if (!dir && secure_computing((int)regs->syscallno))
> + /* seccomp failures shouldn't expose any additional code. */
> + return -1;

That's only restricted to the arm64 code but could we use a more
meaningful error number?

--
Catalin

AKASHI Takahiro

unread,
Feb 19, 2014, 6:20:01 AM2/19/14
to
On 02/18/2014 04:32 AM, Will Deacon wrote:
> On Fri, Feb 07, 2014 at 10:11:32AM +0000, AKASHI Takahiro wrote:
>> kernel/seccomp.c includes linux/compat.h and, indicrectly, asm/compat.h
>> via asm/syscall.h. Due to the duplicated definition of is_compat_task,
>> compiling this file will fail in the case of !CONFIG_COMPAT.
>> This patch makes the definition in asm/compat.h valid only if necessary.
>>
>> Signed-off-by: AKASHI Takahiro <takahir...@linaro.org>
>> ---
>> arch/arm64/include/asm/compat.h | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
>> index fda2704..72f3b18 100644
>> --- a/arch/arm64/include/asm/compat.h
>> +++ b/arch/arm64/include/asm/compat.h
>> @@ -305,10 +305,12 @@ static inline int is_compat_thread(struct thread_info *thread)
>>
>> #else /* !CONFIG_COMPAT */
>>
>> +#ifndef is_compat_task /* it's there in linux/compat.h */
>> static inline int is_compat_task(void)
>> {
>> return 0;
>> }
>> +#endif
>
> This is horrible! Can we instead include linux/compat.h where we need this
> macro and then remove this definition?

It's fine with me, but asm/compat.h is also included in
hw_breakpoint.c, process.c, ptrace.c and signal.c.

After replacing asm/compat.h to linux/compat.h in these files, I could successfully built
the kernel, but I can't guarantee that the kernel works without any problem :-)

Anyway I will go forward with this change.

-Takahiro AKASHI

AKASHI Takahiro

unread,
Feb 19, 2014, 6:40:01 AM2/19/14
to
On 02/19/2014 12:38 AM, Catalin Marinas wrote:
> On Fri, Feb 07, 2014 at 10:11:31AM +0000, AKASHI Takahiro wrote:
>> --- 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>
>> @@ -1064,6 +1065,10 @@ asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
>> {
>> unsigned long saved_reg;
>>
>> + if (!dir && secure_computing((int)regs->syscallno))
>> + /* seccomp failures shouldn't expose any additional code. */
>> + return -1;
>
> That's only restricted to the arm64 code but could we use a more
> meaningful error number?

Other architectures, including arm, also return just -1 in syscall_trace_enter(),
but of course, we can use another value, say, -EPERM or -ENOSYS?

-Takahiro AKASHI

Catalin Marinas

unread,
Feb 19, 2014, 11:50:02 AM2/19/14
to
On Wed, Feb 19, 2014 at 11:39:09AM +0000, AKASHI Takahiro wrote:
> On 02/19/2014 12:38 AM, Catalin Marinas wrote:
> > On Fri, Feb 07, 2014 at 10:11:31AM +0000, AKASHI Takahiro wrote:
> >> --- 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>
> >> @@ -1064,6 +1065,10 @@ asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
> >> {
> >> unsigned long saved_reg;
> >>
> >> + if (!dir && secure_computing((int)regs->syscallno))
> >> + /* seccomp failures shouldn't expose any additional code. */
> >> + return -1;
> >
> > That's only restricted to the arm64 code but could we use a more
> > meaningful error number?
>
> Other architectures, including arm, also return just -1 in syscall_trace_enter(),
> but of course, we can use another value, say, -EPERM or -ENOSYS?

Actually we have another case of setting regs->syscallno = ~0UL in the
same function, so we could do the same (also in line with entry.S).

--
Catalin

AKASHI Takahiro

unread,
Feb 19, 2014, 7:40:02 PM2/19/14
to
I believe that I got you now, but we need to distinguish failure case of
seccomp and the existing (~0UL) case. In former case, depending on a bpf
rule loaded into the kernel, errno may be assigned to any arbitrary number
(not necessarily ENOSYS).
So I will use another value for this specific seccomp case.

Thanks,
-Takahiro AKASHI

AKASHI Takahiro

unread,
Feb 25, 2014, 4:30:03 AM2/25/14
to
This patch enables secure computing (system call filtering) on arm64.
System calls can be allowed or denied by loaded bpf-style rules.
Architecture specific part is to run secure_computing() on syscall entry
and check the result. See [2/3]

Prerequisites are:
* "arm64: Add audit support" patch
* "arm64: make a single hook to syscall_trace() for all syscall features" patch

This code is tested on ARMv8 fast model using libseccomp v2.1.1 with
modifications for arm64 and verified by its "live" tests, 20, 21 and 24.

Changes v1 -> v2:
* added generic seccomp.h for arm64 to utilize it [1,2/3]
* changed syscall_trace() to return more meaningful value (-EPERM)
on seccomp failure case [2/3]
* aligned with the change in "arm64: make a single hook to syscall_trace()
for all syscall features" v2 [2/3]
* removed is_compat_task() definition from compat.h [3/3]

AKASHI Takahiro (3):
asm-generic: Add generic seccomp.h for secure computing mode 1
arm64: Add seccomp support
arm64: is_compat_task is defined both in asm/compat.h and
linux/compat.h

arch/arm64/Kconfig | 17 +++++++++++++++++
arch/arm64/include/asm/compat.h | 5 -----
arch/arm64/include/asm/seccomp.h | 25 +++++++++++++++++++++++++
arch/arm64/include/asm/unistd.h | 3 +++
arch/arm64/kernel/entry.S | 4 ++++
arch/arm64/kernel/hw_breakpoint.c | 2 +-
arch/arm64/kernel/process.c | 2 +-
arch/arm64/kernel/ptrace.c | 8 +++++++-
arch/arm64/kernel/signal.c | 2 +-
include/asm-generic/seccomp.h | 28 ++++++++++++++++++++++++++++
10 files changed, 87 insertions(+), 9 deletions(-)
create mode 100644 arch/arm64/include/asm/seccomp.h
create mode 100644 include/asm-generic/seccomp.h

AKASHI Takahiro

unread,
Feb 25, 2014, 4:30:02 AM2/25/14
to
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.

Signed-off-by: AKASHI Takahiro <takahir...@linaro.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 0000000..5e97022
--- /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 <takahir...@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 */

AKASHI Takahiro

unread,
Feb 25, 2014, 4:30:03 AM2/25/14
to
secure_computing() should always be called first in syscall_trace(), and
if it returns non-zero, we should stop further handling. Then that system
call may eventually fail, be trapped or the process itself be killed
depending on loaded rules.

Signed-off-by: AKASHI Takahiro <takahir...@linaro.org>
---
arch/arm64/Kconfig | 17 +++++++++++++++++
arch/arm64/include/asm/seccomp.h | 25 +++++++++++++++++++++++++
arch/arm64/include/asm/unistd.h | 3 +++
arch/arm64/kernel/entry.S | 4 ++++
arch/arm64/kernel/ptrace.c | 6 ++++++
5 files changed, 55 insertions(+)
create mode 100644 arch/arm64/include/asm/seccomp.h
new file mode 100644
index 0000000..c76fac9
--- /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 <takahir...@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 4a09fdb..05f2db3 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -30,6 +30,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 96c2d03..7f3cbaf 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -651,6 +651,10 @@ __sys_trace:
mov x1, sp
mov w0, #0 // trace entry
bl syscall_trace
+#ifdef CONFIG_SECCOMP
+ cmp w0, #-EPERM // check seccomp result
+ b.eq ret_to_user // -EPERM means 'rejected'
+#endif
adr lr, __sys_trace_return // return address
uxtw scno, w0 // syscall number (possibly new)
mov x1, sp // pointer to regs
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index d4ce70e..f2a74bc 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -20,12 +20,14 @@
*/

#include <linux/audit.h>
+#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#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>
@@ -1064,6 +1066,10 @@ asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
{
unsigned long saved_reg;

+ if (!dir && secure_computing((int)regs->syscallno))
+ /* seccomp failures shouldn't expose any additional code. */
+ return -EPERM;
+
if (dir && test_thread_flag(TIF_SYSCALL_AUDIT))
audit_syscall_exit(regs);

AKASHI Takahiro

unread,
Feb 25, 2014, 4:30:03 AM2/25/14
to
kernel/seccomp.c includes linux/compat.h and, indicrectly, asm/compat.h
via asm/syscall.h. Due to the duplicated definitions of is_compat_task,
compiling this file will fail in the case of !CONFIG_COMPAT.
So this patch
1) removes is_compat_task() definition from asm/compat.h
2) replaces asm/compat.h to linux/compat.h in kernel/*.c

Signed-off-by: AKASHI Takahiro <takahir...@linaro.org>
---
arch/arm64/include/asm/compat.h | 5 -----
arch/arm64/kernel/hw_breakpoint.c | 2 +-
arch/arm64/kernel/process.c | 2 +-
arch/arm64/kernel/ptrace.c | 2 +-
arch/arm64/kernel/signal.c | 2 +-
5 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index fda2704..3b334f9 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -305,11 +305,6 @@ static inline int is_compat_thread(struct thread_info *thread)

#else /* !CONFIG_COMPAT */

-static inline int is_compat_task(void)
-{
- return 0;
-}
-
static inline int is_compat_thread(struct thread_info *thread)
{
return 0;
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index f17f581..a45e2db 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -20,6 +20,7 @@

#define pr_fmt(fmt) "hw-breakpoint: " fmt

+#include <linux/compat.h>
#include <linux/cpu_pm.h>
#include <linux/errno.h>
#include <linux/hw_breakpoint.h>
@@ -27,7 +28,6 @@
#include <linux/ptrace.h>
#include <linux/smp.h>

-#include <asm/compat.h>
#include <asm/current.h>
#include <asm/debug-monitors.h>
#include <asm/hw_breakpoint.h>
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 248a15d..c3805b6 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -20,6 +20,7 @@

#include <stdarg.h>

+#include <linux/compat.h>
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -44,7 +45,6 @@
#include <linux/personality.h>
#include <linux/notifier.h>

-#include <asm/compat.h>
#include <asm/cacheflush.h>
#include <asm/fpsimd.h>
#include <asm/mmu_context.h>
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index f2a74bc..340d51f 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -20,6 +20,7 @@
*/

#include <linux/audit.h>
+#include <linux/compat.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -38,7 +39,6 @@
#include <linux/tracehook.h>
#include <linux/elf.h>

-#include <asm/compat.h>
#include <asm/debug-monitors.h>
#include <asm/pgtable.h>
#include <asm/syscall.h>
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 890a591..4a09989 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

+#include <linux/compat.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/personality.h>
@@ -25,7 +26,6 @@
#include <linux/tracehook.h>
#include <linux/ratelimit.h>

-#include <asm/compat.h>
#include <asm/debug-monitors.h>
#include <asm/elf.h>
#include <asm/cacheflush.h>

Will Deacon

unread,
Feb 28, 2014, 12:00:02 PM2/28/14
to
On Tue, Feb 25, 2014 at 09:20:25AM +0000, AKASHI Takahiro wrote:
> kernel/seccomp.c includes linux/compat.h and, indicrectly, asm/compat.h
> via asm/syscall.h. Due to the duplicated definitions of is_compat_task,
> compiling this file will fail in the case of !CONFIG_COMPAT.
> So this patch
> 1) removes is_compat_task() definition from asm/compat.h
> 2) replaces asm/compat.h to linux/compat.h in kernel/*.c
>
> Signed-off-by: AKASHI Takahiro <takahir...@linaro.org>
> ---

You built this, right? If so,

Acked-by: Will Deacon <will....@arm.com>

Will

Will Deacon

unread,
Feb 28, 2014, 12:30:02 PM2/28/14
to
On Tue, Feb 25, 2014 at 09:20:24AM +0000, AKASHI Takahiro wrote:
> secure_computing() should always be called first in syscall_trace(), and
> if it returns non-zero, we should stop further handling. Then that system
> call may eventually fail, be trapped or the process itself be killed
> depending on loaded rules.

[...]

> diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
> index d4ce70e..f2a74bc 100644
> --- a/arch/arm64/kernel/ptrace.c
> +++ b/arch/arm64/kernel/ptrace.c
> @@ -20,12 +20,14 @@
> */
>
> #include <linux/audit.h>
> +#include <linux/errno.h>
> #include <linux/kernel.h>
> #include <linux/sched.h>
> #include <linux/mm.h>
> #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>
> @@ -1064,6 +1066,10 @@ asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
> {
> unsigned long saved_reg;
>
> + if (!dir && secure_computing((int)regs->syscallno))

Why do you need this cast to (int)? Also, it's probably better to check for
-1 explicitly here.

I'm slightly surprised that we do the secure computing check first. Doesn't
this allow a debugger to change the syscall to something else after we've
decided that it's ok?

Will

AKASHI Takahiro

unread,
Mar 5, 2014, 9:40:01 PM3/5/14
to
OK. I will remove it because gcc doesn't complain about it anyway.

> Also, it's probably better to check for
> -1 explicitly here.

I wil fix it.

> I'm slightly surprised that we do the secure computing check first. Doesn't
> this allow a debugger to change the syscall to something else after we've
> decided that it's ok?

To be honest, I just followed other architectures' implementation.
Can you elaborate any use case that you have in your mind?

-Takahiro AKASHI

Will Deacon

unread,
Mar 6, 2014, 10:30:01 AM3/6/14
to
On Thu, Mar 06, 2014 at 02:34:46AM +0000, AKASHI Takahiro wrote:
> On 03/01/2014 02:20 AM, Will Deacon wrote:
> > On Tue, Feb 25, 2014 at 09:20:24AM +0000, AKASHI Takahiro wrote:
> > I'm slightly surprised that we do the secure computing check first. Doesn't
> > this allow a debugger to change the syscall to something else after we've
> > decided that it's ok?
>
> To be honest, I just followed other architectures' implementation.
> Can you elaborate any use case that you have in your mind?

My initial thought was that we should do the secure_computing check *after*
the debugger has finished messing around with the registers. However, I
suppose you'd have had to enable ptrace in your seccompd filter for that
scenario to occur, so there's probably not an issue here after all.

AKASHI Takahiro

unread,
Mar 13, 2014, 6:20:03 AM3/13/14
to
kernel/seccomp.c includes linux/compat.h and, indicrectly, asm/compat.h
via asm/syscall.h. Due to the duplicated definitions of is_compat_task,
compiling this file will fail in the case of !CONFIG_COMPAT.
So this patch
1) removes is_compat_task() definition from asm/compat.h
2) replaces asm/compat.h to linux/compat.h in kernel/*.c

Signed-off-by: AKASHI Takahiro <takahir...@linaro.org>
---
arch/arm64/include/asm/compat.h | 5 -----
arch/arm64/kernel/hw_breakpoint.c | 2 +-
arch/arm64/kernel/process.c | 2 +-
index 1c0a9be..02eefc6 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -20,6 +20,7 @@

#include <stdarg.h>

+#include <linux/compat.h>
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -44,7 +45,6 @@
#include <linux/personality.h>
#include <linux/notifier.h>

-#include <asm/compat.h>
#include <asm/cacheflush.h>
#include <asm/fpsimd.h>
#include <asm/mmu_context.h>
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index be2bb4c..674bae2 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -20,6 +20,7 @@
*/

#include <linux/audit.h>
+#include <linux/compat.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>

AKASHI Takahiro

unread,
Mar 13, 2014, 6:20:03 AM3/13/14
to
secure_computing() should always be called first in syscall_trace_enter().
If it returns non-zero, we should stop further handling. Then that system
call may eventually fail, be trapped or the process itself be killed
depending on loaded rules.
In this case, syscall_trace_enter() returns a dedicated value in order to
skip a normal syscall table lookup because a seccomp rule may have already
overridden errno.

Signed-off-by: AKASHI Takahiro <takahir...@linaro.org>
---
arch/arm64/Kconfig | 14 ++++++++++++++
arch/arm64/include/asm/seccomp.h | 25 +++++++++++++++++++++++++
arch/arm64/include/asm/unistd.h | 3 +++
arch/arm64/kernel/entry.S | 4 ++++
arch/arm64/kernel/ptrace.c | 6 ++++++
5 files changed, 52 insertions(+)
create mode 100644 arch/arm64/include/asm/seccomp.h

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7ca6799..21b33f4 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -27,6 +27,7 @@ config ARM64
select HARDIRQS_SW_RESEND
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
+ select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_C_RECORDMCOUNT
select HAVE_DEBUG_BUGVERBOSE
@@ -229,6 +230,19 @@ config HAVE_ARCH_TRANSPARENT_HUGEPAGE

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.
+
index 04f5d22..28bf882 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -30,6 +30,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 f06ee35..6ef266a 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -650,6 +650,10 @@ ENDPROC(el0_svc)
__sys_trace:
mov x0, sp
bl syscall_trace_enter
+#ifdef CONFIG_SECCOMP
+ cmp w0, #-EPERM // check seccomp result
+ b.eq ret_to_user // -EPERM means 'rejected'
+#endif
adr lr, __sys_trace_return // return address
uxtw scno, w0 // syscall number (possibly new)
mov x1, sp // pointer to regs
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index d10c637..be2bb4c 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -20,12 +20,14 @@
*/

#include <linux/audit.h>
+#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#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>
@@ -1067,6 +1069,10 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
{
unsigned long saved_reg;

+ if (secure_computing(regs->syscallno) == -1)
+ /* seccomp failures shouldn't expose any additional code. */
+ return -EPERM;
+
if (test_thread_flag(TIF_SYSCALL_TRACE)) {
/*
* A scrach register (ip(r12) on AArch32, x7 on AArch64) is

AKASHI Takahiro

unread,
Mar 13, 2014, 6:20:04 AM3/13/14
to
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.

Signed-off-by: AKASHI Takahiro <takahir...@linaro.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 0000000..5e97022
--- /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 <takahir...@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 */

AKASHI Takahiro

unread,
Mar 13, 2014, 6:20:05 AM3/13/14
to
(Please apply this patch after my ftrace patch and audit patch in order
to avoid some conflict on arm64/Kconfig.)

This patch enables secure computing (system call filtering) on arm64.
System calls can be allowed or denied by loaded bpf-style rules.
Architecture specific part is to run secure_computing() on syscall entry
and check the result. See [2/3]

Prerequisites are:
* "arm64: make a single hook to syscall_trace() for all syscall features" patch
* "arm64: split syscall_trace() into separate functions for enter/exit" patch
* "arm64: Add audit support" patch

This code is tested on ARMv8 fast model using libseccomp v2.1.1 with
modifications for arm64 and verified by its "live" tests, 20, 21 and 24.

Changes v2 -> v3:
* removed unnecessary 'type cast' operations [2/3]
* check for a return value (-1) of secure_computing() explicitly [2/3]
* aligned with the patch, "arm64: split syscall_trace() into separate
functions for enter/exit" [2/3]
* changed default of CONFIG_SECCOMP to n [2/3]

Changes v1 -> v2:
* added generic seccomp.h for arm64 to utilize it [1,2/3]
* changed syscall_trace() to return more meaningful value (-EPERM)
on seccomp failure case [2/3]
* aligned with the change in "arm64: make a single hook to syscall_trace()
for all syscall features" v2 [2/3]
* removed is_compat_task() definition from compat.h [3/3]

AKASHI Takahiro (3):
asm-generic: Add generic seccomp.h for secure computing mode 1
arm64: Add seccomp support
arm64: is_compat_task is defined both in asm/compat.h and
linux/compat.h

arch/arm64/Kconfig | 14 ++++++++++++++
arch/arm64/include/asm/compat.h | 5 -----
arch/arm64/include/asm/seccomp.h | 25 +++++++++++++++++++++++++
arch/arm64/include/asm/unistd.h | 3 +++
arch/arm64/kernel/entry.S | 4 ++++
arch/arm64/kernel/hw_breakpoint.c | 2 +-
arch/arm64/kernel/process.c | 2 +-
arch/arm64/kernel/ptrace.c | 8 +++++++-
arch/arm64/kernel/signal.c | 2 +-
include/asm-generic/seccomp.h | 28 ++++++++++++++++++++++++++++
10 files changed, 84 insertions(+), 9 deletions(-)

Catalin Marinas

unread,
Mar 14, 2014, 1:10:03 PM3/14/14
to
On Thu, Mar 13, 2014 at 10:17:01AM +0000, AKASHI Takahiro wrote:
> 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.
>
> Signed-off-by: AKASHI Takahiro <takahir...@linaro.org>
> ---
> include/asm-generic/seccomp.h | 28 ++++++++++++++++++++++++++++
> 1 file changed, 28 insertions(+)
> create mode 100644 include/asm-generic/seccomp.h

I think you need an Ack from Arnd on this patch. The other patches in
this series look ok but they depend on the ftrace patches, so we'll have
to sort those out first.

--
Catalin

AKASHI Takahiro

unread,
Mar 15, 2014, 2:00:01 AM3/15/14
to
secure_computing() should always be called first in syscall_trace_enter().
If it returns non-zero, we should stop further handling. Then that system
call may eventually fail, be trapped or the process itself be killed
depending on loaded rules.
In this case, syscall_trace_enter() returns a dedicated value in order to
skip a normal syscall table lookup because a seccomp rule may have already
overridden errno.

Signed-off-by: AKASHI Takahiro <takahir...@linaro.org>
---
arch/arm64/Kconfig | 14 ++++++++++++++
arch/arm64/include/asm/seccomp.h | 25 +++++++++++++++++++++++++
arch/arm64/include/asm/unistd.h | 3 +++
arch/arm64/kernel/entry.S | 4 ++++
arch/arm64/kernel/ptrace.c | 6 ++++++
5 files changed, 52 insertions(+)
create mode 100644 arch/arm64/include/asm/seccomp.h

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7c1f8c7..d5167d6 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -28,6 +28,7 @@ config ARM64
select HARDIRQS_SW_RESEND
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
+ select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_C_RECORDMCOUNT
select HAVE_DEBUG_BUGVERBOSE
@@ -230,6 +231,19 @@ config HAVE_ARCH_TRANSPARENT_HUGEPAGE

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/seccomp.h b/arch/arm64/include/asm/seccomp.h
new file mode 100644
index 0000000..c76fac9
--- /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 <takahir...@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.
+ */
index f9e1339..bb89fa3 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -21,12 +21,14 @@

#include <linux/audit.h>
#include <linux/compat.h>
+#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#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>
@@ -1093,6 +1095,10 @@ static void tracehook_report_syscall(struct pt_regs *regs,

asmlinkage int syscall_trace_enter(struct pt_regs *regs)
{
+ if (secure_computing(regs->syscallno) == -1)
+ /* seccomp failures shouldn't expose any additional code. */
+ return -EPERM;
+
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);

--
1.8.3.2

AKASHI Takahiro

unread,
Mar 15, 2014, 2:00:02 AM3/15/14
to
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 <ar...@arndb.de>
Signed-off-by: AKASHI Takahiro <takahir...@linaro.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 0000000..5e97022
--- /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 <takahir...@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 */
--
1.8.3.2

AKASHI Takahiro

unread,
Mar 15, 2014, 2:00:02 AM3/15/14
to
(Please apply this patch after my ftrace patch and audit patch in order
to avoid some conflict on arm64/Kconfig.)

This patch enables secure computing (system call filtering) on arm64.
System calls can be allowed or denied by loaded bpf-style rules.
Architecture specific part is to run secure_computing() on syscall entry
and check the result. See [2/2]

Prerequisites are:
* "arm64: make a single hook to syscall_trace() for all syscall features" patch
* "arm64: split syscall_trace() into separate functions for enter/exit" patch
* "arm64: Add audit support" patch
* "arm64: is_compat_task is defined both in asm/compat.h and
linux/compat.h" patch

This code is tested on ARMv8 fast model using libseccomp v2.1.1 with
modifications for arm64 and verified by its "live" tests, 20, 21 and 24.

Changes v3 -> v4:
* removed the following patch and moved it to "arm64: prerequisites for
audit and ftrace" patchset since it is required for audit and ftrace in
case of !COMPAT, too.
"arm64: is_compat_task is defined both in asm/compat.h and linux/compat.h"

Changes v2 -> v3:
* removed unnecessary 'type cast' operations [2/3]
* check for a return value (-1) of secure_computing() explicitly [2/3]
* aligned with the patch, "arm64: split syscall_trace() into separate
functions for enter/exit" [2/3]
* changed default of CONFIG_SECCOMP to n [2/3]

Changes v1 -> v2:
* added generic seccomp.h for arm64 to utilize it [1,2/3]
* changed syscall_trace() to return more meaningful value (-EPERM)
on seccomp failure case [2/3]
* aligned with the change in "arm64: make a single hook to syscall_trace()
for all syscall features" v2 [2/3]
* removed is_compat_task() definition from compat.h [3/3]

AKASHI Takahiro (2):
asm-generic: Add generic seccomp.h for secure computing mode 1
arm64: Add seccomp support

arch/arm64/Kconfig | 14 ++++++++++++++
arch/arm64/include/asm/seccomp.h | 25 +++++++++++++++++++++++++
arch/arm64/include/asm/unistd.h | 3 +++
arch/arm64/kernel/entry.S | 4 ++++
arch/arm64/kernel/ptrace.c | 6 ++++++
include/asm-generic/seccomp.h | 28 ++++++++++++++++++++++++++++
6 files changed, 80 insertions(+)
create mode 100644 arch/arm64/include/asm/seccomp.h
create mode 100644 include/asm-generic/seccomp.h

--
1.8.3.2

Mark Salter

unread,
Jun 25, 2014, 11:00:01 AM6/25/14
to
What is the current status of this patch series? Is it on track
for 3.17?

AKASHI Takahiro

unread,
Jun 25, 2014, 9:00:01 PM6/25/14
to
On 06/25/2014 11:53 PM, Mark Salter wrote:
> What is the current status of this patch series? Is it on track
> for 3.17?

I assume not as I saw no comments on this so far.
But I will re-post a new version soon or later due to recent changes on seccomp.

-Takahiro AKASHI
0 new messages