All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] MIPS seccomp_bpf self test and fixups
@ 2016-03-29  8:35 ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, linux-mips, Arnd Bergmann, Andy Lutomirski,
	Kees Cook, linux-kernel, Shuah Khan, Eric B Munson, James Hogan,
	Andrew Morton, linux-kselftest, linux-arch, Markos Chandras,
	Amanieu d'Antras, Ralf Baechle, Alex Smith, Paul Burton,
	Will Drewry

These patches imporve seccomp support on MIPS.

Firstly support is added for building the seccomp_bpf self test for
MIPS. The
initial results of these tests were:

32bit kernel O32 userspace before: 48 / 48 pass
64bit kernel O32 userspace before: 47 / 48 pass
 Failures: TRAP.Handler
64bit kernel N32 userspace before: 44 / 48 pass
 Failures: global.mode_strict_support, TRAP.handler,
TRACE_syscall.syscall_redirected, TRACE_syscall.syscall_dropped
64bit kernel N64 userspace before: 46 / 48 pass
 Failures: TRACE_syscall.syscall_redirected,
TRACE_syscall.syscall_dropped

The subsequent patches fix issues that were causing the above tests to
fail. With
these fixes, the results are:
32bit kernel O32 userspace after: 48 / 48
64bit kernel O32 userspace after: 48 / 48
64bit kernel N32 userspace after: 48 / 48
64bit kernel N64 userspace after: 48 / 48

Thanks,
Matt

Changes in v2:
- Tested on additional platforms
- Replace __NR_syscall which isn't defined for N32 / N64 ABIs

Matt Redfearn (6):
  selftests/seccomp: add MIPS self-test support
  MIPS: Support sending SIG_SYS to 32bit userspace from 64bit kernel
  MIPS: scall: Handle seccomp filters which redirect syscalls
  seccomp: Get compat syscalls from asm-generic header
  MIPS: seccomp: Support compat with both O32 and N32
  secomp: Constify mode1 syscall whitelist

 arch/mips/include/asm/seccomp.h               | 47 +++++++++++++++------------
 arch/mips/kernel/scall32-o32.S                | 11 +++----
 arch/mips/kernel/scall64-64.S                 |  3 +-
 arch/mips/kernel/scall64-n32.S                | 14 +++++---
 arch/mips/kernel/scall64-o32.S                | 14 +++++---
 arch/mips/kernel/signal32.c                   |  6 ++++
 include/asm-generic/seccomp.h                 | 14 ++++++++
 kernel/seccomp.c                              | 13 ++------
 tools/testing/selftests/seccomp/seccomp_bpf.c | 30 +++++++++++++++--
 9 files changed, 101 insertions(+), 51 deletions(-)

-- 
2.5.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 0/6] MIPS seccomp_bpf self test and fixups
@ 2016-03-29  8:35 ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, linux-mips, Arnd Bergmann, Andy Lutomirski,
	Kees Cook, linux-kernel, Shuah Khan, Eric B Munson, James Hogan,
	Andrew Morton, linux-kselftest, linux-arch, Markos Chandras,
	Amanieu d'Antras, Ralf Baechle, Alex Smith, Paul Burton,
	Will Drewry

These patches imporve seccomp support on MIPS.

Firstly support is added for building the seccomp_bpf self test for
MIPS. The
initial results of these tests were:

32bit kernel O32 userspace before: 48 / 48 pass
64bit kernel O32 userspace before: 47 / 48 pass
 Failures: TRAP.Handler
64bit kernel N32 userspace before: 44 / 48 pass
 Failures: global.mode_strict_support, TRAP.handler,
TRACE_syscall.syscall_redirected, TRACE_syscall.syscall_dropped
64bit kernel N64 userspace before: 46 / 48 pass
 Failures: TRACE_syscall.syscall_redirected,
TRACE_syscall.syscall_dropped

The subsequent patches fix issues that were causing the above tests to
fail. With
these fixes, the results are:
32bit kernel O32 userspace after: 48 / 48
64bit kernel O32 userspace after: 48 / 48
64bit kernel N32 userspace after: 48 / 48
64bit kernel N64 userspace after: 48 / 48

Thanks,
Matt

Changes in v2:
- Tested on additional platforms
- Replace __NR_syscall which isn't defined for N32 / N64 ABIs

Matt Redfearn (6):
  selftests/seccomp: add MIPS self-test support
  MIPS: Support sending SIG_SYS to 32bit userspace from 64bit kernel
  MIPS: scall: Handle seccomp filters which redirect syscalls
  seccomp: Get compat syscalls from asm-generic header
  MIPS: seccomp: Support compat with both O32 and N32
  secomp: Constify mode1 syscall whitelist

 arch/mips/include/asm/seccomp.h               | 47 +++++++++++++++------------
 arch/mips/kernel/scall32-o32.S                | 11 +++----
 arch/mips/kernel/scall64-64.S                 |  3 +-
 arch/mips/kernel/scall64-n32.S                | 14 +++++---
 arch/mips/kernel/scall64-o32.S                | 14 +++++---
 arch/mips/kernel/signal32.c                   |  6 ++++
 include/asm-generic/seccomp.h                 | 14 ++++++++
 kernel/seccomp.c                              | 13 ++------
 tools/testing/selftests/seccomp/seccomp_bpf.c | 30 +++++++++++++++--
 9 files changed, 101 insertions(+), 51 deletions(-)

-- 
2.5.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 1/6] selftests/seccomp: add MIPS self-test support
@ 2016-03-29  8:35   ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, Andy Lutomirski, Kees Cook, linux-kernel,
	Shuah Khan, linux-kselftest, Will Drewry

This adds self-test support on MIPS, based on RFC patch from Kees Cook.
Modifications from the RFC:
- support the O32 syscall which passes the real syscall number in a0.
- Use PTRACE_{GET,SET}REGS
- Because SYSCALL_NUM and SYSCALL_RET are the same register, it is not
  possible to test modifying the syscall return value when skipping,
  since both would need to set the same register. Therefore modify that
  test case to just detect the skipped test.
Tested on MIPS32r2 / MIPS64r2 with O32, N32 and N64 userlands.

Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
Acked-by: Kees Cook <keescook@chromium.org>
---

Changes in v2:
- Tested on additional platforms
- Replace __NR_syscall which isn't defined for N32 / N64 ABIs

 tools/testing/selftests/seccomp/seccomp_bpf.c | 30 +++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index b9453b838162..4c3e032d7224 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -5,6 +5,7 @@
  * Test code for seccomp bpf.
  */
 
+#include <sys/types.h>
 #include <asm/siginfo.h>
 #define __have_siginfo_t 1
 #define __have_sigval_t 1
@@ -14,7 +15,6 @@
 #include <linux/filter.h>
 #include <sys/prctl.h>
 #include <sys/ptrace.h>
