[PATCH 02/13] csky: Add SECCOMP_FILTER supported

From: guoren
Date: Fri Jul 31 2020 - 21:14:57 EST


From: Guo Ren <guoren@xxxxxxxxxxxxxxxxx>

secure_computing() is called first in syscall_trace_enter() so that
a system call will be aborted quickly without doing succeeding syscall
tracing if seccomp rules want to deny that system call.

TODO:
- Update https://github.com/seccomp/libseccomp csky support

Signed-off-by: Guo Ren <guoren@xxxxxxxxxxxxxxxxx>
Cc: Arnd Bergmann <arnd@xxxxxxxx>
---
arch/csky/Kconfig | 14 ++++++++++++++
arch/csky/include/asm/Kbuild | 1 +
arch/csky/include/asm/thread_info.h | 2 +-
arch/csky/kernel/entry.S | 3 +++
arch/csky/kernel/ptrace.c | 8 ++++++--
tools/testing/selftests/seccomp/seccomp_bpf.c | 13 ++++++++++++-
6 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig
index bd31ab1..822362d 100644
--- a/arch/csky/Kconfig
+++ b/arch/csky/Kconfig
@@ -38,6 +38,7 @@ config CSKY
select GX6605S_TIMER if CPU_CK610
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_AUDITSYSCALL
+ select HAVE_ARCH_SECCOMP_FILTER
select HAVE_COPY_THREAD_TLS
select HAVE_DEBUG_BUGVERBOSE
select HAVE_DYNAMIC_FTRACE
@@ -296,3 +297,16 @@ endmenu
source "arch/csky/Kconfig.platforms"

source "kernel/Kconfig.hz"
+
+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.
diff --git a/arch/csky/include/asm/Kbuild b/arch/csky/include/asm/Kbuild
index 9337225..64876e59 100644
--- a/arch/csky/include/asm/Kbuild
+++ b/arch/csky/include/asm/Kbuild
@@ -4,5 +4,6 @@ generic-y += gpio.h
generic-y += kvm_para.h
generic-y += local64.h
generic-y += qrwlock.h
+generic-y += seccomp.h
generic-y += user.h
generic-y += vmlinux.lds.h
diff --git a/arch/csky/include/asm/thread_info.h b/arch/csky/include/asm/thread_info.h
index 8980e4e..68e7a12 100644
--- a/arch/csky/include/asm/thread_info.h
+++ b/arch/csky/include/asm/thread_info.h
@@ -85,6 +85,6 @@ static inline struct thread_info *current_thread_info(void)
_TIF_NOTIFY_RESUME | _TIF_UPROBE)

#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
- _TIF_SYSCALL_TRACEPOINT)
+ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)

#endif /* _ASM_CSKY_THREAD_INFO_H */
diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S
index f138003..efd2e69 100644
--- a/arch/csky/kernel/entry.S
+++ b/arch/csky/kernel/entry.S
@@ -168,6 +168,8 @@ ENTRY(csky_systemcall)
csky_syscall_trace:
mov a0, sp /* sp = pt_regs pointer */
jbsr syscall_trace_enter
+ cmpnei a0, 0
+ bt 1f
/* Prepare args before do system call */
ldw a0, (sp, LSAVE_A0)
ldw a1, (sp, LSAVE_A1)
@@ -188,6 +190,7 @@ csky_syscall_trace:
#endif
stw a0, (sp, LSAVE_A0) /* Save return value */

+1:
#ifdef CONFIG_DEBUG_RSEQ
mov a0, sp
jbsr rseq_syscall
diff --git a/arch/csky/kernel/ptrace.c b/arch/csky/kernel/ptrace.c
index 944ca2f..0de10f7 100644
--- a/arch/csky/kernel/ptrace.c
+++ b/arch/csky/kernel/ptrace.c
@@ -320,16 +320,20 @@ long arch_ptrace(struct task_struct *child, long request,
return ret;
}

-asmlinkage void syscall_trace_enter(struct pt_regs *regs)
+asmlinkage int syscall_trace_enter(struct pt_regs *regs)
{
if (test_thread_flag(TIF_SYSCALL_TRACE))
if (tracehook_report_syscall_entry(regs))
- syscall_set_nr(current, regs, -1);
+ return -1;
+
+ if (secure_computing() == -1)
+ return -1;

if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, syscall_get_nr(current, regs));

audit_syscall_entry(regs_syscallid(regs), regs->a0, regs->a1, regs->a2, regs->a3);
+ return 0;
}

asmlinkage void syscall_trace_exit(struct pt_regs *regs)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 252140a..8d18a0d 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -116,6 +116,8 @@ struct seccomp_data {
# define __NR_seccomp 277
# elif defined(__riscv)
# define __NR_seccomp 277
+# elif defined(__csky__)
+# define __NR_seccomp 277
# elif defined(__hppa__)
# define __NR_seccomp 338
# elif defined(__powerpc__)
@@ -1603,6 +1605,14 @@ TEST_F(TRACE_poke, getpid_runs_normally)
# define ARCH_REGS struct user_regs_struct
# define SYSCALL_NUM a7
# define SYSCALL_RET a0
+#elif defined(__csky__)
+# define ARCH_REGS struct pt_regs
+#if defined(__CSKYABIV2__)
+# define SYSCALL_NUM regs[3]
+#else
+# define SYSCALL_NUM regs[9]
+#endif
+# define SYSCALL_RET a0
#elif defined(__hppa__)
# define ARCH_REGS struct user_regs_struct
# define SYSCALL_NUM gr[20]
@@ -1693,7 +1703,8 @@ void change_syscall(struct __test_metadata *_metadata,
EXPECT_EQ(0, ret) {}

#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \
- defined(__s390__) || defined(__hppa__) || defined(__riscv)
+ defined(__s390__) || defined(__hppa__) || defined(__riscv) || \
+ defined(__csky__)
{
regs.SYSCALL_NUM = syscall;
}
--
2.7.4