Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1359653 > unrolled thread

[PATCH] selftests/seccomp: add MIPS self-test support

Started byMatt Redfearn <matt.redfearn@imgtec.com>
First post2016-03-17 10:30 +0100
Last post2016-03-21 20:50 +0100
Articles 2 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH] selftests/seccomp: add MIPS self-test support Matt Redfearn <matt.redfearn@imgtec.com> - 2016-03-17 10:30 +0100
    Re: [PATCH] selftests/seccomp: add MIPS self-test support Kees Cook <keescook@chromium.org> - 2016-03-21 20:50 +0100

#1359653 — [PATCH] selftests/seccomp: add MIPS self-test support

FromMatt Redfearn <matt.redfearn@imgtec.com>
Date2016-03-17 10:30 +0100
Subject[PATCH] selftests/seccomp: add MIPS self-test support
Message-ID<rdCpJ-5uU-15@gated-at.bofh.it>
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 with an O32 userland where 48/48 tests now pass.

Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
---
 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..92862c828c4a 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_syscall)
+		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_syscall)
+			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

[toc] | [next] | [standalone]


#1362113

FromKees Cook <keescook@chromium.org>
Date2016-03-21 20:50 +0100
Message-ID<rfdZU-1O7-1@gated-at.bofh.it>
In reply to#1359653
On Thu, Mar 17, 2016 at 2:26 AM, Matt Redfearn <matt.redfearn@imgtec.com> wrote:
> 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.

I wonder how s390 deals with sharing the register? Seems like it
should be failing the same test in the same way.

> Tested on MIPS32r2 with an O32 userland where 48/48 tests now pass.
>
> Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
> ---
>  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..92862c828c4a 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_syscall)
> +               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_syscall)
> +                       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
>

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

Thanks!

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web