-#include <sys/types.h>
 #include <sys/user.h>
 #include <linux/prctl.h>
 #include <linux/ptrace.h>
@@ -1242,6 +1242,12 @@ TEST_F(TRACE_poke, getpid_runs_normally)
 # define ARCH_REGS     s390_regs
 # define SYSCALL_NUM   gprs[2]
 # define SYSCALL_RET   gprs[2]
+#elif defined(__mips__)
+# define ARCH_REGS	struct pt_regs
+# define SYSCALL_NUM	regs[2]
+# define SYSCALL_SYSCALL_NUM regs[4]
+# define SYSCALL_RET	regs[2]
+# define SYSCALL_NUM_RET_SHARE_REG
 #else
 # error "Do not know how to find your architecture's registers and syscalls"
 #endif
@@ -1249,7 +1255,7 @@ TEST_F(TRACE_poke, getpid_runs_normally)
 /* Use PTRACE_GETREGS and PTRACE_SETREGS when available. This is useful for
  * architectures without HAVE_ARCH_TRACEHOOK (e.g. User-mode Linux).
  */
-#if defined(__x86_64__) || defined(__i386__)
+#if defined(__x86_64__) || defined(__i386__) || defined(__mips__)
 #define HAVE_GETREGS
 #endif
 
@@ -1273,6 +1279,10 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
 	}
 #endif
 
+#if defined(__mips__)
+	if (regs.SYSCALL_NUM == __NR_O32_Linux)
+		return regs.SYSCALL_SYSCALL_NUM;
+#endif
 	return regs.SYSCALL_NUM;
 }
 
@@ -1297,6 +1307,13 @@ void change_syscall(struct __test_metadata *_metadata,
 	{
 		regs.SYSCALL_NUM = syscall;
 	}
+#elif defined(__mips__)
+	{
+		if (regs.SYSCALL_NUM == __NR_O32_Linux)
+			regs.SYSCALL_SYSCALL_NUM = syscall;
+		else
+			regs.SYSCALL_NUM = syscall;
+	}
 
 #elif defined(__arm__)
 # ifndef PTRACE_SET_SYSCALL
@@ -1327,7 +1344,11 @@ void change_syscall(struct __test_metadata *_metadata,
 
 	/* If syscall is skipped, change return value. */
 	if (syscall == -1)
+#ifdef SYSCALL_NUM_RET_SHARE_REG
+		TH_LOG("Can't modify syscall return on this architecture");
+#else
 		regs.SYSCALL_RET = 1;
+#endif
 
 #ifdef HAVE_GETREGS
 	ret = ptrace(PTRACE_SETREGS, tracee, 0, &regs);
@@ -1465,8 +1486,13 @@ TEST_F(TRACE_syscall, syscall_dropped)
 	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
 	ASSERT_EQ(0, ret);
 
+#ifdef SYSCALL_NUM_RET_SHARE_REG
+	/* gettid has been skipped */
+	EXPECT_EQ(-1, syscall(__NR_gettid));
+#else
 	/* gettid has been skipped and an altered return value stored. */
 	EXPECT_EQ(1, syscall(__NR_gettid));
+#endif
 	EXPECT_NE(self->mytid, syscall(__NR_gettid));
 }
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 1/6] selftests/seccomp: add MIPS self-test support
@ 2016-03-29  8:35   ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, Andy Lutomirski, Kees Cook, linux-kernel,
	Shuah Khan, linux-kselftest, Will Drewry

This adds self-test support on MIPS, based on RFC patch from Kees Cook.
Modifications from the RFC:
- support the O32 syscall which passes the real syscall number in a0.
- Use PTRACE_{GET,SET}REGS
- Because SYSCALL_NUM and SYSCALL_RET are the same register, it is not
  possible to test modifying the syscall return value when skipping,
  since both would need to set the same register. Therefore modify that
  test case to just detect the skipped test.
Tested on MIPS32r2 / MIPS64r2 with O32, N32 and N64 userlands.

Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
Acked-by: Kees Cook <keescook@chromium.org>
---

Changes in v2:
- Tested on additional platforms
- Replace __NR_syscall which isn't defined for N32 / N64 ABIs

 tools/testing/selftests/seccomp/seccomp_bpf.c | 30 +++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index b9453b838162..4c3e032d7224 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -5,6 +5,7 @@
  * Test code for seccomp bpf.
  */
 
+#include <sys/types.h>
 #include <asm/siginfo.h>
 #define __have_siginfo_t 1
 #define __have_sigval_t 1
@@ -14,7 +15,6 @@
 #include <linux/filter.h>
 #include <sys/prctl.h>
 #include <sys/ptrace.h>
-#include <sys/types.h>
 #include <sys/user.h>
 #include <linux/prctl.h>
 #include <linux/ptrace.h>
@@ -1242,6 +1242,12 @@ TEST_F(TRACE_poke, getpid_runs_normally)
 # define ARCH_REGS     s390_regs
 # define SYSCALL_NUM   gprs[2]
 # define SYSCALL_RET   gprs[2]
+#elif defined(__mips__)
+# define ARCH_REGS	struct pt_regs
+# define SYSCALL_NUM	regs[2]
+# define SYSCALL_SYSCALL_NUM regs[4]
+# define SYSCALL_RET	regs[2]
+# define SYSCALL_NUM_RET_SHARE_REG
 #else
 # error "Do not know how to find your architecture's registers and syscalls"
 #endif
@@ -1249,7 +1255,7 @@ TEST_F(TRACE_poke, getpid_runs_normally)
 /* Use PTRACE_GETREGS and PTRACE_SETREGS when available. This is useful for
  * architectures without HAVE_ARCH_TRACEHOOK (e.g. User-mode Linux).
  */
-#if defined(__x86_64__) || defined(__i386__)
+#if defined(__x86_64__) || defined(__i386__) || defined(__mips__)
 #define HAVE_GETREGS
 #endif
 
@@ -1273,6 +1279,10 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
 	}
 #endif
 
+#if defined(__mips__)
+	if (regs.SYSCALL_NUM == __NR_O32_Linux)
+		return regs.SYSCALL_SYSCALL_NUM;
+#endif
 	return regs.SYSCALL_NUM;
 }
 
