* [PATCH v2 0/4] um: Add seccomp support
@ 2015-12-21 19:29 ` Mickaël Salaün
0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 19:29 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff, David Drysdale
This series add seccomp support to User-mode Linux (i386 and x86_64
subarchitectures) and fix ptrace issues. This apply on v4.4-rc4 and pass all
the 48 tests from selftest/seccomp plus the UML ptsc test.
Changes since v1; addressed Richard Weinberger's comments:
* fix a new PTRACE_SETREGS bug on x86_64 [1/4]
* fix an old PTRACE_SETREGS bug when updating orig_ax on i386 [1/4]
Regards,
Mickaël
Mickaël Salaün (4):
um: Fix ptrace GETREGS/SETREGS bugs
selftests/seccomp: Remove the need for HAVE_ARCH_TRACEHOOK
um: Add full asm/syscall.h support
um: Add seccomp support
.../seccomp/seccomp-filter/arch-support.txt | 2 +-
arch/um/Kconfig.common | 1 +
arch/um/Kconfig.um | 16 +++
arch/um/include/asm/syscall-generic.h | 138 +++++++++++++++++++++
arch/um/include/asm/thread_info.h | 2 +
arch/um/kernel/skas/syscall.c | 30 +++--
arch/um/os-Linux/skas/process.c | 7 --
arch/x86/um/asm/syscall.h | 1 +
arch/x86/um/ptrace_32.c | 8 +-
tools/testing/selftests/seccomp/seccomp_bpf.c | 27 +++-
10 files changed, 205 insertions(+), 27 deletions(-)
create mode 100644 arch/um/include/asm/syscall-generic.h
--
2.6.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 0/4] um: Add seccomp support
@ 2015-12-21 19:29 ` Mickaël Salaün
0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 19:29 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff
This series add seccomp support to User-mode Linux (i386 and x86_64
subarchitectures) and fix ptrace issues. This apply on v4.4-rc4 and pass all
the 48 tests from selftest/seccomp plus the UML ptsc test.
Changes since v1; addressed Richard Weinberger's comments:
* fix a new PTRACE_SETREGS bug on x86_64 [1/4]
* fix an old PTRACE_SETREGS bug when updating orig_ax on i386 [1/4]
Regards,
Mickaël
Mickaël Salaün (4):
um: Fix ptrace GETREGS/SETREGS bugs
selftests/seccomp: Remove the need for HAVE_ARCH_TRACEHOOK
um: Add full asm/syscall.h support
um: Add seccomp support
.../seccomp/seccomp-filter/arch-support.txt | 2 +-
arch/um/Kconfig.common | 1 +
arch/um/Kconfig.um | 16 +++
arch/um/include/asm/syscall-generic.h | 138 +++++++++++++++++++++
arch/um/include/asm/thread_info.h | 2 +
arch/um/kernel/skas/syscall.c | 30 +++--
arch/um/os-Linux/skas/process.c | 7 --
arch/x86/um/asm/syscall.h | 1 +
arch/x86/um/ptrace_32.c | 8 +-
tools/testing/selftests/seccomp/seccomp_bpf.c | 27 +++-
10 files changed, 205 insertions(+), 27 deletions(-)
create mode 100644 arch/um/include/asm/syscall-generic.h
--
2.6.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 0/4] um: Add seccomp support
@ 2015-12-21 19:29 ` Mickaël Salaün
0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 19:29 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff, David Drysdale
This series add seccomp support to User-mode Linux (i386 and x86_64
subarchitectures) and fix ptrace issues. This apply on v4.4-rc4 and pass all
the 48 tests from selftest/seccomp plus the UML ptsc test.
Changes since v1; addressed Richard Weinberger's comments:
* fix a new PTRACE_SETREGS bug on x86_64 [1/4]
* fix an old PTRACE_SETREGS bug when updating orig_ax on i386 [1/4]
Regards,
Mickaël
Mickaël Salaün (4):
um: Fix ptrace GETREGS/SETREGS bugs
selftests/seccomp: Remove the need for HAVE_ARCH_TRACEHOOK
um: Add full asm/syscall.h support
um: Add seccomp support
.../seccomp/seccomp-filter/arch-support.txt | 2 +-
arch/um/Kconfig.common | 1 +
arch/um/Kconfig.um | 16 +++
arch/um/include/asm/syscall-generic.h | 138 +++++++++++++++++++++
arch/um/include/asm/thread_info.h | 2 +
arch/um/kernel/skas/syscall.c | 30 +++--
arch/um/os-Linux/skas/process.c | 7 --
arch/x86/um/asm/syscall.h | 1 +
arch/x86/um/ptrace_32.c | 8 +-
tools/testing/selftests/seccomp/seccomp_bpf.c | 27 +++-
10 files changed, 205 insertions(+), 27 deletions(-)
create mode 100644 arch/um/include/asm/syscall-generic.h
--
2.6.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 1/4] um: Fix ptrace GETREGS/SETREGS bugs
2015-12-21 19:29 ` Mickaël Salaün
(?)
@ 2015-12-21 19:29 ` Mickaël Salaün
-1 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 19:29 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff, David Drysdale
This fix two related bugs:
* PTRACE_GETREGS doesn't get the right orig_ax (syscall) value
* PTRACE_SETREGS can't set the orig_ax value (erased by initial value)
Remove the now useless and error-prone get_syscall().
Fix inconsistent behavior in the ptrace implementation for i386 when
updating orig_eax automatically update the syscall number as well. This
is now updated in handle_syscall().
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Thomas Meyer <thomas@m3y3r.de>
Cc: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
Cc: Anton Ivanov <aivanov@brocade.com>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
arch/um/kernel/skas/syscall.c | 25 ++++++++++++++-----------
arch/um/os-Linux/skas/process.c | 7 -------
arch/x86/um/ptrace_32.c | 8 +++-----
3 files changed, 17 insertions(+), 23 deletions(-)
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 1683b8e..0d624e0 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -7,29 +7,32 @@
#include <linux/ptrace.h>
#include <kern_util.h>
#include <sysdep/ptrace.h>
+#include <sysdep/ptrace_user.h>
#include <sysdep/syscalls.h>
#include <os.h>
void handle_syscall(struct uml_pt_regs *r)
{
struct pt_regs *regs = container_of(r, struct pt_regs, regs);
- long result;
int syscall;
- if (syscall_trace_enter(regs)) {
- result = -ENOSYS;
+ /* Initialize the syscall number and default return value. */
+ UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
+ PT_REGS_SET_SYSCALL_RETURN(regs, -ENOSYS);
+
+ if (syscall_trace_enter(regs))
goto out;
- }
- syscall = get_syscall(r);
+ /* Update the syscall number after orig_ax has potentially been updated
+ * with ptrace.
+ */
+ UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
+ syscall = UPT_SYSCALL_NR(r);
- if ((syscall > __NR_syscall_max) || syscall < 0)
- result = -ENOSYS;
- else
- result = EXECUTE_SYSCALL(syscall, regs);
+ if (syscall >= 0 && syscall <= __NR_syscall_max)
+ PT_REGS_SET_SYSCALL_RETURN(regs,
+ EXECUTE_SYSCALL(syscall, regs));
out:
- PT_REGS_SET_SYSCALL_RETURN(regs, result);
-
syscall_trace_leave(regs);
}
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index b856c66..23025d6 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -172,13 +172,6 @@ static void handle_trap(int pid, struct uml_pt_regs *regs,
handle_syscall(regs);
}
-int get_syscall(struct uml_pt_regs *regs)
-{
- UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp);
-
- return UPT_SYSCALL_NR(regs);
-}
-
extern char __syscall_stub_start[];
static int userspace_tramp(void *stack)
diff --git a/arch/x86/um/ptrace_32.c b/arch/x86/um/ptrace_32.c
index a29756f..47c78d5 100644
--- a/arch/x86/um/ptrace_32.c
+++ b/arch/x86/um/ptrace_32.c
@@ -68,6 +68,7 @@ static const int reg_offsets[] = {
[EFL] = HOST_EFLAGS,
[UESP] = HOST_SP,
[SS] = HOST_SS,
+ [ORIG_EAX] = HOST_ORIG_AX,
};
int putreg(struct task_struct *child, int regno, unsigned long value)
@@ -83,6 +84,7 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
case EAX:
case EIP:
case UESP:
+ case ORIG_EAX:
break;
case FS:
if (value && (value & 3) != 3)
@@ -108,9 +110,6 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
value &= FLAG_MASK;
child->thread.regs.regs.gp[HOST_EFLAGS] |= value;
return 0;
- case ORIG_EAX:
- child->thread.regs.regs.syscall = value;
- return 0;
default :
panic("Bad register in putreg() : %d\n", regno);
}
@@ -143,8 +142,6 @@ unsigned long getreg(struct task_struct *child, int regno)
regno >>= 2;
switch (regno) {
- case ORIG_EAX:
- return child->thread.regs.regs.syscall;
case FS:
case GS:
case DS:
@@ -163,6 +160,7 @@ unsigned long getreg(struct task_struct *child, int regno)
case EDI:
case EBP:
case EFL:
+ case ORIG_EAX:
break;
default:
panic("Bad register in getreg() : %d\n", regno);
--
2.6.4
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 1/4] um: Fix ptrace GETREGS/SETREGS bugs
@ 2015-12-21 19:29 ` Mickaël Salaün
0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 19:29 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff
This fix two related bugs:
* PTRACE_GETREGS doesn't get the right orig_ax (syscall) value
* PTRACE_SETREGS can't set the orig_ax value (erased by initial value)
Remove the now useless and error-prone get_syscall().
Fix inconsistent behavior in the ptrace implementation for i386 when
updating orig_eax automatically update the syscall number as well. This
is now updated in handle_syscall().
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Thomas Meyer <thomas@m3y3r.de>
Cc: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
Cc: Anton Ivanov <aivanov@brocade.com>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
arch/um/kernel/skas/syscall.c | 25 ++++++++++++++-----------
arch/um/os-Linux/skas/process.c | 7 -------
arch/x86/um/ptrace_32.c | 8 +++-----
3 files changed, 17 insertions(+), 23 deletions(-)
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 1683b8e..0d624e0 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -7,29 +7,32 @@
#include <linux/ptrace.h>
#include <kern_util.h>
#include <sysdep/ptrace.h>
+#include <sysdep/ptrace_user.h>
#include <sysdep/syscalls.h>
#include <os.h>
void handle_syscall(struct uml_pt_regs *r)
{
struct pt_regs *regs = container_of(r, struct pt_regs, regs);
- long result;
int syscall;
- if (syscall_trace_enter(regs)) {
- result = -ENOSYS;
+ /* Initialize the syscall number and default return value. */
+ UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
+ PT_REGS_SET_SYSCALL_RETURN(regs, -ENOSYS);
+
+ if (syscall_trace_enter(regs))
goto out;
- }
- syscall = get_syscall(r);
+ /* Update the syscall number after orig_ax has potentially been updated
+ * with ptrace.
+ */
+ UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
+ syscall = UPT_SYSCALL_NR(r);
- if ((syscall > __NR_syscall_max) || syscall < 0)
- result = -ENOSYS;
- else
- result = EXECUTE_SYSCALL(syscall, regs);
+ if (syscall >= 0 && syscall <= __NR_syscall_max)
+ PT_REGS_SET_SYSCALL_RETURN(regs,
+ EXECUTE_SYSCALL(syscall, regs));
out:
- PT_REGS_SET_SYSCALL_RETURN(regs, result);
-
syscall_trace_leave(regs);
}
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index b856c66..23025d6 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -172,13 +172,6 @@ static void handle_trap(int pid, struct uml_pt_regs *regs,
handle_syscall(regs);
}
-int get_syscall(struct uml_pt_regs *regs)
-{
- UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp);
-
- return UPT_SYSCALL_NR(regs);
-}
-
extern char __syscall_stub_start[];
static int userspace_tramp(void *stack)
diff --git a/arch/x86/um/ptrace_32.c b/arch/x86/um/ptrace_32.c
index a29756f..47c78d5 100644
--- a/arch/x86/um/ptrace_32.c
+++ b/arch/x86/um/ptrace_32.c
@@ -68,6 +68,7 @@ static const int reg_offsets[] = {
[EFL] = HOST_EFLAGS,
[UESP] = HOST_SP,
[SS] = HOST_SS,
+ [ORIG_EAX] = HOST_ORIG_AX,
};
int putreg(struct task_struct *child, int regno, unsigned long value)
@@ -83,6 +84,7 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
case EAX:
case EIP:
case UESP:
+ case ORIG_EAX:
break;
case FS:
if (value && (value & 3) != 3)
@@ -108,9 +110,6 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
value &= FLAG_MASK;
child->thread.regs.regs.gp[HOST_EFLAGS] |= value;
return 0;
- case ORIG_EAX:
- child->thread.regs.regs.syscall = value;
- return 0;
default :
panic("Bad register in putreg() : %d\n", regno);
}
@@ -143,8 +142,6 @@ unsigned long getreg(struct task_struct *child, int regno)
regno >>= 2;
switch (regno) {
- case ORIG_EAX:
- return child->thread.regs.regs.syscall;
case FS:
case GS:
case DS:
@@ -163,6 +160,7 @@ unsigned long getreg(struct task_struct *child, int regno)
case EDI:
case EBP:
case EFL:
+ case ORIG_EAX:
break;
default:
panic("Bad register in getreg() : %d\n", regno);
--
2.6.4
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 1/4] um: Fix ptrace GETREGS/SETREGS bugs
@ 2015-12-21 19:29 ` Mickaël Salaün
0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 19:29 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff, David Drysdale
This fix two related bugs:
* PTRACE_GETREGS doesn't get the right orig_ax (syscall) value
* PTRACE_SETREGS can't set the orig_ax value (erased by initial value)
Remove the now useless and error-prone get_syscall().
Fix inconsistent behavior in the ptrace implementation for i386 when
updating orig_eax automatically update the syscall number as well. This
is now updated in handle_syscall().
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Thomas Meyer <thomas@m3y3r.de>
Cc: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
Cc: Anton Ivanov <aivanov@brocade.com>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
arch/um/kernel/skas/syscall.c | 25 ++++++++++++++-----------
arch/um/os-Linux/skas/process.c | 7 -------
arch/x86/um/ptrace_32.c | 8 +++-----
3 files changed, 17 insertions(+), 23 deletions(-)
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 1683b8e..0d624e0 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -7,29 +7,32 @@
#include <linux/ptrace.h>
#include <kern_util.h>
#include <sysdep/ptrace.h>
+#include <sysdep/ptrace_user.h>
#include <sysdep/syscalls.h>
#include <os.h>
void handle_syscall(struct uml_pt_regs *r)
{
struct pt_regs *regs = container_of(r, struct pt_regs, regs);
- long result;
int syscall;
- if (syscall_trace_enter(regs)) {
- result = -ENOSYS;
+ /* Initialize the syscall number and default return value. */
+ UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
+ PT_REGS_SET_SYSCALL_RETURN(regs, -ENOSYS);
+
+ if (syscall_trace_enter(regs))
goto out;
- }
- syscall = get_syscall(r);
+ /* Update the syscall number after orig_ax has potentially been updated
+ * with ptrace.
+ */
+ UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
+ syscall = UPT_SYSCALL_NR(r);
- if ((syscall > __NR_syscall_max) || syscall < 0)
- result = -ENOSYS;
- else
- result = EXECUTE_SYSCALL(syscall, regs);
+ if (syscall >= 0 && syscall <= __NR_syscall_max)
+ PT_REGS_SET_SYSCALL_RETURN(regs,
+ EXECUTE_SYSCALL(syscall, regs));
out:
- PT_REGS_SET_SYSCALL_RETURN(regs, result);
-
syscall_trace_leave(regs);
}
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index b856c66..23025d6 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -172,13 +172,6 @@ static void handle_trap(int pid, struct uml_pt_regs *regs,
handle_syscall(regs);
}
-int get_syscall(struct uml_pt_regs *regs)
-{
- UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp);
-
- return UPT_SYSCALL_NR(regs);
-}
-
extern char __syscall_stub_start[];
static int userspace_tramp(void *stack)
diff --git a/arch/x86/um/ptrace_32.c b/arch/x86/um/ptrace_32.c
index a29756f..47c78d5 100644
--- a/arch/x86/um/ptrace_32.c
+++ b/arch/x86/um/ptrace_32.c
@@ -68,6 +68,7 @@ static const int reg_offsets[] = {
[EFL] = HOST_EFLAGS,
[UESP] = HOST_SP,
[SS] = HOST_SS,
+ [ORIG_EAX] = HOST_ORIG_AX,
};
int putreg(struct task_struct *child, int regno, unsigned long value)
@@ -83,6 +84,7 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
case EAX:
case EIP:
case UESP:
+ case ORIG_EAX:
break;
case FS:
if (value && (value & 3) != 3)
@@ -108,9 +110,6 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
value &= FLAG_MASK;
child->thread.regs.regs.gp[HOST_EFLAGS] |= value;
return 0;
- case ORIG_EAX:
- child->thread.regs.regs.syscall = value;
- return 0;
default :
panic("Bad register in putreg() : %d\n", regno);
}
@@ -143,8 +142,6 @@ unsigned long getreg(struct task_struct *child, int regno)
regno >>= 2;
switch (regno) {
- case ORIG_EAX:
- return child->thread.regs.regs.syscall;
case FS:
case GS:
case DS:
@@ -163,6 +160,7 @@ unsigned long getreg(struct task_struct *child, int regno)
case EDI:
case EBP:
case EFL:
+ case ORIG_EAX:
break;
default:
panic("Bad register in getreg() : %d\n", regno);
--
2.6.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 2/4] selftests/seccomp: Remove the need for HAVE_ARCH_TRACEHOOK
2015-12-21 19:29 ` Mickaël Salaün
(?)
@ 2015-12-21 19:29 ` Mickaël Salaün
-1 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 19:29 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff, David Drysdale
Some architectures do not implement PTRACE_GETREGSET nor
PTRACE_SETREGSET (required by HAVE_ARCH_TRACEHOOK) but only implement
PTRACE_GETREGS and PTRACE_SETREGS (e.g. User-mode Linux).
This improve seccomp selftest portability for architectures without
HAVE_ARCH_TRACEHOOK support by defining a new trigger HAVE_GETREGS. For
now, this is only enabled for i386 and x86_64 architectures. This is
required to be able to run this tests on User-mode Linux.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
tools/testing/selftests/seccomp/seccomp_bpf.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 882fe83..b9453b8 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -1246,11 +1246,24 @@ TEST_F(TRACE_poke, getpid_runs_normally)
# error "Do not know how to find your architecture's registers and syscalls"
#endif
+/* 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__)
+#define HAVE_GETREGS
+#endif
+
/* Architecture-specific syscall fetching routine. */
int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
{
- struct iovec iov;
ARCH_REGS regs;
+#ifdef HAVE_GETREGS
+ EXPECT_EQ(0, ptrace(PTRACE_GETREGS, tracee, 0, ®s)) {
+ TH_LOG("PTRACE_GETREGS failed");
+ return -1;
+ }
+#else
+ struct iovec iov;
iov.iov_base = ®s;
iov.iov_len = sizeof(regs);
@@ -1258,6 +1271,7 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
TH_LOG("PTRACE_GETREGSET failed");
return -1;
}
+#endif
return regs.SYSCALL_NUM;
}
@@ -1266,13 +1280,16 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
void change_syscall(struct __test_metadata *_metadata,
pid_t tracee, int syscall)
{
- struct iovec iov;
int ret;
ARCH_REGS regs;
-
+#ifdef HAVE_GETREGS
+ ret = ptrace(PTRACE_GETREGS, tracee, 0, ®s);
+#else
+ struct iovec iov;
iov.iov_base = ®s;
iov.iov_len = sizeof(regs);
ret = ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &iov);
+#endif
EXPECT_EQ(0, ret);
#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \
@@ -1312,9 +1329,13 @@ void change_syscall(struct __test_metadata *_metadata,
if (syscall == -1)
regs.SYSCALL_RET = 1;
+#ifdef HAVE_GETREGS
+ ret = ptrace(PTRACE_SETREGS, tracee, 0, ®s);
+#else
iov.iov_base = ®s;
iov.iov_len = sizeof(regs);
ret = ptrace(PTRACE_SETREGSET, tracee, NT_PRSTATUS, &iov);
+#endif
EXPECT_EQ(0, ret);
}
--
2.6.4
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 2/4] selftests/seccomp: Remove the need for HAVE_ARCH_TRACEHOOK
@ 2015-12-21 19:29 ` Mickaël Salaün
0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 19:29 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff
Some architectures do not implement PTRACE_GETREGSET nor
PTRACE_SETREGSET (required by HAVE_ARCH_TRACEHOOK) but only implement
PTRACE_GETREGS and PTRACE_SETREGS (e.g. User-mode Linux).
This improve seccomp selftest portability for architectures without
HAVE_ARCH_TRACEHOOK support by defining a new trigger HAVE_GETREGS. For
now, this is only enabled for i386 and x86_64 architectures. This is
required to be able to run this tests on User-mode Linux.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
tools/testing/selftests/seccomp/seccomp_bpf.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 882fe83..b9453b8 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -1246,11 +1246,24 @@ TEST_F(TRACE_poke, getpid_runs_normally)
# error "Do not know how to find your architecture's registers and syscalls"
#endif
+/* 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__)
+#define HAVE_GETREGS
+#endif
+
/* Architecture-specific syscall fetching routine. */
int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
{
- struct iovec iov;
ARCH_REGS regs;
+#ifdef HAVE_GETREGS
+ EXPECT_EQ(0, ptrace(PTRACE_GETREGS, tracee, 0, ®s)) {
+ TH_LOG("PTRACE_GETREGS failed");
+ return -1;
+ }
+#else
+ struct iovec iov;
iov.iov_base = ®s;
iov.iov_len = sizeof(regs);
@@ -1258,6 +1271,7 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
TH_LOG("PTRACE_GETREGSET failed");
return -1;
}
+#endif
return regs.SYSCALL_NUM;
}
@@ -1266,13 +1280,16 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
void change_syscall(struct __test_metadata *_metadata,
pid_t tracee, int syscall)
{
- struct iovec iov;
int ret;
ARCH_REGS regs;
-
+#ifdef HAVE_GETREGS
+ ret = ptrace(PTRACE_GETREGS, tracee, 0, ®s);
+#else
+ struct iovec iov;
iov.iov_base = ®s;
iov.iov_len = sizeof(regs);
ret = ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &iov);
+#endif
EXPECT_EQ(0, ret);
#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \
@@ -1312,9 +1329,13 @@ void change_syscall(struct __test_metadata *_metadata,
if (syscall == -1)
regs.SYSCALL_RET = 1;
+#ifdef HAVE_GETREGS
+ ret = ptrace(PTRACE_SETREGS, tracee, 0, ®s);
+#else
iov.iov_base = ®s;
iov.iov_len = sizeof(regs);
ret = ptrace(PTRACE_SETREGSET, tracee, NT_PRSTATUS, &iov);
+#endif
EXPECT_EQ(0, ret);
}
--
2.6.4
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 2/4] selftests/seccomp: Remove the need for HAVE_ARCH_TRACEHOOK
@ 2015-12-21 19:29 ` Mickaël Salaün
0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 19:29 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff, David Drysdale
Some architectures do not implement PTRACE_GETREGSET nor
PTRACE_SETREGSET (required by HAVE_ARCH_TRACEHOOK) but only implement
PTRACE_GETREGS and PTRACE_SETREGS (e.g. User-mode Linux).
This improve seccomp selftest portability for architectures without
HAVE_ARCH_TRACEHOOK support by defining a new trigger HAVE_GETREGS. For
now, this is only enabled for i386 and x86_64 architectures. This is
required to be able to run this tests on User-mode Linux.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
tools/testing/selftests/seccomp/seccomp_bpf.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 882fe83..b9453b8 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -1246,11 +1246,24 @@ TEST_F(TRACE_poke, getpid_runs_normally)
# error "Do not know how to find your architecture's registers and syscalls"
#endif
+/* 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__)
+#define HAVE_GETREGS
+#endif
+
/* Architecture-specific syscall fetching routine. */
int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
{
- struct iovec iov;
ARCH_REGS regs;
+#ifdef HAVE_GETREGS
+ EXPECT_EQ(0, ptrace(PTRACE_GETREGS, tracee, 0, ®s)) {
+ TH_LOG("PTRACE_GETREGS failed");
+ return -1;
+ }
+#else
+ struct iovec iov;
iov.iov_base = ®s;
iov.iov_len = sizeof(regs);
@@ -1258,6 +1271,7 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
TH_LOG("PTRACE_GETREGSET failed");
return -1;
}
+#endif
return regs.SYSCALL_NUM;
}
@@ -1266,13 +1280,16 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
void change_syscall(struct __test_metadata *_metadata,
pid_t tracee, int syscall)
{
- struct iovec iov;
int ret;
ARCH_REGS regs;
-
+#ifdef HAVE_GETREGS
+ ret = ptrace(PTRACE_GETREGS, tracee, 0, ®s);
+#else
+ struct iovec iov;
iov.iov_base = ®s;
iov.iov_len = sizeof(regs);
ret = ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &iov);
+#endif
EXPECT_EQ(0, ret);
#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \
@@ -1312,9 +1329,13 @@ void change_syscall(struct __test_metadata *_metadata,
if (syscall == -1)
regs.SYSCALL_RET = 1;
+#ifdef HAVE_GETREGS
+ ret = ptrace(PTRACE_SETREGS, tracee, 0, ®s);
+#else
iov.iov_base = ®s;
iov.iov_len = sizeof(regs);
ret = ptrace(PTRACE_SETREGSET, tracee, NT_PRSTATUS, &iov);
+#endif
EXPECT_EQ(0, ret);
}
--
2.6.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 3/4] um: Add full asm/syscall.h support
2015-12-21 19:29 ` Mickaël Salaün
(?)
@ 2015-12-21 20:26 ` Mickaël Salaün
-1 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 20:26 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff, David Drysdale
Add subarchitecture-independent implementation of asm-generic/syscall.h
allowing access to user system call parameters and results:
* syscall_get_nr()
* syscall_rollback()
* syscall_get_error()
* syscall_get_return_value()
* syscall_set_return_value()
* syscall_get_arguments()
* syscall_set_arguments()
* syscall_get_arch() provided by arch/x86/um/asm/syscall.h
This provides the necessary syscall helpers needed by
HAVE_ARCH_SECCOMP_FILTER plus syscall_get_error().
This is inspired from Meredydd Luff's patch
(https://gerrit.chromium.org/gerrit/21425).
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
arch/um/include/asm/syscall-generic.h | 138 ++++++++++++++++++++++++++++++++++
arch/x86/um/asm/syscall.h | 1 +
2 files changed, 139 insertions(+)
create mode 100644 arch/um/include/asm/syscall-generic.h
diff --git a/arch/um/include/asm/syscall-generic.h b/arch/um/include/asm/syscall-generic.h
new file mode 100644
index 0000000..9fb9cf8
--- /dev/null
+++ b/arch/um/include/asm/syscall-generic.h
@@ -0,0 +1,138 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * See asm-generic/syscall.h for function descriptions.
+ *
+ * Copyright (C) 2015 Mickaël Salaün <mic@digikod.net>
+ *
+ * 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 __UM_SYSCALL_GENERIC_H
+#define __UM_SYSCALL_GENERIC_H
+
+#include <asm/ptrace.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <sysdep/ptrace.h>
+
+static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+
+ return PT_REGS_SYSCALL_NR(regs);
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ /* do nothing */
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ const long error = regs_return_value(regs);
+
+ return IS_ERR_VALUE(error) ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs_return_value(regs);
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ PT_REGS_SET_SYSCALL_RETURN(regs, (long) error ?: val);
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ const struct uml_pt_regs *r = ®s->regs;
+
+ switch (i) {
+ case 0:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG1(r);
+ case 1:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG2(r);
+ case 2:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG3(r);
+ case 3:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG4(r);
+ case 4:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG5(r);
+ case 5:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG6(r);
+ case 6:
+ if (!n--)
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ struct uml_pt_regs *r = ®s->regs;
+
+ switch (i) {
+ case 0:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG1(r) = *args++;
+ case 1:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG2(r) = *args++;
+ case 2:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG3(r) = *args++;
+ case 3:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG4(r) = *args++;
+ case 4:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG5(r) = *args++;
+ case 5:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG6(r) = *args++;
+ case 6:
+ if (!n--)
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+/* See arch/x86/um/asm/syscall.h for syscall_get_arch() definition. */
+
+#endif /* __UM_SYSCALL_GENERIC_H */
diff --git a/arch/x86/um/asm/syscall.h b/arch/x86/um/asm/syscall.h
index 81d6562..11ab90d 100644
--- a/arch/x86/um/asm/syscall.h
+++ b/arch/x86/um/asm/syscall.h
@@ -1,6 +1,7 @@
#ifndef __UM_ASM_SYSCALL_H
#define __UM_ASM_SYSCALL_H
+#include <asm/syscall-generic.h>
#include <uapi/linux/audit.h>
typedef asmlinkage long (*sys_call_ptr_t)(unsigned long, unsigned long,
--
2.6.4
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 3/4] um: Add full asm/syscall.h support
@ 2015-12-21 20:26 ` Mickaël Salaün
0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 20:26 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff
Add subarchitecture-independent implementation of asm-generic/syscall.h
allowing access to user system call parameters and results:
* syscall_get_nr()
* syscall_rollback()
* syscall_get_error()
* syscall_get_return_value()
* syscall_set_return_value()
* syscall_get_arguments()
* syscall_set_arguments()
* syscall_get_arch() provided by arch/x86/um/asm/syscall.h
This provides the necessary syscall helpers needed by
HAVE_ARCH_SECCOMP_FILTER plus syscall_get_error().
This is inspired from Meredydd Luff's patch
(https://gerrit.chromium.org/gerrit/21425).
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
arch/um/include/asm/syscall-generic.h | 138 ++++++++++++++++++++++++++++++++++
arch/x86/um/asm/syscall.h | 1 +
2 files changed, 139 insertions(+)
create mode 100644 arch/um/include/asm/syscall-generic.h
diff --git a/arch/um/include/asm/syscall-generic.h b/arch/um/include/asm/syscall-generic.h
new file mode 100644
index 0000000..9fb9cf8
--- /dev/null
+++ b/arch/um/include/asm/syscall-generic.h
@@ -0,0 +1,138 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * See asm-generic/syscall.h for function descriptions.
+ *
+ * Copyright (C) 2015 Mickaël Salaün <mic@digikod.net>
+ *
+ * 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 __UM_SYSCALL_GENERIC_H
+#define __UM_SYSCALL_GENERIC_H
+
+#include <asm/ptrace.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <sysdep/ptrace.h>
+
+static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+
+ return PT_REGS_SYSCALL_NR(regs);
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ /* do nothing */
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ const long error = regs_return_value(regs);
+
+ return IS_ERR_VALUE(error) ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs_return_value(regs);
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ PT_REGS_SET_SYSCALL_RETURN(regs, (long) error ?: val);
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ const struct uml_pt_regs *r = ®s->regs;
+
+ switch (i) {
+ case 0:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG1(r);
+ case 1:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG2(r);
+ case 2:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG3(r);
+ case 3:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG4(r);
+ case 4:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG5(r);
+ case 5:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG6(r);
+ case 6:
+ if (!n--)
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ struct uml_pt_regs *r = ®s->regs;
+
+ switch (i) {
+ case 0:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG1(r) = *args++;
+ case 1:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG2(r) = *args++;
+ case 2:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG3(r) = *args++;
+ case 3:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG4(r) = *args++;
+ case 4:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG5(r) = *args++;
+ case 5:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG6(r) = *args++;
+ case 6:
+ if (!n--)
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+/* See arch/x86/um/asm/syscall.h for syscall_get_arch() definition. */
+
+#endif /* __UM_SYSCALL_GENERIC_H */
diff --git a/arch/x86/um/asm/syscall.h b/arch/x86/um/asm/syscall.h
index 81d6562..11ab90d 100644
--- a/arch/x86/um/asm/syscall.h
+++ b/arch/x86/um/asm/syscall.h
@@ -1,6 +1,7 @@
#ifndef __UM_ASM_SYSCALL_H
#define __UM_ASM_SYSCALL_H
+#include <asm/syscall-generic.h>
#include <uapi/linux/audit.h>
typedef asmlinkage long (*sys_call_ptr_t)(unsigned long, unsigned long,
--
2.6.4
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 3/4] um: Add full asm/syscall.h support
@ 2015-12-21 20:26 ` Mickaël Salaün
0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 20:26 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff, David Drysdale
Add subarchitecture-independent implementation of asm-generic/syscall.h
allowing access to user system call parameters and results:
* syscall_get_nr()
* syscall_rollback()
* syscall_get_error()
* syscall_get_return_value()
* syscall_set_return_value()
* syscall_get_arguments()
* syscall_set_arguments()
* syscall_get_arch() provided by arch/x86/um/asm/syscall.h
This provides the necessary syscall helpers needed by
HAVE_ARCH_SECCOMP_FILTER plus syscall_get_error().
This is inspired from Meredydd Luff's patch
(https://gerrit.chromium.org/gerrit/21425).
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
arch/um/include/asm/syscall-generic.h | 138 ++++++++++++++++++++++++++++++++++
arch/x86/um/asm/syscall.h | 1 +
2 files changed, 139 insertions(+)
create mode 100644 arch/um/include/asm/syscall-generic.h
diff --git a/arch/um/include/asm/syscall-generic.h b/arch/um/include/asm/syscall-generic.h
new file mode 100644
index 0000000..9fb9cf8
--- /dev/null
+++ b/arch/um/include/asm/syscall-generic.h
@@ -0,0 +1,138 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * See asm-generic/syscall.h for function descriptions.
+ *
+ * Copyright (C) 2015 Mickaël Salaün <mic@digikod.net>
+ *
+ * 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 __UM_SYSCALL_GENERIC_H
+#define __UM_SYSCALL_GENERIC_H
+
+#include <asm/ptrace.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <sysdep/ptrace.h>
+
+static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+
+ return PT_REGS_SYSCALL_NR(regs);
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ /* do nothing */
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ const long error = regs_return_value(regs);
+
+ return IS_ERR_VALUE(error) ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs_return_value(regs);
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ PT_REGS_SET_SYSCALL_RETURN(regs, (long) error ?: val);
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ const struct uml_pt_regs *r = ®s->regs;
+
+ switch (i) {
+ case 0:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG1(r);
+ case 1:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG2(r);
+ case 2:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG3(r);
+ case 3:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG4(r);
+ case 4:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG5(r);
+ case 5:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG6(r);
+ case 6:
+ if (!n--)
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ struct uml_pt_regs *r = ®s->regs;
+
+ switch (i) {
+ case 0:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG1(r) = *args++;
+ case 1:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG2(r) = *args++;
+ case 2:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG3(r) = *args++;
+ case 3:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG4(r) = *args++;
+ case 4:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG5(r) = *args++;
+ case 5:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG6(r) = *args++;
+ case 6:
+ if (!n--)
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+/* See arch/x86/um/asm/syscall.h for syscall_get_arch() definition. */
+
+#endif /* __UM_SYSCALL_GENERIC_H */
diff --git a/arch/x86/um/asm/syscall.h b/arch/x86/um/asm/syscall.h
index 81d6562..11ab90d 100644
--- a/arch/x86/um/asm/syscall.h
+++ b/arch/x86/um/asm/syscall.h
@@ -1,6 +1,7 @@
#ifndef __UM_ASM_SYSCALL_H
#define __UM_ASM_SYSCALL_H
+#include <asm/syscall-generic.h>
#include <uapi/linux/audit.h>
typedef asmlinkage long (*sys_call_ptr_t)(unsigned long, unsigned long,
--
2.6.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 4/4] um: Add seccomp support
2015-12-21 19:29 ` Mickaël Salaün
(?)
@ 2015-12-21 20:30 ` Mickaël Salaün
-1 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 20:30 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff, David Drysdale
This brings SECCOMP_MODE_STRICT and SECCOMP_MODE_FILTER support through
prctl(2) and seccomp(2) to User-mode Linux for i386 and x86_64
subarchitectures.
secure_computing() is called first in handle_syscall() so that the
syscall emulation will be aborted quickly if matching a seccomp rule.
This is inspired from Meredydd Luff's patch
(https://gerrit.chromium.org/gerrit/21425).
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Chris Metcalf <cmetcalf@ezchip.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
.../features/seccomp/seccomp-filter/arch-support.txt | 2 +-
arch/um/Kconfig.common | 1 +
arch/um/Kconfig.um | 16 ++++++++++++++++
arch/um/include/asm/thread_info.h | 2 ++
arch/um/kernel/skas/syscall.c | 5 +++++
5 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/Documentation/features/seccomp/seccomp-filter/arch-support.txt b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
index 76d39d6..4f66ec1 100644
--- a/Documentation/features/seccomp/seccomp-filter/arch-support.txt
+++ b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
@@ -33,7 +33,7 @@
| sh: | TODO |
| sparc: | TODO |
| tile: | ok |
- | um: | TODO |
+ | um: | ok |
| unicore32: | TODO |
| x86: | ok |
| xtensa: | TODO |
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index d195a87..cc00134 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -2,6 +2,7 @@ config UML
bool
default y
select HAVE_ARCH_AUDITSYSCALL
+ select HAVE_ARCH_SECCOMP_FILTER
select HAVE_UID16
select HAVE_FUTEX_CMPXCHG if FUTEX
select GENERIC_IRQ_SHOW
diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um
index 28a9885..4b2ed58 100644
--- a/arch/um/Kconfig.um
+++ b/arch/um/Kconfig.um
@@ -104,3 +104,19 @@ config PGTABLE_LEVELS
int
default 3 if 3_LEVEL_PGTABLES
default 2
+
+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.
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h
index 53968aa..053baff 100644
--- a/arch/um/include/asm/thread_info.h
+++ b/arch/um/include/asm/thread_info.h
@@ -62,11 +62,13 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_AUDIT 6
#define TIF_RESTORE_SIGMASK 7
#define TIF_NOTIFY_RESUME 8
+#define TIF_SECCOMP 9 /* secure computing */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#endif
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 0d624e0..5abc677 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -5,6 +5,7 @@
#include <linux/kernel.h>
#include <linux/ptrace.h>
+#include <linux/seccomp.h>
#include <kern_util.h>
#include <sysdep/ptrace.h>
#include <sysdep/ptrace_user.h>
@@ -20,6 +21,10 @@ void handle_syscall(struct uml_pt_regs *r)
UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
PT_REGS_SET_SYSCALL_RETURN(regs, -ENOSYS);
+ /* Do the secure computing check first; failures should be fast. */
+ if (secure_computing() == -1)
+ return;
+
if (syscall_trace_enter(regs))
goto out;
--
2.6.4
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 4/4] um: Add seccomp support
@ 2015-12-21 20:30 ` Mickaël Salaün
0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 20:30 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff
This brings SECCOMP_MODE_STRICT and SECCOMP_MODE_FILTER support through
prctl(2) and seccomp(2) to User-mode Linux for i386 and x86_64
subarchitectures.
secure_computing() is called first in handle_syscall() so that the
syscall emulation will be aborted quickly if matching a seccomp rule.
This is inspired from Meredydd Luff's patch
(https://gerrit.chromium.org/gerrit/21425).
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Chris Metcalf <cmetcalf@ezchip.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
.../features/seccomp/seccomp-filter/arch-support.txt | 2 +-
arch/um/Kconfig.common | 1 +
arch/um/Kconfig.um | 16 ++++++++++++++++
arch/um/include/asm/thread_info.h | 2 ++
arch/um/kernel/skas/syscall.c | 5 +++++
5 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/Documentation/features/seccomp/seccomp-filter/arch-support.txt b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
index 76d39d6..4f66ec1 100644
--- a/Documentation/features/seccomp/seccomp-filter/arch-support.txt
+++ b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
@@ -33,7 +33,7 @@
| sh: | TODO |
| sparc: | TODO |
| tile: | ok |
- | um: | TODO |
+ | um: | ok |
| unicore32: | TODO |
| x86: | ok |
| xtensa: | TODO |
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index d195a87..cc00134 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -2,6 +2,7 @@ config UML
bool
default y
select HAVE_ARCH_AUDITSYSCALL
+ select HAVE_ARCH_SECCOMP_FILTER
select HAVE_UID16
select HAVE_FUTEX_CMPXCHG if FUTEX
select GENERIC_IRQ_SHOW
diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um
index 28a9885..4b2ed58 100644
--- a/arch/um/Kconfig.um
+++ b/arch/um/Kconfig.um
@@ -104,3 +104,19 @@ config PGTABLE_LEVELS
int
default 3 if 3_LEVEL_PGTABLES
default 2
+
+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.
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h
index 53968aa..053baff 100644
--- a/arch/um/include/asm/thread_info.h
+++ b/arch/um/include/asm/thread_info.h
@@ -62,11 +62,13 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_AUDIT 6
#define TIF_RESTORE_SIGMASK 7
#define TIF_NOTIFY_RESUME 8
+#define TIF_SECCOMP 9 /* secure computing */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#endif
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 0d624e0..5abc677 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -5,6 +5,7 @@
#include <linux/kernel.h>
#include <linux/ptrace.h>
+#include <linux/seccomp.h>
#include <kern_util.h>
#include <sysdep/ptrace.h>
#include <sysdep/ptrace_user.h>
@@ -20,6 +21,10 @@ void handle_syscall(struct uml_pt_regs *r)
UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
PT_REGS_SET_SYSCALL_RETURN(regs, -ENOSYS);
+ /* Do the secure computing check first; failures should be fast. */
+ if (secure_computing() == -1)
+ return;
+
if (syscall_trace_enter(regs))
goto out;
--
2.6.4
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 4/4] um: Add seccomp support
@ 2015-12-21 20:30 ` Mickaël Salaün
0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2015-12-21 20:30 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Jonathan Corbet, Jeff Dike,
Richard Weinberger, Thomas Gleixner, Ingo Molnar,
H . Peter Anvin, x86, Kees Cook, Andy Lutomirski, Will Drewry,
Shuah Khan, Chris Metcalf, Michael Ellerman, Andrew Morton,
James Hogan, Thomas Meyer, Nicolas Iooss, Anton Ivanov,
linux-doc, user-mode-linux-devel, user-mode-linux-user,
linux-api, Meredydd Luff, David Drysdale
This brings SECCOMP_MODE_STRICT and SECCOMP_MODE_FILTER support through
prctl(2) and seccomp(2) to User-mode Linux for i386 and x86_64
subarchitectures.
secure_computing() is called first in handle_syscall() so that the
syscall emulation will be aborted quickly if matching a seccomp rule.
This is inspired from Meredydd Luff's patch
(https://gerrit.chromium.org/gerrit/21425).
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Chris Metcalf <cmetcalf@ezchip.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Meredydd Luff <meredydd@senatehouse.org>
Cc: David Drysdale <drysdale@google.com>
---
.../features/seccomp/seccomp-filter/arch-support.txt | 2 +-
arch/um/Kconfig.common | 1 +
arch/um/Kconfig.um | 16 ++++++++++++++++
arch/um/include/asm/thread_info.h | 2 ++
arch/um/kernel/skas/syscall.c | 5 +++++
5 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/Documentation/features/seccomp/seccomp-filter/arch-support.txt b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
index 76d39d6..4f66ec1 100644
--- a/Documentation/features/seccomp/seccomp-filter/arch-support.txt
+++ b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
@@ -33,7 +33,7 @@
| sh: | TODO |
| sparc: | TODO |
| tile: | ok |
- | um: | TODO |
+ | um: | ok |
| unicore32: | TODO |
| x86: | ok |
| xtensa: | TODO |
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index d195a87..cc00134 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -2,6 +2,7 @@ config UML
bool
default y
select HAVE_ARCH_AUDITSYSCALL
+ select HAVE_ARCH_SECCOMP_FILTER
select HAVE_UID16
select HAVE_FUTEX_CMPXCHG if FUTEX
select GENERIC_IRQ_SHOW
diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um
index 28a9885..4b2ed58 100644
--- a/arch/um/Kconfig.um
+++ b/arch/um/Kconfig.um
@@ -104,3 +104,19 @@ config PGTABLE_LEVELS
int
default 3 if 3_LEVEL_PGTABLES
default 2
+
+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.
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h
index 53968aa..053baff 100644
--- a/arch/um/include/asm/thread_info.h
+++ b/arch/um/include/asm/thread_info.h
@@ -62,11 +62,13 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_AUDIT 6
#define TIF_RESTORE_SIGMASK 7
#define TIF_NOTIFY_RESUME 8
+#define TIF_SECCOMP 9 /* secure computing */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#endif
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 0d624e0..5abc677 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -5,6 +5,7 @@
#include <linux/kernel.h>
#include <linux/ptrace.h>
+#include <linux/seccomp.h>
#include <kern_util.h>
#include <sysdep/ptrace.h>
#include <sysdep/ptrace_user.h>
@@ -20,6 +21,10 @@ void handle_syscall(struct uml_pt_regs *r)
UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
PT_REGS_SET_SYSCALL_RETURN(regs, -ENOSYS);
+ /* Do the secure computing check first; failures should be fast. */
+ if (secure_computing() == -1)
+ return;
+
if (syscall_trace_enter(regs))
goto out;
--
2.6.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply related [flat|nested] 15+ messages in thread
end of thread, other threads:[~2015-12-21 21:48 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-21 19:29 [PATCH v2 0/4] um: Add seccomp support Mickaël Salaün
2015-12-21 19:29 ` Mickaël Salaün
2015-12-21 19:29 ` Mickaël Salaün
2015-12-21 19:29 ` [PATCH v2 1/4] um: Fix ptrace GETREGS/SETREGS bugs Mickaël Salaün
2015-12-21 19:29 ` Mickaël Salaün
2015-12-21 19:29 ` Mickaël Salaün
2015-12-21 19:29 ` [PATCH v2 2/4] selftests/seccomp: Remove the need for HAVE_ARCH_TRACEHOOK Mickaël Salaün
2015-12-21 19:29 ` Mickaël Salaün
2015-12-21 19:29 ` Mickaël Salaün
2015-12-21 20:26 ` [PATCH v2 3/4] um: Add full asm/syscall.h support Mickaël Salaün
2015-12-21 20:26 ` Mickaël Salaün
2015-12-21 20:26 ` Mickaël Salaün
2015-12-21 20:30 ` [PATCH v2 4/4] um: Add seccomp support Mickaël Salaün
2015-12-21 20:30 ` Mickaël Salaün
2015-12-21 20:30 ` Mickaël Salaün
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.