@@ -1297,6 +1307,13 @@ void change_syscall(struct __test_metadata *_metadata,
 	{
 		regs.SYSCALL_NUM = syscall;
 	}
+#elif defined(__mips__)
+	{
+		if (regs.SYSCALL_NUM == __NR_O32_Linux)
+			regs.SYSCALL_SYSCALL_NUM = syscall;
+		else
+			regs.SYSCALL_NUM = syscall;
+	}
 
 #elif defined(__arm__)
 # ifndef PTRACE_SET_SYSCALL
@@ -1327,7 +1344,11 @@ void change_syscall(struct __test_metadata *_metadata,
 
 	/* If syscall is skipped, change return value. */
 	if (syscall == -1)
+#ifdef SYSCALL_NUM_RET_SHARE_REG
+		TH_LOG("Can't modify syscall return on this architecture");
+#else
 		regs.SYSCALL_RET = 1;
+#endif
 
 #ifdef HAVE_GETREGS
 	ret = ptrace(PTRACE_SETREGS, tracee, 0, &regs);
@@ -1465,8 +1486,13 @@ TEST_F(TRACE_syscall, syscall_dropped)
 	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
 	ASSERT_EQ(0, ret);
 
+#ifdef SYSCALL_NUM_RET_SHARE_REG
+	/* gettid has been skipped */
+	EXPECT_EQ(-1, syscall(__NR_gettid));
+#else
 	/* gettid has been skipped and an altered return value stored. */
 	EXPECT_EQ(1, syscall(__NR_gettid));
+#endif
 	EXPECT_NE(self->mytid, syscall(__NR_gettid));
 }
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 2/6] MIPS: Support sending SIG_SYS to 32bit userspace from 64bit kernel
@ 2016-03-29  8:35   ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, Paul Burton, linux-mips, linux-kernel,
	Amanieu d'Antras, Ralf Baechle, Alex Smith, Andrew Morton

The seccomp_bpf self test revealed that a 64bit kernel delivered an
invalid SIG_SYS to a 32bit userspace, because it was falling into the
default of the switch statement. Add a case to handle delivering the
signal.

With this patch, the seccomp_bpf self test now passes the TRAP.handler
case with O32 and N32 userlands.

Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
---

Changes in v2: None

 arch/mips/kernel/signal32.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 4909639aa35b..78c8349d151c 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -227,6 +227,12 @@ 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;
+		case __SI_SYS >> 16:
+			err |= __copy_to_user(&to->si_call_addr, &from->si_call_addr,
+					      sizeof(compat_uptr_t));
+			err |= __put_user(from->si_syscall, &to->si_syscall);
+			err |= __put_user(from->si_arch, &to->si_arch);
+			break;
 		}
 	}
 	return err;
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 2/6] MIPS: Support sending SIG_SYS to 32bit userspace from 64bit kernel
@ 2016-03-29  8:35   ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, Paul Burton, linux-mips, linux-kernel,
	Amanieu d'Antras, Ralf Baechle, Alex Smith, Andrew Morton

The seccomp_bpf self test revealed that a 64bit kernel delivered an
invalid SIG_SYS to a 32bit userspace, because it was falling into the
default of the switch statement. Add a case to handle delivering the
signal.

With this patch, the seccomp_bpf self test now passes the TRAP.handler
case with O32 and N32 userlands.

Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
---

Changes in v2: None

 arch/mips/kernel/signal32.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 4909639aa35b..78c8349d151c 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -227,6 +227,12 @@ 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;
+		case __SI_SYS >> 16:
+			err |= __copy_to_user(&to->si_call_addr, &from->si_call_addr,
+					      sizeof(compat_uptr_t));
+			err |= __put_user(from->si_syscall, &to->si_syscall);
+			err |= __put_user(from->si_arch, &to->si_arch);
+			break;
 		}
 	}
 	return err;
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 3/6] MIPS: scall: Handle seccomp filters which redirect syscalls
@ 2016-03-29  8:35   ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, linux-mips, linux-kernel, Eric B Munson,
	James Hogan, Markos Chandras, Ralf Baechle, Andrew Morton

Commit d218af78492a ("MIPS: scall: Always run the seccomp syscall
filters") modified the syscall code to always call the seccomp filters,
but missed the case where a filter may redirect the syscall, as
revealed by the seccomp_bpf self test.

The syscall path now restores the syscall from the stack after the
filter rather than saving it locally. Syscall number checking and
syscall function table lookup is done after the filter may have run such
that redirected syscalls are also checked, and executed.

The regular path of syscall number checking and pointer lookup is also
made more consistent between ABIs with scall64-64.S being the reference.

With this patch in place, the seccomp_bpf self test now passes
TRACE_syscall.syscall_redirected and TRACE_syscall.syscall_dropped on
all MIPS ABIs.

Fixes: d218af78492a ("MIPS: scall: Always run the seccomp syscall filters")
Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
Cc: linux-mips@linux-mips.org
---

Changes in v2: None

 arch/mips/kernel/scall32-o32.S | 11 +++++------
 arch/mips/kernel/scall64-64.S  |  3 +--
 arch/mips/kernel/scall64-n32.S | 14 +++++++++-----
 arch/mips/kernel/scall64-o32.S | 14 +++++++++-----
 4 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index a56317444bda..6c1b5e085f2d 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -35,7 +35,6 @@ NESTED(handle_sys, PT_SIZE, sp)
 
 	lw	t1, PT_EPC(sp)		# skip syscall on return
 
-	subu	v0, v0, __NR_O32_Linux	# check syscall number
 	addiu	t1, 4			# skip to next instruction
 	sw	t1, PT_EPC(sp)
 
@@ -89,6 +88,7 @@ loads_done:
 	and	t0, t1
 	bnez	t0, syscall_trace_entry # -> yes
 syscall_common:
+	subu	v0, v0, __NR_O32_Linux	# check syscall number
 	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
 	beqz	t0, illegal_syscall
 
@@ -118,24 +118,23 @@ o32_syscall_exit:
 
 syscall_trace_entry:
 	SAVE_STATIC
-	move	s0, v0
 	move	a0, sp
 
 	/*
 	 * syscall number is in v0 unless we called syscall(__NR_###)
 	 * where the real syscall number is in a0
 	 */
-	addiu	a1, v0,  __NR_O32_Linux
-	bnez	v0, 1f /* __NR_syscall at offset 0 */
+	move	a1, v0
+	subu	t2, v0,  __NR_O32_Linux
+	bnez	t2, 1f /* __NR_syscall at offset 0 */
 	lw	a1, PT_R4(sp)
 
 1:	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	v0, s0			# restore syscall
-
 	RESTORE_STATIC
+	lw	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	lw	a0, PT_R4(sp)		# Restore argument registers
 	lw	a1, PT_R5(sp)
 	lw	a2, PT_R6(sp)
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 2b2dc14610d0..ede49e35d6a6 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -82,15 +82,14 @@ n64_syscall_exit:
 
 syscall_trace_entry:
 	SAVE_STATIC
-	move	s0, v0
 	move	a0, sp
 	move	a1, v0
 	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	v0, s0
 	RESTORE_STATIC
+	ld	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 2bf5c8593d91..f75a6e19b902 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -42,9 +42,6 @@ NESTED(handle_sysn32, PT_SIZE, sp)
 #endif
 	beqz	t0, not_n32_scall
 
-	dsll	t0, v0, 3		# offset into table
-	ld	t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
-
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
 	li	t1, _TIF_WORK_SYSCALL_ENTRY
@@ -53,6 +50,9 @@ NESTED(handle_sysn32, PT_SIZE, sp)
 	bnez	t0, n32_syscall_trace_entry
 
 syscall_common:
+	dsll	t0, v0, 3		# offset into table
+	ld	t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
+
 	jalr	t2			# Do The Real Thing (TM)
 
 	li	t0, -EMAXERRNO - 1	# error?
@@ -71,21 +71,25 @@ syscall_common:
 
 n32_syscall_trace_entry:
 	SAVE_STATIC
-	move	s0, t2
 	move	a0, sp
 	move	a1, v0
 	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	t2, s0
 	RESTORE_STATIC
+	ld	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
 	ld	a3, PT_R7(sp)
 	ld	a4, PT_R8(sp)
 	ld	a5, PT_R9(sp)
+
+	dsubu	t2, v0, __NR_N32_Linux	# check (new) syscall number
+	sltiu   t0, t2, __NR_N32_Linux_syscalls + 1
+	beqz	t0, not_n32_scall
+
 	j	syscall_common
 
 1:	j	syscall_exit
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index c5b759e584c7..db224e7b995c 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -52,9 +52,6 @@ NESTED(handle_sys, PT_SIZE, sp)
 	sll	a2, a2, 0
 	sll	a3, a3, 0
 
-	dsll	t0, v0, 3		# offset into table
-	ld	t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
-
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
 	/*
@@ -88,6 +85,9 @@ loads_done:
 	bnez	t0, trace_a_syscall
 
 syscall_common:
+	dsll	t0, v0, 3		# offset into table
+	ld	t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
+
 	jalr	t2			# Do The Real Thing (TM)
 
 	li	t0, -EMAXERRNO - 1	# error?
@@ -112,7 +112,6 @@ trace_a_syscall:
 	sd	a6, PT_R10(sp)
 	sd	a7, PT_R11(sp)		# For indirect syscalls
 
-	move	s0, t2			# Save syscall pointer
 	move	a0, sp
 	/*
 	 * absolute syscall number is in v0 unless we called syscall(__NR_###)
@@ -133,8 +132,8 @@ trace_a_syscall:
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	t2, s0
 	RESTORE_STATIC
+	ld	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
@@ -143,6 +142,11 @@ trace_a_syscall:
 	ld	a5, PT_R9(sp)
 	ld	a6, PT_R10(sp)
 	ld	a7, PT_R11(sp)		# For indirect syscalls
+
+	dsubu	t0, v0, __NR_O32_Linux	# check (new) syscall number
+	sltiu	t0, t0, __NR_O32_Linux_syscalls + 1
+	beqz	t0, not_o32_scall
+
 	j	syscall_common
 
 1:	j	syscall_exit
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 3/6] MIPS: scall: Handle seccomp filters which redirect syscalls
@ 2016-03-29  8:35   ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, linux-mips, linux-kernel, Eric B Munson,
	James Hogan, Markos Chandras, Ralf Baechle, Andrew Morton

Commit d218af78492a ("MIPS: scall: Always run the seccomp syscall
filters") modified the syscall code to always call the seccomp filters,
but missed the case where a filter may redirect the syscall, as
revealed by the seccomp_bpf self test.

The syscall path now restores the syscall from the stack after the
filter rather than saving it locally. Syscall number checking and
syscall function table lookup is done after the filter may have run such
that redirected syscalls are also checked, and executed.

The regular path of syscall number checking and pointer lookup is also
made more consistent between ABIs with scall64-64.S being the reference.

With this patch in place, the seccomp_bpf self test now passes
TRACE_syscall.syscall_redirected and TRACE_syscall.syscall_dropped on
all MIPS ABIs.

Fixes: d218af78492a ("MIPS: scall: Always run the seccomp syscall filters")
Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
Cc: linux-mips@linux-mips.org
---

Changes in v2: None

 arch/mips/kernel/scall32-o32.S | 11 +++++------
 arch/mips/kernel/scall64-64.S  |  3 +--
 arch/mips/kernel/scall64-n32.S | 14 +++++++++-----
 arch/mips/kernel/scall64-o32.S | 14 +++++++++-----
 4 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index a56317444bda..6c1b5e085f2d 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -35,7 +35,6 @@ NESTED(handle_sys, PT_SIZE, sp)
 
 	lw	t1, PT_EPC(sp)		# skip syscall on return
 
-	subu	v0, v0, __NR_O32_Linux	# check syscall number
 	addiu	t1, 4			# skip to next instruction
 	sw	t1, PT_EPC(sp)
 
@@ -89,6 +88,7 @@ loads_done:
 	and	t0, t1
 	bnez	t0, syscall_trace_entry # -> yes
 syscall_common:
+	subu	v0, v0, __NR_O32_Linux	# check syscall number
 	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
 	beqz	t0, illegal_syscall
 
@@ -118,24 +118,23 @@ o32_syscall_exit:
 
 syscall_trace_entry:
 	SAVE_STATIC
-	move	s0, v0
 	move	a0, sp
 
 	/*
 	 * syscall number is in v0 unless we called syscall(__NR_###)
 	 * where the real syscall number is in a0
 	 */
-	addiu	a1, v0,  __NR_O32_Linux
-	bnez	v0, 1f /* __NR_syscall at offset 0 */
+	move	a1, v0
+	subu	t2, v0,  __NR_O32_Linux
+	bnez	t2, 1f /* __NR_syscall at offset 0 */
 	lw	a1, PT_R4(sp)
 
 1:	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	v0, s0			# restore syscall
-
 	RESTORE_STATIC
+	lw	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	lw	a0, PT_R4(sp)		# Restore argument registers
 	lw	a1, PT_R5(sp)
 	lw	a2, PT_R6(sp)
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 2b2dc14610d0..ede49e35d6a6 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -82,15 +82,14 @@ n64_syscall_exit:
 
 syscall_trace_entry:
 	SAVE_STATIC
-	move	s0, v0
 	move	a0, sp
 	move	a1, v0
 	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	v0, s0
 	RESTORE_STATIC
+	ld	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 2bf5c8593d91..f75a6e19b902 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -42,9 +42,6 @@ NESTED(handle_sysn32, PT_SIZE, sp)
 #endif
 	beqz	t0, not_n32_scall
 
-	dsll	t0, v0, 3		# offset into table
-	ld	t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
-
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
 	li	t1, _TIF_WORK_SYSCALL_ENTRY
@@ -53,6 +50,9 @@ NESTED(handle_sysn32, PT_SIZE, sp)
 	bnez	t0, n32_syscall_trace_entry
 
 syscall_common:
+	dsll	t0, v0, 3		# offset into table
+	ld	t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
+
 	jalr	t2			# Do The Real Thing (TM)
 
 	li	t0, -EMAXERRNO - 1	# error?
@@ -71,21 +71,25 @@ syscall_common:
 
 n32_syscall_trace_entry:
 	SAVE_STATIC
-	move	s0, t2
 	move	a0, sp
 	move	a1, v0
 	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	t2, s0
 	RESTORE_STATIC
+	ld	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
 	ld	a3, PT_R7(sp)
 	ld	a4, PT_R8(sp)
 	ld	a5, PT_R9(sp)
+
+	dsubu	t2, v0, __NR_N32_Linux	# check (new) syscall number
+	sltiu   t0, t2, __NR_N32_Linux_syscalls + 1
+	beqz	t0, not_n32_scall
+
 	j	syscall_common
 
 1:	j	syscall_exit
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index c5b759e584c7..db224e7b995c 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -52,9 +52,6 @@ NESTED(handle_sys, PT_SIZE, sp)
 	sll	a2, a2, 0
 	sll	a3, a3, 0
 
-	dsll	t0, v0, 3		# offset into table
-	ld	t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
-
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
 	/*
@@ -88,6 +85,9 @@ loads_done:
 	bnez	t0, trace_a_syscall
 
 syscall_common:
+	dsll	t0, v0, 3		# offset into table
+	ld	t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
+
 	jalr	t2			# Do The Real Thing (TM)
 
 	li	t0, -EMAXERRNO - 1	# error?
@@ -112,7 +112,6 @@ trace_a_syscall:
 	sd	a6, PT_R10(sp)
 	sd	a7, PT_R11(sp)		# For indirect syscalls
 
-	move	s0, t2			# Save syscall pointer
 	move	a0, sp
 	/*
 	 * absolute syscall number is in v0 unless we called syscall(__NR_###)
@@ -133,8 +132,8 @@ trace_a_syscall:
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	t2, s0
 	RESTORE_STATIC
+	ld	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
@@ -143,6 +142,11 @@ trace_a_syscall:
 	ld	a5, PT_R9(sp)
 	ld	a6, PT_R10(sp)
 	ld	a7, PT_R11(sp)		# For indirect syscalls
+
+	dsubu	t0, v0, __NR_O32_Linux	# check (new) syscall number
+	sltiu	t0, t0, __NR_O32_Linux_syscalls + 1
+	beqz	t0, not_o32_scall
+
 	j	syscall_common
 
 1:	j	syscall_exit
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 4/6] seccomp: Get compat syscalls from asm-generic header
  2016-03-29  8:35 ` Matt Redfearn
@ 2016-03-29  8:35   ` Matt Redfearn
  -1 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, linux-arch, Arnd Bergmann, Kees Cook,
	linux-kernel, Andy Lutomirski, Will Drewry

Move retrieval of compat syscall numbers into inline function defined in
asm-generic header so that arches may override it.

Suggested-by: Paul Burton <paul.burton@imgtec.com>
Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
---

Changes in v2: None

 include/asm-generic/seccomp.h | 14 ++++++++++++++
 kernel/seccomp.c              |  9 +--------
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/include/asm-generic/seccomp.h b/include/asm-generic/seccomp.h
index c9ccafa0d99a..e74072d23e69 100644
--- a/include/asm-generic/seccomp.h
+++ b/include/asm-generic/seccomp.h
@@ -29,4 +29,18 @@
 #define __NR_seccomp_sigreturn		__NR_rt_sigreturn
 #endif
 
+#ifdef CONFIG_COMPAT
+#ifndef get_compat_mode1_syscalls
+static inline const int *get_compat_mode1_syscalls(void)
+{
+	static const int mode1_syscalls_32[] = {
+		__NR_seccomp_read_32, __NR_seccomp_write_32,
+		__NR_seccomp_exit_32, __NR_seccomp_sigreturn_32,
+		0, /* null terminated */
+	};
+	return mode1_syscalls_32;
+}
+#endif
+#endif /* CONFIG_COMPAT */
+
 #endif /* _ASM_GENERIC_SECCOMP_H */
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 15a1795bbba1..b0082c14764f 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -518,19 +518,12 @@ static int mode1_syscalls[] = {
 	0, /* null terminated */
 };
 
-#ifdef CONFIG_COMPAT
-static int mode1_syscalls_32[] = {
-	__NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32,
-	0, /* null terminated */
-};
-#endif
-
 static void __secure_computing_strict(int this_syscall)
 {
 	int *syscall_whitelist = mode1_syscalls;
 #ifdef CONFIG_COMPAT
 	if (is_compat_task())
-		syscall_whitelist = mode1_syscalls_32;
+		syscall_whitelist = get_compat_mode1_syscalls();
 #endif
 	do {
 		if (*syscall_whitelist == this_syscall)
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 4/6] seccomp: Get compat syscalls from asm-generic header
@ 2016-03-29  8:35   ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, linux-arch, Arnd Bergmann, Kees Cook,
	linux-kernel, Andy Lutomirski, Will Drewry

Move retrieval of compat syscall numbers into inline function defined in
asm-generic header so that arches may override it.

Suggested-by: Paul Burton <paul.burton@imgtec.com>
Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
---

Changes in v2: None

 include/asm-generic/seccomp.h | 14 ++++++++++++++
 kernel/seccomp.c              |  9 +--------
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/include/asm-generic/seccomp.h b/include/asm-generic/seccomp.h
index c9ccafa0d99a..e74072d23e69 100644
--- a/include/asm-generic/seccomp.h
+++ b/include/asm-generic/seccomp.h
@@ -29,4 +29,18 @@
 #define __NR_seccomp_sigreturn		__NR_rt_sigreturn
 #endif
 
+#ifdef CONFIG_COMPAT
+#ifndef get_compat_mode1_syscalls
+static inline const int *get_compat_mode1_syscalls(void)
+{
+	static const int mode1_syscalls_32[] = {
+		__NR_seccomp_read_32, __NR_seccomp_write_32,
+		__NR_seccomp_exit_32, __NR_seccomp_sigreturn_32,
+		0, /* null terminated */
+	};
+	return mode1_syscalls_32;
+}
+#endif
+#endif /* CONFIG_COMPAT */
+
 #endif /* _ASM_GENERIC_SECCOMP_H */
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 15a1795bbba1..b0082c14764f 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -518,19 +518,12 @@ static int mode1_syscalls[] = {
 	0, /* null terminated */
 };
 
-#ifdef CONFIG_COMPAT
-static int mode1_syscalls_32[] = {
-	__NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32,
-	0, /* null terminated */
-};
-#endif
-
 static void __secure_computing_strict(int this_syscall)
 {
 	int *syscall_whitelist = mode1_syscalls;
 #ifdef CONFIG_COMPAT
 	if (is_compat_task())
-		syscall_whitelist = mode1_syscalls_32;
+		syscall_whitelist = get_compat_mode1_syscalls();
 #endif
 	do {
 		if (*syscall_whitelist == this_syscall)
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 5/6] MIPS: seccomp: Support compat with both O32 and N32
@ 2016-03-29  8:35   ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, linux-mips, Kees Cook, linux-kernel, Ralf Baechle,
	Andrew Morton

Previously the seccomp would only support strict mode on O32 userland
programs when the kernel had support for both O32 and N32 ABIs. Remove
kludge and support both ABIs.

With this patch in place, the seccomp_bpf self test now passes
global.mode_strict_support with N32 userland.

Suggested-by: Paul Burton <paul.burton@imgtec.com>
Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
---

Changes in v2: None

 arch/mips/include/asm/seccomp.h | 47 +++++++++++++++++++++++------------------
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/arch/mips/include/asm/seccomp.h b/arch/mips/include/asm/seccomp.h
index 1d8a2e2c75c1..684fb3a12ed3 100644
--- a/arch/mips/include/asm/seccomp.h
+++ b/arch/mips/include/asm/seccomp.h
@@ -2,27 +2,32 @@
 
 #include <linux/unistd.h>
 
-/*
- * Kludge alert:
- *
- * The generic seccomp code currently allows only a single compat ABI.	Until
- * this is fixed we priorize O32 as the compat ABI over N32.
- */
-#ifdef CONFIG_MIPS32_O32
-
-#define __NR_seccomp_read_32		4003
-#define __NR_seccomp_write_32		4004
-#define __NR_seccomp_exit_32		4001
-#define __NR_seccomp_sigreturn_32	4193	/* rt_sigreturn */
-
-#elif defined(CONFIG_MIPS32_N32)
-
-#define __NR_seccomp_read_32		6000
-#define __NR_seccomp_write_32		6001
-#define __NR_seccomp_exit_32		6058
-#define __NR_seccomp_sigreturn_32	6211	/* rt_sigreturn */
-
-#endif /* CONFIG_MIPS32_O32 */
+#ifdef CONFIG_COMPAT
+static inline const int *get_compat_mode1_syscalls(void)
+{
+	static const int syscalls_O32[] = {
+		__NR_O32_Linux + 3, __NR_O32_Linux + 4,
+		__NR_O32_Linux + 1, __NR_O32_Linux + 193,
+		0, /* null terminated */
+	};
+	static const int syscalls_N32[] = {
+		__NR_N32_Linux + 0, __NR_N32_Linux + 1,
+		__NR_N32_Linux + 58, __NR_N32_Linux + 211,
+		0, /* null terminated */
+	};
+
+	if (config_enabled(CONFIG_MIPS32_O32) && test_thread_flag(TIF_32BIT_REGS))
+		return syscalls_O32;
+
+	if (config_enabled(CONFIG_MIPS32_N32))
+		return syscalls_N32;
+
+	BUG();
+}
+
+#define get_compat_mode1_syscalls get_compat_mode1_syscalls
+
+#endif /* CONFIG_COMPAT */
 
 #include <asm-generic/seccomp.h>
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 5/6] MIPS: seccomp: Support compat with both O32 and N32
@ 2016-03-29  8:35   ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, linux-mips, Kees Cook, linux-kernel, Ralf Baechle,
	Andrew Morton

Previously the seccomp would only support strict mode on O32 userland
programs when the kernel had support for both O32 and N32 ABIs. Remove
kludge and support both ABIs.

With this patch in place, the seccomp_bpf self test now passes
global.mode_strict_support with N32 userland.

Suggested-by: Paul Burton <paul.burton@imgtec.com>
Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
---

Changes in v2: None

 arch/mips/include/asm/seccomp.h | 47 +++++++++++++++++++++++------------------
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/arch/mips/include/asm/seccomp.h b/arch/mips/include/asm/seccomp.h
index 1d8a2e2c75c1..684fb3a12ed3 100644
--- a/arch/mips/include/asm/seccomp.h
+++ b/arch/mips/include/asm/seccomp.h
@@ -2,27 +2,32 @@
 
 #include <linux/unistd.h>
 
-/*
- * Kludge alert:
- *
- * The generic seccomp code currently allows only a single compat ABI.	Until
- * this is fixed we priorize O32 as the compat ABI over N32.
- */
-#ifdef CONFIG_MIPS32_O32
-
-#define __NR_seccomp_read_32		4003
-#define __NR_seccomp_write_32		4004
-#define __NR_seccomp_exit_32		4001
-#define __NR_seccomp_sigreturn_32	4193	/* rt_sigreturn */
-
-#elif defined(CONFIG_MIPS32_N32)
-
-#define __NR_seccomp_read_32		6000
-#define __NR_seccomp_write_32		6001
-#define __NR_seccomp_exit_32		6058
-#define __NR_seccomp_sigreturn_32	6211	/* rt_sigreturn */
-
-#endif /* CONFIG_MIPS32_O32 */
+#ifdef CONFIG_COMPAT
+static inline const int *get_compat_mode1_syscalls(void)
+{
+	static const int syscalls_O32[] = {
+		__NR_O32_Linux + 3, __NR_O32_Linux + 4,
+		__NR_O32_Linux + 1, __NR_O32_Linux + 193,
+		0, /* null terminated */
+	};
+	static const int syscalls_N32[] = {
+		__NR_N32_Linux + 0, __NR_N32_Linux + 1,
+		__NR_N32_Linux + 58, __NR_N32_Linux + 211,
+		0, /* null terminated */
+	};
+
+	if (config_enabled(CONFIG_MIPS32_O32) && test_thread_flag(TIF_32BIT_REGS))
+		return syscalls_O32;
+
+	if (config_enabled(CONFIG_MIPS32_N32))
+		return syscalls_N32;
+
+	BUG();
+}
+
+#define get_compat_mode1_syscalls get_compat_mode1_syscalls
+
+#endif /* CONFIG_COMPAT */
 
 #include <asm-generic/seccomp.h>
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 6/6] secomp: Constify mode1 syscall whitelist
@ 2016-03-29  8:35   ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, Will Drewry, linux-kernel, Andy Lutomirski, Kees Cook

These values are constant and should be marked as such.

Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
---

Changes in v2: None

 kernel/seccomp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index b0082c14764f..9243d686d11a 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -513,14 +513,14 @@ static void seccomp_send_sigsys(int syscall, int reason)
  * To be fully secure this must be combined with rlimit
  * to limit the stack allocations too.
  */
-static int mode1_syscalls[] = {
+static const int mode1_syscalls[] = {
 	__NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn,
 	0, /* null terminated */
 };
 
 static void __secure_computing_strict(int this_syscall)
 {
-	int *syscall_whitelist = mode1_syscalls;
+	const int *syscall_whitelist = mode1_syscalls;
 #ifdef CONFIG_COMPAT
 	if (is_compat_task())
 		syscall_whitelist = get_compat_mode1_syscalls();
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 6/6] secomp: Constify mode1 syscall whitelist
@ 2016-03-29  8:35   ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-29  8:35 UTC (permalink / raw)
  To: IMG-MIPSLinuxKerneldevelopers
  Cc: Matt Redfearn, Will Drewry, linux-kernel, Andy Lutomirski, Kees Cook

These values are constant and should be marked as such.

Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
---

Changes in v2: None

 kernel/seccomp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index b0082c14764f..9243d686d11a 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -513,14 +513,14 @@ static void seccomp_send_sigsys(int syscall, int reason)
  * To be fully secure this must be combined with rlimit
  * to limit the stack allocations too.
  */
-static int mode1_syscalls[] = {
+static const int mode1_syscalls[] = {
 	__NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn,
 	0, /* null terminated */
 };
 
 static void __secure_computing_strict(int this_syscall)
 {
-	int *syscall_whitelist = mode1_syscalls;
+	const int *syscall_whitelist = mode1_syscalls;
 #ifdef CONFIG_COMPAT
 	if (is_compat_task())
 		syscall_whitelist = get_compat_mode1_syscalls();
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/6] MIPS seccomp_bpf self test and fixups
  2016-03-29  8:35 ` Matt Redfearn
                   ` (6 preceding siblings ...)
  (?)
@ 2016-03-30  5:06 ` Kees Cook
  2016-03-31  8:57     ` Matt Redfearn
  -1 siblings, 1 reply; 17+ messages in thread
From: Kees Cook @ 2016-03-30  5:06 UTC (permalink / raw)
  To: Matt Redfearn
  Cc: IMG-MIPSLinuxKerneldevelopers, Linux MIPS Mailing List,
	Arnd Bergmann, Andy Lutomirski, LKML, Shuah Khan, Eric B Munson,
	James Hogan, Andrew Morton, linux-kselftest, linux-arch,
	Markos Chandras, Amanieu d'Antras, Ralf Baechle, Alex Smith,
	Paul Burton, Will Drewry

On Tue, Mar 29, 2016 at 1:35 AM, Matt Redfearn <matt.redfearn@imgtec.com> wrote:
> These patches imporve seccomp support on MIPS.
>
> Firstly support is added for building the seccomp_bpf self test for
> MIPS. The
> initial results of these tests were:
>
> 32bit kernel O32 userspace before: 48 / 48 pass
> 64bit kernel O32 userspace before: 47 / 48 pass
>  Failures: TRAP.Handler
> 64bit kernel N32 userspace before: 44 / 48 pass
>  Failures: global.mode_strict_support, TRAP.handler,
> TRACE_syscall.syscall_redirected, TRACE_syscall.syscall_dropped
> 64bit kernel N64 userspace before: 46 / 48 pass
>  Failures: TRACE_syscall.syscall_redirected,
> TRACE_syscall.syscall_dropped
>
> The subsequent patches fix issues that were causing the above tests to
> fail. With
> these fixes, the results are:
> 32bit kernel O32 userspace after: 48 / 48
> 64bit kernel O32 userspace after: 48 / 48
> 64bit kernel N32 userspace after: 48 / 48
> 64bit kernel N64 userspace after: 48 / 48
>
> Thanks,
> Matt
>
> Changes in v2:
> - Tested on additional platforms
> - Replace __NR_syscall which isn't defined for N32 / N64 ABIs
>
> Matt Redfearn (6):
>   selftests/seccomp: add MIPS self-test support
>   MIPS: Support sending SIG_SYS to 32bit userspace from 64bit kernel
>   MIPS: scall: Handle seccomp filters which redirect syscalls
>   seccomp: Get compat syscalls from asm-generic header
>   MIPS: seccomp: Support compat with both O32 and N32
>   secomp: Constify mode1 syscall whitelist
>
>  arch/mips/include/asm/seccomp.h               | 47 +++++++++++++++------------
>  arch/mips/kernel/scall32-o32.S                | 11 +++----
>  arch/mips/kernel/scall64-64.S                 |  3 +-
>  arch/mips/kernel/scall64-n32.S                | 14 +++++---
>  arch/mips/kernel/scall64-o32.S                | 14 +++++---
>  arch/mips/kernel/signal32.c                   |  6 ++++
>  include/asm-generic/seccomp.h                 | 14 ++++++++
>  kernel/seccomp.c                              | 13 ++------
>  tools/testing/selftests/seccomp/seccomp_bpf.c | 30 +++++++++++++++--
>  9 files changed, 101 insertions(+), 51 deletions(-)

Thanks for digging into this! Consider all the seccomp pieces:

Acked-by: Kees Cook <keescook@chromium.org>

Probably best to carry it all in the MIPS tree, but if you want to me
take pieces of it into my seccomp tree, I can do that. Up to you. :)

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/6] MIPS seccomp_bpf self test and fixups
  2016-03-30  5:06 ` [PATCH v2 0/6] MIPS seccomp_bpf self test and fixups Kees Cook
@ 2016-03-31  8:57     ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-31  8:57 UTC (permalink / raw)
  To: Kees Cook
  Cc: Linux MIPS Mailing List, Arnd Bergmann, Andy Lutomirski, LKML,
	Shuah Khan, Eric B Munson, James Hogan, Andrew Morton,
	linux-kselftest, linux-arch, Markos Chandras,
	Amanieu d'Antras, Ralf Baechle, Alex Smith, Paul Burton,
	Will Drewry



On 30/03/16 06:06, Kees Cook wrote:
> On Tue, Mar 29, 2016 at 1:35 AM, Matt Redfearn <matt.redfearn@imgtec.com> wrote:
>> These patches imporve seccomp support on MIPS.
>>
>> Firstly support is added for building the seccomp_bpf self test for
>> MIPS. The
>> initial results of these tests were:
>>
>> 32bit kernel O32 userspace before: 48 / 48 pass
>> 64bit kernel O32 userspace before: 47 / 48 pass
>>   Failures: TRAP.Handler
>> 64bit kernel N32 userspace before: 44 / 48 pass
>>   Failures: global.mode_strict_support, TRAP.handler,
>> TRACE_syscall.syscall_redirected, TRACE_syscall.syscall_dropped
>> 64bit kernel N64 userspace before: 46 / 48 pass
>>   Failures: TRACE_syscall.syscall_redirected,
>> TRACE_syscall.syscall_dropped
>>
>> The subsequent patches fix issues that were causing the above tests to
>> fail. With
>> these fixes, the results are:
>> 32bit kernel O32 userspace after: 48 / 48
>> 64bit kernel O32 userspace after: 48 / 48
>> 64bit kernel N32 userspace after: 48 / 48
>> 64bit kernel N64 userspace after: 48 / 48
>>
>> Thanks,
>> Matt
>>
>> Changes in v2:
>> - Tested on additional platforms
>> - Replace __NR_syscall which isn't defined for N32 / N64 ABIs
>>
>> Matt Redfearn (6):
>>    selftests/seccomp: add MIPS self-test support
>>    MIPS: Support sending SIG_SYS to 32bit userspace from 64bit kernel
>>    MIPS: scall: Handle seccomp filters which redirect syscalls
>>    seccomp: Get compat syscalls from asm-generic header
>>    MIPS: seccomp: Support compat with both O32 and N32
>>    secomp: Constify mode1 syscall whitelist
>>
>>   arch/mips/include/asm/seccomp.h               | 47 +++++++++++++++------------
>>   arch/mips/kernel/scall32-o32.S                | 11 +++----
>>   arch/mips/kernel/scall64-64.S                 |  3 +-
>>   arch/mips/kernel/scall64-n32.S                | 14 +++++---
>>   arch/mips/kernel/scall64-o32.S                | 14 +++++---
>>   arch/mips/kernel/signal32.c                   |  6 ++++
>>   include/asm-generic/seccomp.h                 | 14 ++++++++
>>   kernel/seccomp.c                              | 13 ++------
>>   tools/testing/selftests/seccomp/seccomp_bpf.c | 30 +++++++++++++++--
>>   9 files changed, 101 insertions(+), 51 deletions(-)
> Thanks for digging into this! Consider all the seccomp pieces:
>
> Acked-by: Kees Cook <keescook@chromium.org>
>
> Probably best to carry it all in the MIPS tree, but if you want to me
> take pieces of it into my seccomp tree, I can do that. Up to you. :)
>
> -Kees
>
Thanks Kees. Ralf is going to take it via the MIPS tree.

Matt

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/6] MIPS seccomp_bpf self test and fixups
@ 2016-03-31  8:57     ` Matt Redfearn
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Redfearn @ 2016-03-31  8:57 UTC (permalink / raw)
  To: Kees Cook
  Cc: Linux MIPS Mailing List, Arnd Bergmann, Andy Lutomirski, LKML,
	Shuah Khan, Eric B Munson, James Hogan, Andrew Morton,
	linux-kselftest, linux-arch, Markos Chandras,
	Amanieu d'Antras, Ralf Baechle, Alex Smith, Paul Burton,
	Will Drewry



On 30/03/16 06:06, Kees Cook wrote:
> On Tue, Mar 29, 2016 at 1:35 AM, Matt Redfearn <matt.redfearn@imgtec.com> wrote:
>> These patches imporve seccomp support on MIPS.
>>
>> Firstly support is added for building the seccomp_bpf self test for
>> MIPS. The
>> initial results of these tests were:
>>
>> 32bit kernel O32 userspace before: 48 / 48 pass
>> 64bit kernel O32 userspace before: 47 / 48 pass
>>   Failures: TRAP.Handler
>> 64bit kernel N32 userspace before: 44 / 48 pass
>>   Failures: global.mode_strict_support, TRAP.handler,
>> TRACE_syscall.syscall_redirected, TRACE_syscall.syscall_dropped
>> 64bit kernel N64 userspace before: 46 / 48 pass
>>   Failures: TRACE_syscall.syscall_redirected,
>> TRACE_syscall.syscall_dropped
>>
>> The subsequent patches fix issues that were causing the above tests to
>> fail. With
>> these fixes, the results are:
>> 32bit kernel O32 userspace after: 48 / 48
>> 64bit kernel O32 userspace after: 48 / 48
>> 64bit kernel N32 userspace after: 48 / 48
>> 64bit kernel N64 userspace after: 48 / 48
>>
>> Thanks,
>> Matt
>>
>> Changes in v2:
>> - Tested on additional platforms
>> - Replace __NR_syscall which isn't defined for N32 / N64 ABIs
>>
>> Matt Redfearn (6):
>>    selftests/seccomp: add MIPS self-test support
>>    MIPS: Support sending SIG_SYS to 32bit userspace from 64bit kernel
>>    MIPS: scall: Handle seccomp filters which redirect syscalls
>>    seccomp: Get compat syscalls from asm-generic header
>>    MIPS: seccomp: Support compat with both O32 and N32
>>    secomp: Constify mode1 syscall whitelist
>>
>>   arch/mips/include/asm/seccomp.h               | 47 +++++++++++++++------------
>>   arch/mips/kernel/scall32-o32.S                | 11 +++----
>>   arch/mips/kernel/scall64-64.S                 |  3 +-
>>   arch/mips/kernel/scall64-n32.S                | 14 +++++---
>>   arch/mips/kernel/scall64-o32.S                | 14 +++++---
>>   arch/mips/kernel/signal32.c                   |  6 ++++
>>   include/asm-generic/seccomp.h                 | 14 ++++++++
>>   kernel/seccomp.c                              | 13 ++------
>>   tools/testing/selftests/seccomp/seccomp_bpf.c | 30 +++++++++++++++--
>>   9 files changed, 101 insertions(+), 51 deletions(-)
> Thanks for digging into this! Consider all the seccomp pieces:
>
> Acked-by: Kees Cook <keescook@chromium.org>
>
> Probably best to carry it all in the MIPS tree, but if you want to me
> take pieces of it into my seccomp tree, I can do that. Up to you. :)
>
> -Kees
>
Thanks Kees. Ralf is going to take it via the MIPS tree.

Matt

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2016-03-31  8:57 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-29  8:35 [PATCH v2 0/6] MIPS seccomp_bpf self test and fixups Matt Redfearn
2016-03-29  8:35 ` Matt Redfearn
2016-03-29  8:35 ` [PATCH v2 1/6] selftests/seccomp: add MIPS self-test support Matt Redfearn
2016-03-29  8:35   ` Matt Redfearn
2016-03-29  8:35 ` [PATCH v2 2/6] MIPS: Support sending SIG_SYS to 32bit userspace from 64bit kernel Matt Redfearn
2016-03-29  8:35   ` Matt Redfearn
2016-03-29  8:35 ` [PATCH v2 3/6] MIPS: scall: Handle seccomp filters which redirect syscalls Matt Redfearn
2016-03-29  8:35   ` Matt Redfearn
2016-03-29  8:35 ` [PATCH v2 4/6] seccomp: Get compat syscalls from asm-generic header Matt Redfearn
2016-03-29  8:35   ` Matt Redfearn
2016-03-29  8:35 ` [PATCH v2 5/6] MIPS: seccomp: Support compat with both O32 and N32 Matt Redfearn
2016-03-29  8:35   ` Matt Redfearn
2016-03-29  8:35 ` [PATCH v2 6/6] secomp: Constify mode1 syscall whitelist Matt Redfearn
2016-03-29  8:35   ` Matt Redfearn
2016-03-30  5:06 ` [PATCH v2 0/6] MIPS seccomp_bpf self test and fixups Kees Cook
2016-03-31  8:57   ` Matt Redfearn
2016-03-31  8:57     ` Matt Redfearn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.