All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering
@ 2012-03-29 20:01 ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Please see prior revisions for a detailed discussion of this patch
series.

This series is a rebase on to:
  b5174fa3a7f4f8f150bfa3b917c92608953dfa0f
with very minor changes due to rebasing and tweaks noticed by a few
initial users.  (I will rebase again for v3.4-rc1 when that time comes.)

I realize now is a noisy time, but I wanted to get the most current
revision on the list.

As per prior posts, I am now including luto@'s PR_SET_NO_NEW_PRIVS
changes in the series for clarity and ease of testing.  This latest
rebased required required bumping the prctl() numbers for the
NO_NEW_PRIVS work due to the new reaper options.

For those inclined, the whole series can be found here too:
   https://github.com/redpig/linux/tree/seccomp

At this point, I'm not aware of any outstanding concerns, complaints,
etc. If there are any, I'd love to know.

Thanks!
will


Andy Lutomirski (1):
  Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs

John Johansen (1):
  Fix apparmor for PR_{GET,SET}_NO_NEW_PRIVS

Kees Cook (1):
  seccomp: remove duplicated failure logging

Will Drewry (12):
  sk_run_filter: add BPF_S_ANC_SECCOMP_LD_W
  net/compat.c,linux/filter.h: share compat_sock_fprog
  seccomp: kill the seccomp_t typedef
  arch/x86: add syscall_get_arch to syscall.h
  asm/syscall.h: add syscall_get_arch
  seccomp: add system call filtering using BPF
  seccomp: add SECCOMP_RET_ERRNO
  signal, x86: add SIGSYS info and make it synchronous.
  seccomp: Add SECCOMP_RET_TRAP
  ptrace,seccomp: Add PTRACE_SECCOMP support
  x86: Enable HAVE_ARCH_SECCOMP_FILTER
  Documentation: prctl/seccomp_filter

 Documentation/prctl/seccomp_filter.txt |  163 ++++++++++++
 arch/Kconfig                           |   24 ++
 arch/x86/Kconfig                       |    1 +
 arch/x86/ia32/ia32_signal.c            |    4 +
 arch/x86/include/asm/ia32.h            |    6 +
 arch/x86/include/asm/syscall.h         |   23 ++
 arch/x86/kernel/ptrace.c               |    7 +-
 fs/exec.c                              |   10 +-
 include/asm-generic/siginfo.h          |   22 ++
 include/asm-generic/syscall.h          |   14 +
 include/linux/Kbuild                   |    1 +
 include/linux/audit.h                  |    8 +-
 include/linux/filter.h                 |   12 +
 include/linux/prctl.h                  |   15 +
 include/linux/ptrace.h                 |    5 +-
 include/linux/sched.h                  |    4 +-
 include/linux/seccomp.h                |  105 +++++++-
 include/linux/security.h               |    1 +
 kernel/auditsc.c                       |   10 +-
 kernel/fork.c                          |    3 +
 kernel/seccomp.c                       |  447 ++++++++++++++++++++++++++++++--
 kernel/signal.c                        |    9 +-
 kernel/sys.c                           |   12 +-
 net/compat.c                           |    8 -
 net/core/filter.c                      |    6 +
 samples/Makefile                       |    2 +-
 samples/seccomp/Makefile               |   38 +++
 samples/seccomp/bpf-direct.c           |  176 +++++++++++++
 samples/seccomp/bpf-fancy.c            |  102 ++++++++
 samples/seccomp/bpf-helper.c           |   89 +++++++
 samples/seccomp/bpf-helper.h           |  238 +++++++++++++++++
 samples/seccomp/dropper.c              |   68 +++++
 security/apparmor/domain.c             |   35 +++
 security/commoncap.c                   |    7 +-
 security/selinux/hooks.c               |   10 +-
 35 files changed, 1628 insertions(+), 57 deletions(-)
 create mode 100644 Documentation/prctl/seccomp_filter.txt
 create mode 100644 samples/seccomp/Makefile
 create mode 100644 samples/seccomp/bpf-direct.c
 create mode 100644 samples/seccomp/bpf-fancy.c
 create mode 100644 samples/seccomp/bpf-helper.c
 create mode 100644 samples/seccomp/bpf-helper.h
 create mode 100644 samples/seccomp/dropper.c

-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering
@ 2012-03-29 20:01 ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Please see prior revisions for a detailed discussion of this patch
series.

This series is a rebase on to:
  b5174fa3a7f4f8f150bfa3b917c92608953dfa0f
with very minor changes due to rebasing and tweaks noticed by a few
initial users.  (I will rebase again for v3.4-rc1 when that time comes.)

I realize now is a noisy time, but I wanted to get the most current
revision on the list.

As per prior posts, I am now including luto@'s PR_SET_NO_NEW_PRIVS
changes in the series for clarity and ease of testing.  This latest
rebased required required bumping the prctl() numbers for the
NO_NEW_PRIVS work due to the new reaper options.

For those inclined, the whole series can be found here too:
   https://github.com/redpig/linux/tree/seccomp

At this point, I'm not aware of any outstanding concerns, complaints,
etc. If there are any, I'd love to know.

Thanks!
will


Andy Lutomirski (1):
  Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs

John Johansen (1):
  Fix apparmor for PR_{GET,SET}_NO_NEW_PRIVS

Kees Cook (1):
  seccomp: remove duplicated failure logging

Will Drewry (12):
  sk_run_filter: add BPF_S_ANC_SECCOMP_LD_W
  net/compat.c,linux/filter.h: share compat_sock_fprog
  seccomp: kill the seccomp_t typedef
  arch/x86: add syscall_get_arch to syscall.h
  asm/syscall.h: add syscall_get_arch
  seccomp: add system call filtering using BPF
  seccomp: add SECCOMP_RET_ERRNO
  signal, x86: add SIGSYS info and make it synchronous.
  seccomp: Add SECCOMP_RET_TRAP
  ptrace,seccomp: Add PTRACE_SECCOMP support
  x86: Enable HAVE_ARCH_SECCOMP_FILTER
  Documentation: prctl/seccomp_filter

 Documentation/prctl/seccomp_filter.txt |  163 ++++++++++++
 arch/Kconfig                           |   24 ++
 arch/x86/Kconfig                       |    1 +
 arch/x86/ia32/ia32_signal.c            |    4 +
 arch/x86/include/asm/ia32.h            |    6 +
 arch/x86/include/asm/syscall.h         |   23 ++
 arch/x86/kernel/ptrace.c               |    7 +-
 fs/exec.c                              |   10 +-
 include/asm-generic/siginfo.h          |   22 ++
 include/asm-generic/syscall.h          |   14 +
 include/linux/Kbuild                   |    1 +
 include/linux/audit.h                  |    8 +-
 include/linux/filter.h                 |   12 +
 include/linux/prctl.h                  |   15 +
 include/linux/ptrace.h                 |    5 +-
 include/linux/sched.h                  |    4 +-
 include/linux/seccomp.h                |  105 +++++++-
 include/linux/security.h               |    1 +
 kernel/auditsc.c                       |   10 +-
 kernel/fork.c                          |    3 +
 kernel/seccomp.c                       |  447 ++++++++++++++++++++++++++++++--
 kernel/signal.c                        |    9 +-
 kernel/sys.c                           |   12 +-
 net/compat.c                           |    8 -
 net/core/filter.c                      |    6 +
 samples/Makefile                       |    2 +-
 samples/seccomp/Makefile               |   38 +++
 samples/seccomp/bpf-direct.c           |  176 +++++++++++++
 samples/seccomp/bpf-fancy.c            |  102 ++++++++
 samples/seccomp/bpf-helper.c           |   89 +++++++
 samples/seccomp/bpf-helper.h           |  238 +++++++++++++++++
 samples/seccomp/dropper.c              |   68 +++++
 security/apparmor/domain.c             |   35 +++
 security/commoncap.c                   |    7 +-
 security/selinux/hooks.c               |   10 +-
 35 files changed, 1628 insertions(+), 57 deletions(-)
 create mode 100644 Documentation/prctl/seccomp_filter.txt
 create mode 100644 samples/seccomp/Makefile
 create mode 100644 samples/seccomp/bpf-direct.c
 create mode 100644 samples/seccomp/bpf-fancy.c
 create mode 100644 samples/seccomp/bpf-helper.c
 create mode 100644 samples/seccomp/bpf-helper.h
 create mode 100644 samples/seccomp/dropper.c

-- 
1.7.5.4

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

* [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski

From: Andy Lutomirski <luto@amacapital.net>

With this set, a lot of dangerous operations (chroot, unshare, etc)
become a lot less dangerous because there is no possibility of
subverting privileged binaries.

This patch completely breaks apparmor.  Someone who understands (and
uses) apparmor should fix it or at least give me a hint.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>

(rebased onto -linus, bumping prctl # -wad@chromium.org)
---
 fs/exec.c                  |   10 +++++++++-
 include/linux/prctl.h      |   15 +++++++++++++++
 include/linux/sched.h      |    2 ++
 include/linux/security.h   |    1 +
 kernel/sys.c               |   10 ++++++++++
 security/apparmor/domain.c |    4 ++++
 security/commoncap.c       |    7 +++++--
 security/selinux/hooks.c   |   10 +++++++++-
 8 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index c8b63d1..a8451ec 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1245,6 +1245,13 @@ static int check_unsafe_exec(struct linux_binprm *bprm)
 			bprm->unsafe |= LSM_UNSAFE_PTRACE;
 	}
 
+	/*
+	 * This isn't strictly necessary, but it makes it harder for LSMs to
+	 * mess up.
+	 */
+	if (current->no_new_privs)
+		bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS;
+
 	n_fs = 1;
 	spin_lock(&p->fs->lock);
 	rcu_read_lock();
@@ -1288,7 +1295,8 @@ int prepare_binprm(struct linux_binprm *bprm)
 	bprm->cred->euid = current_euid();
 	bprm->cred->egid = current_egid();
 
-	if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) {
+	if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) &&
+	    !current->no_new_privs) {
 		/* Set-uid? */
 		if (mode & S_ISUID) {
 			bprm->per_clear |= PER_CLEAR_ON_SETID;
diff --git a/include/linux/prctl.h b/include/linux/prctl.h
index e0cfec2..78b76e2 100644
--- a/include/linux/prctl.h
+++ b/include/linux/prctl.h
@@ -124,4 +124,19 @@
 #define PR_SET_CHILD_SUBREAPER 36
 #define PR_GET_CHILD_SUBREAPER 37
 
+/*
+ * If no_new_privs is set, then operations that grant new privileges (i.e.
+ * execve) will either fail or not grant them.  This affects suid/sgid,
+ * file capabilities, and LSMs.
+ *
+ * Operations that merely manipulate or drop existing privileges (setresuid,
+ * capset, etc.) will still work.  Drop those privileges if you want them gone.
+ *
+ * Changing LSM security domain is considered a new privilege.  So, for example,
+ * asking selinux for a specific new context (e.g. with runcon) will result
+ * in execve returning -EPERM.
+ */
+#define PR_SET_NO_NEW_PRIVS 38
+#define PR_GET_NO_NEW_PRIVS 39
+
 #endif /* _LINUX_PRCTL_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 81a173c..ba60897 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1341,6 +1341,8 @@ struct task_struct {
 				 * execve */
 	unsigned in_iowait:1;
 
+	/* task may not gain privileges */
+	unsigned no_new_privs:1;
 
 	/* Revert to default priority/policy when forking */
 	unsigned sched_reset_on_fork:1;
diff --git a/include/linux/security.h b/include/linux/security.h
index 673afbb..6e1dea9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -144,6 +144,7 @@ struct request_sock;
 #define LSM_UNSAFE_SHARE	1
 #define LSM_UNSAFE_PTRACE	2
 #define LSM_UNSAFE_PTRACE_CAP	4
+#define LSM_UNSAFE_NO_NEW_PRIVS	8
 
 #ifdef CONFIG_MMU
 extern int mmap_min_addr_handler(struct ctl_table *table, int write,
diff --git a/kernel/sys.c b/kernel/sys.c
index e7006eb..b82568b 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1979,6 +1979,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 			error = put_user(me->signal->is_child_subreaper,
 					 (int __user *) arg2);
 			break;
+		case PR_SET_NO_NEW_PRIVS:
+			if (arg2 != 1 || arg3 || arg4 || arg5)
+				return -EINVAL;
+
+			current->no_new_privs = 1;
+			break;
+		case PR_GET_NO_NEW_PRIVS:
+			if (arg2 || arg3 || arg4 || arg5)
+				return -EINVAL;
+			return current->no_new_privs ? 1 : 0;
 		default:
 			error = -EINVAL;
 			break;
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 6327685..18c88d0 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -360,6 +360,10 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
 	if (bprm->cred_prepared)
 		return 0;
 
+	/* XXX: no_new_privs is not usable with AppArmor yet */
+	if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
+		return -EPERM;
+
 	cxt = bprm->cred->security;
 	BUG_ON(!cxt);
 
diff --git a/security/commoncap.c b/security/commoncap.c
index 0cf4b53..edd3918 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -506,14 +506,17 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
 skip:
 
 	/* Don't let someone trace a set[ug]id/setpcap binary with the revised
-	 * credentials unless they have the appropriate permit
+	 * credentials unless they have the appropriate permit.
+	 *
+	 * In addition, if NO_NEW_PRIVS, then ensure we get no new privs.
 	 */
 	if ((new->euid != old->uid ||
 	     new->egid != old->gid ||
 	     !cap_issubset(new->cap_permitted, old->cap_permitted)) &&
 	    bprm->unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
 		/* downgrade; they get no more than they had, and maybe less */
-		if (!capable(CAP_SETUID)) {
+		if (!capable(CAP_SETUID) ||
+		    (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) {
 			new->euid = new->uid;
 			new->egid = new->gid;
 		}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 3049299..be99c84 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2000,6 +2000,13 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
 		new_tsec->sid = old_tsec->exec_sid;
 		/* Reset exec SID on execve. */
 		new_tsec->exec_sid = 0;
+
+		/*
+		 * Minimize confusion: if no_new_privs and a transition is
+		 * explicitly requested, then fail the exec.
+		 */
+		if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
+			return -EPERM;
 	} else {
 		/* Check for a default transition on this program. */
 		rc = security_transition_sid(old_tsec->sid, isec->sid,
@@ -2012,7 +2019,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
 	COMMON_AUDIT_DATA_INIT(&ad, PATH);
 	ad.u.path = bprm->file->f_path;
 
-	if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
+	if ((bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) ||
+	    (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS))
 		new_tsec->sid = old_tsec->sid;
 
 	if (new_tsec->sid == old_tsec->sid) {
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski

From: Andy Lutomirski <luto@amacapital.net>

With this set, a lot of dangerous operations (chroot, unshare, etc)
become a lot less dangerous because there is no possibility of
subverting privileged binaries.

This patch completely breaks apparmor.  Someone who understands (and
uses) apparmor should fix it or at least give me a hint.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>

(rebased onto -linus, bumping prctl # -wad@chromium.org)
---
 fs/exec.c                  |   10 +++++++++-
 include/linux/prctl.h      |   15 +++++++++++++++
 include/linux/sched.h      |    2 ++
 include/linux/security.h   |    1 +
 kernel/sys.c               |   10 ++++++++++
 security/apparmor/domain.c |    4 ++++
 security/commoncap.c       |    7 +++++--
 security/selinux/hooks.c   |   10 +++++++++-
 8 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index c8b63d1..a8451ec 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1245,6 +1245,13 @@ static int check_unsafe_exec(struct linux_binprm *bprm)
 			bprm->unsafe |= LSM_UNSAFE_PTRACE;
 	}
 
+	/*
+	 * This isn't strictly necessary, but it makes it harder for LSMs to
+	 * mess up.
+	 */
+	if (current->no_new_privs)
+		bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS;
+
 	n_fs = 1;
 	spin_lock(&p->fs->lock);
 	rcu_read_lock();
@@ -1288,7 +1295,8 @@ int prepare_binprm(struct linux_binprm *bprm)
 	bprm->cred->euid = current_euid();
 	bprm->cred->egid = current_egid();
 
-	if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) {
+	if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) &&
+	    !current->no_new_privs) {
 		/* Set-uid? */
 		if (mode & S_ISUID) {
 			bprm->per_clear |= PER_CLEAR_ON_SETID;
diff --git a/include/linux/prctl.h b/include/linux/prctl.h
index e0cfec2..78b76e2 100644
--- a/include/linux/prctl.h
+++ b/include/linux/prctl.h
@@ -124,4 +124,19 @@
 #define PR_SET_CHILD_SUBREAPER 36
 #define PR_GET_CHILD_SUBREAPER 37
 
+/*
+ * If no_new_privs is set, then operations that grant new privileges (i.e.
+ * execve) will either fail or not grant them.  This affects suid/sgid,
+ * file capabilities, and LSMs.
+ *
+ * Operations that merely manipulate or drop existing privileges (setresuid,
+ * capset, etc.) will still work.  Drop those privileges if you want them gone.
+ *
+ * Changing LSM security domain is considered a new privilege.  So, for example,
+ * asking selinux for a specific new context (e.g. with runcon) will result
+ * in execve returning -EPERM.
+ */
+#define PR_SET_NO_NEW_PRIVS 38
+#define PR_GET_NO_NEW_PRIVS 39
+
 #endif /* _LINUX_PRCTL_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 81a173c..ba60897 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1341,6 +1341,8 @@ struct task_struct {
 				 * execve */
 	unsigned in_iowait:1;
 
+	/* task may not gain privileges */
+	unsigned no_new_privs:1;
 
 	/* Revert to default priority/policy when forking */
 	unsigned sched_reset_on_fork:1;
diff --git a/include/linux/security.h b/include/linux/security.h
index 673afbb..6e1dea9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -144,6 +144,7 @@ struct request_sock;
 #define LSM_UNSAFE_SHARE	1
 #define LSM_UNSAFE_PTRACE	2
 #define LSM_UNSAFE_PTRACE_CAP	4
+#define LSM_UNSAFE_NO_NEW_PRIVS	8
 
 #ifdef CONFIG_MMU
 extern int mmap_min_addr_handler(struct ctl_table *table, int write,
diff --git a/kernel/sys.c b/kernel/sys.c
index e7006eb..b82568b 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1979,6 +1979,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 			error = put_user(me->signal->is_child_subreaper,
 					 (int __user *) arg2);
 			break;
+		case PR_SET_NO_NEW_PRIVS:
+			if (arg2 != 1 || arg3 || arg4 || arg5)
+				return -EINVAL;
+
+			current->no_new_privs = 1;
+			break;
+		case PR_GET_NO_NEW_PRIVS:
+			if (arg2 || arg3 || arg4 || arg5)
+				return -EINVAL;
+			return current->no_new_privs ? 1 : 0;
 		default:
 			error = -EINVAL;
 			break;
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 6327685..18c88d0 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -360,6 +360,10 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
 	if (bprm->cred_prepared)
 		return 0;
 
+	/* XXX: no_new_privs is not usable with AppArmor yet */
+	if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
+		return -EPERM;
+
 	cxt = bprm->cred->security;
 	BUG_ON(!cxt);
 
diff --git a/security/commoncap.c b/security/commoncap.c
index 0cf4b53..edd3918 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -506,14 +506,17 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
 skip:
 
 	/* Don't let someone trace a set[ug]id/setpcap binary with the revised
-	 * credentials unless they have the appropriate permit
+	 * credentials unless they have the appropriate permit.
+	 *
+	 * In addition, if NO_NEW_PRIVS, then ensure we get no new privs.
 	 */
 	if ((new->euid != old->uid ||
 	     new->egid != old->gid ||
 	     !cap_issubset(new->cap_permitted, old->cap_permitted)) &&
 	    bprm->unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
 		/* downgrade; they get no more than they had, and maybe less */
-		if (!capable(CAP_SETUID)) {
+		if (!capable(CAP_SETUID) ||
+		    (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) {
 			new->euid = new->uid;
 			new->egid = new->gid;
 		}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 3049299..be99c84 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2000,6 +2000,13 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
 		new_tsec->sid = old_tsec->exec_sid;
 		/* Reset exec SID on execve. */
 		new_tsec->exec_sid = 0;
+
+		/*
+		 * Minimize confusion: if no_new_privs and a transition is
+		 * explicitly requested, then fail the exec.
+		 */
+		if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
+			return -EPERM;
 	} else {
 		/* Check for a default transition on this program. */
 		rc = security_transition_sid(old_tsec->sid, isec->sid,
@@ -2012,7 +2019,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
 	COMMON_AUDIT_DATA_INIT(&ad, PATH);
 	ad.u.path = bprm->file->f_path;
 
-	if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
+	if ((bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) ||
+	    (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS))
 		new_tsec->sid = old_tsec->sid;
 
 	if (new_tsec->sid == old_tsec->sid) {
-- 
1.7.5.4

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

* [PATCH v17 02/15] Fix apparmor for PR_{GET,SET}_NO_NEW_PRIVS
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, John Johansen, Andy Lutomirski

From: John Johansen <john.johansen@canonical.com>

Signed-off-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
 security/apparmor/domain.c |   39 +++++++++++++++++++++++++++++++++++----
 1 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 18c88d0..b81ea10 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -360,10 +360,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
 	if (bprm->cred_prepared)
 		return 0;
 
-	/* XXX: no_new_privs is not usable with AppArmor yet */
-	if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
-		return -EPERM;
-
 	cxt = bprm->cred->security;
 	BUG_ON(!cxt);
 
@@ -398,6 +394,11 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
 			new_profile = find_attach(ns, &ns->base.profiles, name);
 		if (!new_profile)
 			goto cleanup;
+		/*
+		 * NOTE: Domain transitions from unconfined are allowed
+		 * even when no_new_privs is set because this aways results
+		 * in a further reduction of permissions.
+		 */
 		goto apply;
 	}
 
@@ -459,6 +460,16 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
 		/* fail exec */
 		error = -EACCES;
 
+	/*
+	 * Policy has specified a domain transition, if no_new_privs then
+	 * fail the exec.
+	 */
+	if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) {
+		aa_put_profile(new_profile);
+		error = -EPERM;
+		goto cleanup;
+	}
+
 	if (!new_profile)
 		goto audit;
 
@@ -613,6 +624,14 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
 	const char *target = NULL, *info = NULL;
 	int error = 0;
 
+	/*
+	 * Fail explicitly requested domain transitions if no_new_privs.
+	 * There is no exception for unconfined as change_hat is not
+	 * available.
+	 */
+	if (current->no_new_privs)
+		return -EPERM;
+
 	/* released below */
 	cred = get_current_cred();
 	cxt = cred->security;
@@ -754,6 +773,18 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
 	cxt = cred->security;
 	profile = aa_cred_profile(cred);
 
+	/*
+	 * Fail explicitly requested domain transitions if no_new_privs
+	 * and not unconfined.
+	 * Domain transitions from unconfined are allowed even when
+	 * no_new_privs is set because this aways results in a reduction
+	 * of permissions.
+	 */
+	if (current->no_new_privs && !unconfined(profile)) {
+		put_cred(cred);
+		return -EPERM;
+	}
+
 	if (ns_name) {
 		/* released below */
 		ns = aa_find_namespace(profile->ns, ns_name);
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 02/15] Fix apparmor for PR_{GET,SET}_NO_NEW_PRIVS
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, John Johansen, Andy Lutomirski

From: John Johansen <john.johansen@canonical.com>

Signed-off-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
 security/apparmor/domain.c |   39 +++++++++++++++++++++++++++++++++++----
 1 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 18c88d0..b81ea10 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -360,10 +360,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
 	if (bprm->cred_prepared)
 		return 0;
 
-	/* XXX: no_new_privs is not usable with AppArmor yet */
-	if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
-		return -EPERM;
-
 	cxt = bprm->cred->security;
 	BUG_ON(!cxt);
 
@@ -398,6 +394,11 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
 			new_profile = find_attach(ns, &ns->base.profiles, name);
 		if (!new_profile)
 			goto cleanup;
+		/*
+		 * NOTE: Domain transitions from unconfined are allowed
+		 * even when no_new_privs is set because this aways results
+		 * in a further reduction of permissions.
+		 */
 		goto apply;
 	}
 
@@ -459,6 +460,16 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
 		/* fail exec */
 		error = -EACCES;
 
+	/*
+	 * Policy has specified a domain transition, if no_new_privs then
+	 * fail the exec.
+	 */
+	if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) {
+		aa_put_profile(new_profile);
+		error = -EPERM;
+		goto cleanup;
+	}
+
 	if (!new_profile)
 		goto audit;
 
@@ -613,6 +624,14 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
 	const char *target = NULL, *info = NULL;
 	int error = 0;
 
+	/*
+	 * Fail explicitly requested domain transitions if no_new_privs.
+	 * There is no exception for unconfined as change_hat is not
+	 * available.
+	 */
+	if (current->no_new_privs)
+		return -EPERM;
+
 	/* released below */
 	cred = get_current_cred();
 	cxt = cred->security;
@@ -754,6 +773,18 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
 	cxt = cred->security;
 	profile = aa_cred_profile(cred);
 
+	/*
+	 * Fail explicitly requested domain transitions if no_new_privs
+	 * and not unconfined.
+	 * Domain transitions from unconfined are allowed even when
+	 * no_new_privs is set because this aways results in a reduction
+	 * of permissions.
+	 */
+	if (current->no_new_privs && !unconfined(profile)) {
+		put_cred(cred);
+		return -EPERM;
+	}
+
 	if (ns_name) {
 		/* released below */
 		ns = aa_find_namespace(profile->ns, ns_name);
-- 
1.7.5.4

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

* [PATCH v17 03/15] sk_run_filter: add BPF_S_ANC_SECCOMP_LD_W
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Introduces a new BPF ancillary instruction that all LD calls will be
mapped through when skb_run_filter() is being used for seccomp BPF.  The
rewriting will be done using a secondary chk_filter function that is run
after skb_chk_filter.

The code change is guarded by CONFIG_SECCOMP_FILTER which is added,
along with the seccomp_bpf_load() function later in this series.

This is based on http://lkml.org/lkml/2012/3/2/141

v17: rebase
v16: -
v15: include seccomp.h explicitly for when seccomp_bpf_load exists.
v14: First cut using a single additional instruction
... v13: made bpf functions generic.

Suggested-by: Indan Zupancic <indan@nul.nu>
Signed-off-by: Will Drewry <wad@chromium.org>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/linux/filter.h |    1 +
 net/core/filter.c      |    6 ++++++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index 8eeb205..aaa2e80 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -228,6 +228,7 @@ enum {
 	BPF_S_ANC_HATYPE,
 	BPF_S_ANC_RXHASH,
 	BPF_S_ANC_CPU,
+	BPF_S_ANC_SECCOMP_LD_W,
 };
 
 #endif /* __KERNEL__ */
diff --git a/net/core/filter.c b/net/core/filter.c
index cf4989a..b6caa49 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -38,6 +38,7 @@
 #include <linux/filter.h>
 #include <linux/reciprocal_div.h>
 #include <linux/ratelimit.h>
+#include <linux/seccomp.h>
 
 /* No hurry in this branch */
 static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
@@ -349,6 +350,11 @@ load_b:
 				A = 0;
 			continue;
 		}
+#ifdef CONFIG_SECCOMP_FILTER
+		case BPF_S_ANC_SECCOMP_LD_W:
+			A = seccomp_bpf_load(fentry->k);
+			continue;
+#endif
 		default:
 			WARN_RATELIMIT(1, "Unknown code:%u jt:%u tf:%u k:%u\n",
 				       fentry->code, fentry->jt,
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 03/15] sk_run_filter: add BPF_S_ANC_SECCOMP_LD_W
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Introduces a new BPF ancillary instruction that all LD calls will be
mapped through when skb_run_filter() is being used for seccomp BPF.  The
rewriting will be done using a secondary chk_filter function that is run
after skb_chk_filter.

The code change is guarded by CONFIG_SECCOMP_FILTER which is added,
along with the seccomp_bpf_load() function later in this series.

This is based on http://lkml.org/lkml/2012/3/2/141

v17: rebase
v16: -
v15: include seccomp.h explicitly for when seccomp_bpf_load exists.
v14: First cut using a single additional instruction
... v13: made bpf functions generic.

Suggested-by: Indan Zupancic <indan@nul.nu>
Signed-off-by: Will Drewry <wad@chromium.org>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/linux/filter.h |    1 +
 net/core/filter.c      |    6 ++++++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index 8eeb205..aaa2e80 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -228,6 +228,7 @@ enum {
 	BPF_S_ANC_HATYPE,
 	BPF_S_ANC_RXHASH,
 	BPF_S_ANC_CPU,
+	BPF_S_ANC_SECCOMP_LD_W,
 };
 
 #endif /* __KERNEL__ */
diff --git a/net/core/filter.c b/net/core/filter.c
index cf4989a..b6caa49 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -38,6 +38,7 @@
 #include <linux/filter.h>
 #include <linux/reciprocal_div.h>
 #include <linux/ratelimit.h>
+#include <linux/seccomp.h>
 
 /* No hurry in this branch */
 static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
@@ -349,6 +350,11 @@ load_b:
 				A = 0;
 			continue;
 		}
+#ifdef CONFIG_SECCOMP_FILTER
+		case BPF_S_ANC_SECCOMP_LD_W:
+			A = seccomp_bpf_load(fentry->k);
+			continue;
+#endif
 		default:
 			WARN_RATELIMIT(1, "Unknown code:%u jt:%u tf:%u k:%u\n",
 				       fentry->code, fentry->jt,
-- 
1.7.5.4

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

* [PATCH v17 04/15] net/compat.c,linux/filter.h: share compat_sock_fprog
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Any other users of bpf_*_filter that take a struct sock_fprog from
userspace will need to be able to also accept a compat_sock_fprog
if the arch supports compat calls.  This change let's the existing
compat_sock_fprog be shared.

Signed-off-by: Will Drewry <wad@chromium.org>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>

v14..v17: rebase/nochanges
v13: rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: rebase on to linux-next
v11: introduction
---
 include/linux/filter.h |   11 +++++++++++
 net/compat.c           |    8 --------
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index aaa2e80..f2e5315 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -10,6 +10,7 @@
 
 #ifdef __KERNEL__
 #include <linux/atomic.h>
+#include <linux/compat.h>
 #endif
 
 /*
@@ -132,6 +133,16 @@ struct sock_fprog {	/* Required for SO_ATTACH_FILTER. */
 
 #ifdef __KERNEL__
 
+#ifdef CONFIG_COMPAT
+/*
+ * A struct sock_filter is architecture independent.
+ */
+struct compat_sock_fprog {
+	u16		len;
+	compat_uptr_t	filter;		/* struct sock_filter * */
+};
+#endif
+
 struct sk_buff;
 struct sock;
 
diff --git a/net/compat.c b/net/compat.c
index 64b4515..a3a008e 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -326,14 +326,6 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
 	__scm_destroy(scm);
 }
 
-/*
- * A struct sock_filter is architecture independent.
- */
-struct compat_sock_fprog {
-	u16		len;
-	compat_uptr_t	filter;		/* struct sock_filter * */
-};
-
 static int do_set_attach_filter(struct socket *sock, int level, int optname,
 				char __user *optval, unsigned int optlen)
 {
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 04/15] net/compat.c,linux/filter.h: share compat_sock_fprog
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Any other users of bpf_*_filter that take a struct sock_fprog from
userspace will need to be able to also accept a compat_sock_fprog
if the arch supports compat calls.  This change let's the existing
compat_sock_fprog be shared.

Signed-off-by: Will Drewry <wad@chromium.org>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>

v14..v17: rebase/nochanges
v13: rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: rebase on to linux-next
v11: introduction
---
 include/linux/filter.h |   11 +++++++++++
 net/compat.c           |    8 --------
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index aaa2e80..f2e5315 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -10,6 +10,7 @@
 
 #ifdef __KERNEL__
 #include <linux/atomic.h>
+#include <linux/compat.h>
 #endif
 
 /*
@@ -132,6 +133,16 @@ struct sock_fprog {	/* Required for SO_ATTACH_FILTER. */
 
 #ifdef __KERNEL__
 
+#ifdef CONFIG_COMPAT
+/*
+ * A struct sock_filter is architecture independent.
+ */
+struct compat_sock_fprog {
+	u16		len;
+	compat_uptr_t	filter;		/* struct sock_filter * */
+};
+#endif
+
 struct sk_buff;
 struct sock;
 
diff --git a/net/compat.c b/net/compat.c
index 64b4515..a3a008e 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -326,14 +326,6 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
 	__scm_destroy(scm);
 }
 
-/*
- * A struct sock_filter is architecture independent.
- */
-struct compat_sock_fprog {
-	u16		len;
-	compat_uptr_t	filter;		/* struct sock_filter * */
-};
-
 static int do_set_attach_filter(struct socket *sock, int level, int optname,
 				char __user *optval, unsigned int optlen)
 {
-- 
1.7.5.4

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

* [PATCH v17 05/15] seccomp: kill the seccomp_t typedef
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Replaces the seccomp_t typedef with struct seccomp to match modern
kernel style.

v14..v17: rebase/nochanges
v13: rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: rebase on to linux-next
v8-v11: no changes
v7: struct seccomp_struct -> struct seccomp
v6: original inclusion in this series.

Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: Will Drewry <wad@chromium.org>
---
 include/linux/sched.h   |    2 +-
 include/linux/seccomp.h |   10 ++++++----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index ba60897..cad1502 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1452,7 +1452,7 @@ struct task_struct {
 	uid_t loginuid;
 	unsigned int sessionid;
 #endif
-	seccomp_t seccomp;
+	struct seccomp seccomp;
 
 /* Thread group tracking */
    	u32 parent_exec_id;
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index cc7a4e9..d61f27f 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -7,7 +7,9 @@
 #include <linux/thread_info.h>
 #include <asm/seccomp.h>
 
-typedef struct { int mode; } seccomp_t;
+struct seccomp {
+	int mode;
+};
 
 extern void __secure_computing(int);
 static inline void secure_computing(int this_syscall)
@@ -19,7 +21,7 @@ static inline void secure_computing(int this_syscall)
 extern long prctl_get_seccomp(void);
 extern long prctl_set_seccomp(unsigned long);
 
-static inline int seccomp_mode(seccomp_t *s)
+static inline int seccomp_mode(struct seccomp *s)
 {
 	return s->mode;
 }
@@ -28,7 +30,7 @@ static inline int seccomp_mode(seccomp_t *s)
 
 #include <linux/errno.h>
 
-typedef struct { } seccomp_t;
+struct seccomp { };
 
 #define secure_computing(x) do { } while (0)
 
@@ -42,7 +44,7 @@ static inline long prctl_set_seccomp(unsigned long arg2)
 	return -EINVAL;
 }
 
-static inline int seccomp_mode(seccomp_t *s)
+static inline int seccomp_mode(struct seccomp *s)
 {
 	return 0;
 }
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 05/15] seccomp: kill the seccomp_t typedef
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Replaces the seccomp_t typedef with struct seccomp to match modern
kernel style.

v14..v17: rebase/nochanges
v13: rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: rebase on to linux-next
v8-v11: no changes
v7: struct seccomp_struct -> struct seccomp
v6: original inclusion in this series.

Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: Will Drewry <wad@chromium.org>
---
 include/linux/sched.h   |    2 +-
 include/linux/seccomp.h |   10 ++++++----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index ba60897..cad1502 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1452,7 +1452,7 @@ struct task_struct {
 	uid_t loginuid;
 	unsigned int sessionid;
 #endif
-	seccomp_t seccomp;
+	struct seccomp seccomp;
 
 /* Thread group tracking */
    	u32 parent_exec_id;
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index cc7a4e9..d61f27f 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -7,7 +7,9 @@
 #include <linux/thread_info.h>
 #include <asm/seccomp.h>
 
-typedef struct { int mode; } seccomp_t;
+struct seccomp {
+	int mode;
+};
 
 extern void __secure_computing(int);
 static inline void secure_computing(int this_syscall)
@@ -19,7 +21,7 @@ static inline void secure_computing(int this_syscall)
 extern long prctl_get_seccomp(void);
 extern long prctl_set_seccomp(unsigned long);
 
-static inline int seccomp_mode(seccomp_t *s)
+static inline int seccomp_mode(struct seccomp *s)
 {
 	return s->mode;
 }
@@ -28,7 +30,7 @@ static inline int seccomp_mode(seccomp_t *s)
 
 #include <linux/errno.h>
 
-typedef struct { } seccomp_t;
+struct seccomp { };
 
 #define secure_computing(x) do { } while (0)
 
@@ -42,7 +44,7 @@ static inline long prctl_set_seccomp(unsigned long arg2)
 	return -EINVAL;
 }
 
-static inline int seccomp_mode(seccomp_t *s)
+static inline int seccomp_mode(struct seccomp *s)
 {
 	return 0;
 }
-- 
1.7.5.4

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

* [PATCH v17 06/15] arch/x86: add syscall_get_arch to syscall.h
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Add syscall_get_arch() to export the current AUDIT_ARCH_* based on system call
entry path.

Reviewed-by: H. Peter Anvin <hpa@zytor.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Will Drewry <wad@chromium.org>

v17: rebase and reviewed-by
v14: rebase/nochanges
v13: rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
---
 arch/x86/include/asm/syscall.h |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h
index d962e56..1d713e4 100644
--- a/arch/x86/include/asm/syscall.h
+++ b/arch/x86/include/asm/syscall.h
@@ -13,6 +13,7 @@
 #ifndef _ASM_X86_SYSCALL_H
 #define _ASM_X86_SYSCALL_H
 
+#include <linux/audit.h>
 #include <linux/sched.h>
 #include <linux/err.h>
 #include <asm/asm-offsets.h>	/* For NR_syscalls */
@@ -87,6 +88,12 @@ static inline void syscall_set_arguments(struct task_struct *task,
 	memcpy(&regs->bx + i, args, n * sizeof(args[0]));
 }
 
+static inline int syscall_get_arch(struct task_struct *task,
+				   struct pt_regs *regs)
+{
+	return AUDIT_ARCH_I386;
+}
+
 #else	 /* CONFIG_X86_64 */
 
 static inline void syscall_get_arguments(struct task_struct *task,
@@ -211,6 +218,22 @@ static inline void syscall_set_arguments(struct task_struct *task,
 		}
 }
 
+static inline int syscall_get_arch(struct task_struct *task,
+				   struct pt_regs *regs)
+{
+#ifdef CONFIG_IA32_EMULATION
+	/*
+	 * TS_COMPAT is set for 32-bit syscall entries and then
+	 * remains set until we return to user mode.
+	 *
+	 * TIF_IA32 tasks should always have TS_COMPAT set at
+	 * system call time.
+	 */
+	if (task_thread_info(task)->status & TS_COMPAT)
+		return AUDIT_ARCH_I386;
+#endif
+	return AUDIT_ARCH_X86_64;
+}
 #endif	/* CONFIG_X86_32 */
 
 #endif	/* _ASM_X86_SYSCALL_H */
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 06/15] arch/x86: add syscall_get_arch to syscall.h
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Add syscall_get_arch() to export the current AUDIT_ARCH_* based on system call
entry path.

Reviewed-by: H. Peter Anvin <hpa@zytor.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Will Drewry <wad@chromium.org>

v17: rebase and reviewed-by
v14: rebase/nochanges
v13: rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
---
 arch/x86/include/asm/syscall.h |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h
index d962e56..1d713e4 100644
--- a/arch/x86/include/asm/syscall.h
+++ b/arch/x86/include/asm/syscall.h
@@ -13,6 +13,7 @@
 #ifndef _ASM_X86_SYSCALL_H
 #define _ASM_X86_SYSCALL_H
 
+#include <linux/audit.h>
 #include <linux/sched.h>
 #include <linux/err.h>
 #include <asm/asm-offsets.h>	/* For NR_syscalls */
@@ -87,6 +88,12 @@ static inline void syscall_set_arguments(struct task_struct *task,
 	memcpy(&regs->bx + i, args, n * sizeof(args[0]));
 }
 
+static inline int syscall_get_arch(struct task_struct *task,
+				   struct pt_regs *regs)
+{
+	return AUDIT_ARCH_I386;
+}
+
 #else	 /* CONFIG_X86_64 */
 
 static inline void syscall_get_arguments(struct task_struct *task,
@@ -211,6 +218,22 @@ static inline void syscall_set_arguments(struct task_struct *task,
 		}
 }
 
+static inline int syscall_get_arch(struct task_struct *task,
+				   struct pt_regs *regs)
+{
+#ifdef CONFIG_IA32_EMULATION
+	/*
+	 * TS_COMPAT is set for 32-bit syscall entries and then
+	 * remains set until we return to user mode.
+	 *
+	 * TIF_IA32 tasks should always have TS_COMPAT set at
+	 * system call time.
+	 */
+	if (task_thread_info(task)->status & TS_COMPAT)
+		return AUDIT_ARCH_I386;
+#endif
+	return AUDIT_ARCH_X86_64;
+}
 #endif	/* CONFIG_X86_32 */
 
 #endif	/* _ASM_X86_SYSCALL_H */
-- 
1.7.5.4

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

* [PATCH v17 07/15] asm/syscall.h: add syscall_get_arch
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Adds a stub for a function that will return the AUDIT_ARCH_*
value appropriate to the supplied task based on the system
call convention.

For audit's use, the value can generally be hard-coded at the
audit-site.  However, for other functionality not inlined into
syscall entry/exit, this makes that information available.
seccomp_filter is the first planned consumer and, as such,
the comment indicates a tie to HAVE_ARCH_SECCOMP_FILTER.  That
is probably an unneeded detail.

Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Suggested-by: Roland McGrath <mcgrathr@chromium.org>
Signed-off-by: Will Drewry <wad@chromium.org>

v14..v17: rebase/nochanges
v13: rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: rebase on to linux-next
v11: fixed improper return type
v10: introduced
---
 include/asm-generic/syscall.h |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h
index 5c122ae..a2c13dc 100644
--- a/include/asm-generic/syscall.h
+++ b/include/asm-generic/syscall.h
@@ -142,4 +142,18 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
 			   unsigned int i, unsigned int n,
 			   const unsigned long *args);
 
+/**
+ * syscall_get_arch - return the AUDIT_ARCH for the current system call
+ * @task:	task of interest, must be in system call entry tracing
+ * @regs:	task_pt_regs() of @task
+ *
+ * Returns the AUDIT_ARCH_* based on the system call convention in use.
+ *
+ * It's only valid to call this when @task is stopped on entry to a system
+ * call, due to %TIF_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or %TIF_SECCOMP.
+ *
+ * Note, at present this function is only required with
+ * CONFIG_HAVE_ARCH_SECCOMP_FILTER.
+ */
+int syscall_get_arch(struct task_struct *task, struct pt_regs *regs);
 #endif	/* _ASM_SYSCALL_H */
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 07/15] asm/syscall.h: add syscall_get_arch
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Adds a stub for a function that will return the AUDIT_ARCH_*
value appropriate to the supplied task based on the system
call convention.

For audit's use, the value can generally be hard-coded at the
audit-site.  However, for other functionality not inlined into
syscall entry/exit, this makes that information available.
seccomp_filter is the first planned consumer and, as such,
the comment indicates a tie to HAVE_ARCH_SECCOMP_FILTER.  That
is probably an unneeded detail.

Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Suggested-by: Roland McGrath <mcgrathr@chromium.org>
Signed-off-by: Will Drewry <wad@chromium.org>

v14..v17: rebase/nochanges
v13: rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: rebase on to linux-next
v11: fixed improper return type
v10: introduced
---
 include/asm-generic/syscall.h |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h
index 5c122ae..a2c13dc 100644
--- a/include/asm-generic/syscall.h
+++ b/include/asm-generic/syscall.h
@@ -142,4 +142,18 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
 			   unsigned int i, unsigned int n,
 			   const unsigned long *args);
 
+/**
+ * syscall_get_arch - return the AUDIT_ARCH for the current system call
+ * @task:	task of interest, must be in system call entry tracing
+ * @regs:	task_pt_regs() of @task
+ *
+ * Returns the AUDIT_ARCH_* based on the system call convention in use.
+ *
+ * It's only valid to call this when @task is stopped on entry to a system
+ * call, due to %TIF_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or %TIF_SECCOMP.
+ *
+ * Note, at present this function is only required with
+ * CONFIG_HAVE_ARCH_SECCOMP_FILTER.
+ */
+int syscall_get_arch(struct task_struct *task, struct pt_regs *regs);
 #endif	/* _ASM_SYSCALL_H */
-- 
1.7.5.4

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

* [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

[This patch depends on luto@mit.edu's no_new_privs patch:
   https://lkml.org/lkml/2012/1/30/264
 included in this series for ease of consumption.
]

This patch adds support for seccomp mode 2.  Mode 2 introduces the
ability for unprivileged processes to install system call filtering
policy expressed in terms of a Berkeley Packet Filter (BPF) program.
This program will be evaluated in the kernel for each system call
the task makes and computes a result based on data in the format
of struct seccomp_data.

A filter program may be installed by calling:
  struct sock_fprog fprog = { ... };
  ...
  prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &fprog);

The return value of the filter program determines if the system call is
allowed to proceed or denied.  If the first filter program installed
allows prctl(2) calls, then the above call may be made repeatedly
by a task to further reduce its access to the kernel.  All attached
programs must be evaluated before a system call will be allowed to
proceed.

Filter programs will be inherited across fork/clone and execve.
However, if the task attaching the filter is unprivileged
(!CAP_SYS_ADMIN) the no_new_privs bit will be set on the task.  This
ensures that unprivileged tasks cannot attach filters that affect
privileged tasks (e.g., setuid binary).

There are a number of benefits to this approach. A few of which are
as follows:
- BPF has been exposed to userland for a long time
- BPF optimization (and JIT'ing) are well understood
- Userland already knows its ABI: system call numbers and desired
  arguments
- No time-of-check-time-of-use vulnerable data accesses are possible.
- system call arguments are loaded on access only to minimize copying
  required for system call policy decisions.

Mode 2 support is restricted to architectures that enable
HAVE_ARCH_SECCOMP_FILTER.  In this patch, the primary dependency is on
syscall_get_arguments().  The full desired scope of this feature will
add a few minor additional requirements expressed later in this series.
Based on discussion, SECCOMP_RET_ERRNO and SECCOMP_RET_TRACE seem to be
the desired additional functionality.

No architectures are enabled in this patch.

v17: - properly guard seccomp filter needed headers (leann@ubuntu.com)
     - tighten return mask to 0x7fff0000
     - rebase
v16: - no change
v15: - add a 4 instr penalty when counting a path to account for seccomp_filter
       size (indan@nul.nu)
     - drop the max insns to 256KB (indan@nul.nu)
     - return ENOMEM if the max insns limit has been hit (indan@nul.nu)
     - move IP checks after args (indan@nul.nu)
     - drop !user_filter check (indan@nul.nu)
     - only allow explicit bpf codes (indan@nul.nu)
     - exit_code -> exit_sig
v14: - put/get_seccomp_filter takes struct task_struct
       (indan@nul.nu,keescook@chromium.org)
     - adds seccomp_chk_filter and drops general bpf_run/chk_filter user
     - add seccomp_bpf_load for use by net/core/filter.c
     - lower max per-process/per-hierarchy: 1MB
     - moved nnp/capability check prior to allocation
       (all of the above: indan@nul.nu)
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - added a maximum instruction count per path (indan@nul.nu,oleg@redhat.com)
     - removed copy_seccomp (keescook@chromium.org,indan@nul.nu)
     - reworded the prctl_set_seccomp comment (indan@nul.nu)
v11: - reorder struct seccomp_data to allow future args expansion (hpa@zytor.com)
     - style clean up, @compat dropped, compat_sock_fprog32 (indan@nul.nu)
     - do_exit(SIGSYS) (keescook@chromium.org, luto@mit.edu)
     - pare down Kconfig doc reference.
     - extra comment clean up
v10: - seccomp_data has changed again to be more aesthetically pleasing
       (hpa@zytor.com)
     - calling convention is noted in a new u32 field using syscall_get_arch.
       This allows for cross-calling convention tasks to use seccomp filters.
       (hpa@zytor.com)
     - lots of clean up (thanks, Indan!)
 v9: - n/a
 v8: - use bpf_chk_filter, bpf_run_filter. update load_fns
     - Lots of fixes courtesy of indan@nul.nu:
     -- fix up load behavior, compat fixups, and merge alloc code,
     -- renamed pc and dropped __packed, use bool compat.
     -- Added a hidden CONFIG_SECCOMP_FILTER to synthesize non-arch
        dependencies
 v7:  (massive overhaul thanks to Indan, others)
     - added CONFIG_HAVE_ARCH_SECCOMP_FILTER
     - merged into seccomp.c
     - minimal seccomp_filter.h
     - no config option (part of seccomp)
     - no new prctl
     - doesn't break seccomp on systems without asm/syscall.h
       (works but arg access always fails)
     - dropped seccomp_init_task, extra free functions, ...
     - dropped the no-asm/syscall.h code paths
     - merges with network sk_run_filter and sk_chk_filter
 v6: - fix memory leak on attach compat check failure
     - require no_new_privs || CAP_SYS_ADMIN prior to filter
       installation. (luto@mit.edu)
     - s/seccomp_struct_/seccomp_/ for macros/functions (amwang@redhat.com)
     - cleaned up Kconfig (amwang@redhat.com)
     - on block, note if the call was compat (so the # means something)
 v5: - uses syscall_get_arguments
       (indan@nul.nu,oleg@redhat.com, mcgrathr@chromium.org)
      - uses union-based arg storage with hi/lo struct to
        handle endianness.  Compromises between the two alternate
        proposals to minimize extra arg shuffling and account for
        endianness assuming userspace uses offsetof().
        (mcgrathr@chromium.org, indan@nul.nu)
      - update Kconfig description
      - add include/seccomp_filter.h and add its installation
      - (naive) on-demand syscall argument loading
      - drop seccomp_t (eparis@redhat.com)
 v4:  - adjusted prctl to make room for PR_[SG]ET_NO_NEW_PRIVS
      - now uses current->no_new_privs
        (luto@mit.edu,torvalds@linux-foundation.com)
      - assign names to seccomp modes (rdunlap@xenotime.net)
      - fix style issues (rdunlap@xenotime.net)
      - reworded Kconfig entry (rdunlap@xenotime.net)
 v3:  - macros to inline (oleg@redhat.com)
      - init_task behavior fixed (oleg@redhat.com)
      - drop creator entry and extra NULL check (oleg@redhat.com)
      - alloc returns -EINVAL on bad sizing (serge.hallyn@canonical.com)
      - adds tentative use of "always_unprivileged" as per
        torvalds@linux-foundation.org and luto@mit.edu
 v2:  - (patch 2 only)

Reviewed-by: Indan Zupancic <indan@nul.nu>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>

Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/Kconfig            |   17 ++
 include/linux/Kbuild    |    1 +
 include/linux/seccomp.h |   76 +++++++++-
 kernel/fork.c           |    3 +
 kernel/seccomp.c        |  391 ++++++++++++++++++++++++++++++++++++++++++++---
 kernel/sys.c            |    2 +-
 6 files changed, 467 insertions(+), 23 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index a6f14f6..697304d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -213,4 +213,21 @@ config HAVE_CMPXCHG_LOCAL
 config HAVE_CMPXCHG_DOUBLE
 	bool
 
+config HAVE_ARCH_SECCOMP_FILTER
+	bool
+	help
+	  This symbol should be selected by an architecure if it provides
+	  asm/syscall.h, specifically syscall_get_arguments() and
+	  syscall_get_arch().
+
+config SECCOMP_FILTER
+	def_bool y
+	depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET
+	help
+	  Enable tasks to build secure computing environments defined
+	  in terms of Berkeley Packet Filter programs which implement
+	  task-defined system call filtering polices.
+
+	  See Documentation/prctl/seccomp_filter.txt for details.
+
 source "kernel/gcov/Kconfig"
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index a255553..879e5f0 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -332,6 +332,7 @@ header-y += scc.h
 header-y += sched.h
 header-y += screen_info.h
 header-y += sdla.h
+header-y += seccomp.h
 header-y += securebits.h
 header-y += selinux_netlink.h
 header-y += sem.h
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index d61f27f..86bb68f 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -1,14 +1,67 @@
 #ifndef _LINUX_SECCOMP_H
 #define _LINUX_SECCOMP_H
 
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+
+/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */
+#define SECCOMP_MODE_DISABLED	0 /* seccomp is not in use. */
+#define SECCOMP_MODE_STRICT	1 /* uses hard-coded filter. */
+#define SECCOMP_MODE_FILTER	2 /* uses user-supplied filter. */
+
+/*
+ * All BPF programs must return a 32-bit value.
+ * The bottom 16-bits are reserved for future use.
+ * The upper 16-bits are ordered from least permissive values to most.
+ *
+ * The ordering ensures that a min_t() over composed return values always
+ * selects the least permissive choice.
+ */
+#define SECCOMP_RET_KILL	0x00000000U /* kill the task immediately */
+#define SECCOMP_RET_ALLOW	0x7fff0000U /* allow */
+
+/* Masks for the return value sections. */
+#define SECCOMP_RET_ACTION	0x7fff0000U
+#define SECCOMP_RET_DATA	0x0000ffffU
+
+/**
+ * struct seccomp_data - the format the BPF program executes over.
+ * @nr: the system call number
+ * @arch: indicates system call convention as an AUDIT_ARCH_* value
+ *        as defined in <linux/audit.h>.
+ * @instruction_pointer: at the time of the system call.
+ * @args: up to 6 system call arguments always stored as 64-bit values
+ *        regardless of the architecture.
+ */
+struct seccomp_data {
+	int nr;
+	__u32 arch;
+	__u64 instruction_pointer;
+	__u64 args[6];
+};
 
+#ifdef __KERNEL__
 #ifdef CONFIG_SECCOMP
 
 #include <linux/thread_info.h>
 #include <asm/seccomp.h>
 
+struct seccomp_filter;
+/**
+ * struct seccomp - the state of a seccomp'ed process
+ *
+ * @mode:  indicates one of the valid values above for controlled
+ *         system calls available to a process.
+ * @filter: The metadata and ruleset for determining what system calls
+ *          are allowed for a task.
+ *
+ *          @filter must only be accessed from the context of current as there
+ *          is no locking.
+ */
 struct seccomp {
 	int mode;
+	struct seccomp_filter *filter;
 };
 
 extern void __secure_computing(int);
@@ -19,7 +72,7 @@ static inline void secure_computing(int this_syscall)
 }
 
 extern long prctl_get_seccomp(void);
-extern long prctl_set_seccomp(unsigned long);
+extern long prctl_set_seccomp(unsigned long, char __user *);
 
 static inline int seccomp_mode(struct seccomp *s)
 {
@@ -31,15 +84,16 @@ static inline int seccomp_mode(struct seccomp *s)
 #include <linux/errno.h>
 
 struct seccomp { };
+struct seccomp_filter { };
 
-#define secure_computing(x) do { } while (0)
+#define secure_computing(x) 0
 
 static inline long prctl_get_seccomp(void)
 {
 	return -EINVAL;
 }
 
-static inline long prctl_set_seccomp(unsigned long arg2)
+static inline long prctl_set_seccomp(unsigned long arg2, char __user *arg3)
 {
 	return -EINVAL;
 }
@@ -48,7 +102,21 @@ static inline int seccomp_mode(struct seccomp *s)
 {
 	return 0;
 }
-
 #endif /* CONFIG_SECCOMP */
 
+#ifdef CONFIG_SECCOMP_FILTER
+extern void put_seccomp_filter(struct task_struct *tsk);
+extern void get_seccomp_filter(struct task_struct *tsk);
+extern u32 seccomp_bpf_load(int off);
+#else  /* CONFIG_SECCOMP_FILTER */
+static inline void put_seccomp_filter(struct task_struct *tsk)
+{
+	return;
+}
+static inline void get_seccomp_filter(struct task_struct *tsk)
+{
+	return;
+}
+#endif /* CONFIG_SECCOMP_FILTER */
+#endif /* __KERNEL__ */
 #endif /* _LINUX_SECCOMP_H */
diff --git a/kernel/fork.c b/kernel/fork.c
index b9372a0..f7cf6fb 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -34,6 +34,7 @@
 #include <linux/cgroup.h>
 #include <linux/security.h>
 #include <linux/hugetlb.h>
+#include <linux/seccomp.h>
 #include <linux/swap.h>
 #include <linux/syscalls.h>
 #include <linux/jiffies.h>
@@ -170,6 +171,7 @@ void free_task(struct task_struct *tsk)
 	free_thread_info(tsk->stack);
 	rt_mutex_debug_task_free(tsk);
 	ftrace_graph_exit_task(tsk);
+	put_seccomp_filter(tsk);
 	free_task_struct(tsk);
 }
 EXPORT_SYMBOL(free_task);
@@ -1162,6 +1164,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 		goto fork_out;
 
 	ftrace_graph_init_task(p);
+	get_seccomp_filter(p);
 
 	rt_mutex_init_task(p);
 
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index e8d76c5..5fb2d57 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -3,16 +3,338 @@
  *
  * Copyright 2004-2005  Andrea Arcangeli <andrea@cpushare.com>
  *
- * This defines a simple but solid secure-computing mode.
+ * Copyright (C) 2012 Google, Inc.
+ * Will Drewry <wad@chromium.org>
+ *
+ * This defines a simple but solid secure-computing facility.
+ *
+ * Mode 1 uses a fixed list of allowed system calls.
+ * Mode 2 allows user-defined system call filters in the form
+ *        of Berkeley Packet Filters/Linux Socket Filters.
  */
 
+#include <linux/atomic.h>
 #include <linux/audit.h>
-#include <linux/seccomp.h>
-#include <linux/sched.h>
 #include <linux/compat.h>
+#include <linux/sched.h>
+#include <linux/seccomp.h>
 
 /* #define SECCOMP_DEBUG 1 */
-#define NR_SECCOMP_MODES 1
+
+#ifdef CONFIG_SECCOMP_FILTER
+#include <asm/syscall.h>
+#include <linux/filter.h>
+#include <linux/security.h>
+#include <linux/slab.h>
+#include <linux/tracehook.h>
+#include <linux/uaccess.h>
+
+/**
+ * struct seccomp_filter - container for seccomp BPF programs
+ *
+ * @usage: reference count to manage the object liftime.
+ *         get/put helpers should be used when accessing an instance
+ *         outside of a lifetime-guarded section.  In general, this
+ *         is only needed for handling filters shared across tasks.
+ * @prev: points to a previously installed, or inherited, filter
+ * @len: the number of instructions in the program
+ * @insns: the BPF program instructions to evaluate
+ *
+ * seccomp_filter objects are organized in a tree linked via the @prev
+ * pointer.  For any task, it appears to be a singly-linked list starting
+ * with current->seccomp.filter, the most recently attached or inherited filter.
+ * However, multiple filters may share a @prev node, by way of fork(), which
+ * results in a unidirectional tree existing in memory.  This is similar to
+ * how namespaces work.
+ *
+ * seccomp_filter objects should never be modified after being attached
+ * to a task_struct (other than @usage).
+ */
+struct seccomp_filter {
+	atomic_t usage;
+	struct seccomp_filter *prev;
+	unsigned short len;  /* Instruction count */
+	struct sock_filter insns[];
+};
+
+/* Limit any path through the tree to 256KB worth of instructions. */
+#define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
+
+static void seccomp_filter_log_failure(int syscall)
+{
+	int compat = 0;
+#ifdef CONFIG_COMPAT
+	compat = is_compat_task();
+#endif
+	pr_info("%s[%d]: %ssystem call %d blocked at 0x%lx\n",
+		current->comm, task_pid_nr(current),
+		(compat ? "compat " : ""),
+		syscall, KSTK_EIP(current));
+}
+
+/**
+ * get_u32 - returns a u32 offset into data
+ * @data: a unsigned 64 bit value
+ * @index: 0 or 1 to return the first or second 32-bits
+ *
+ * This inline exists to hide the length of unsigned long.
+ * If a 32-bit unsigned long is passed in, it will be extended
+ * and the top 32-bits will be 0. If it is a 64-bit unsigned
+ * long, then whatever data is resident will be properly returned.
+ */
+static inline u32 get_u32(u64 data, int index)
+{
+	return ((u32 *)&data)[index];
+}
+
+/* Helper for bpf_load below. */
+#define BPF_DATA(_name) offsetof(struct seccomp_data, _name)
+/**
+ * bpf_load: checks and returns a pointer to the requested offset
+ * @off: offset into struct seccomp_data to load from
+ *
+ * Returns the requested 32-bits of data.
+ * seccomp_chk_filter() should assure that @off is 32-bit aligned
+ * and not out of bounds.  Failure to do so is a BUG.
+ */
+u32 seccomp_bpf_load(int off)
+{
+	struct pt_regs *regs = task_pt_regs(current);
+	if (off == BPF_DATA(nr))
+		return syscall_get_nr(current, regs);
+	if (off == BPF_DATA(arch))
+		return syscall_get_arch(current, regs);
+	if (off >= BPF_DATA(args[0]) && off < BPF_DATA(args[6])) {
+		unsigned long value;
+		int arg = (off - BPF_DATA(args[0])) / sizeof(u64);
+		int index = !!(off % sizeof(u64));
+		syscall_get_arguments(current, regs, arg, 1, &value);
+		return get_u32(value, index);
+	}
+	if (off == BPF_DATA(instruction_pointer))
+		return get_u32(KSTK_EIP(current), 0);
+	if (off == BPF_DATA(instruction_pointer) + sizeof(u32))
+		return get_u32(KSTK_EIP(current), 1);
+	/* seccomp_chk_filter should make this impossible. */
+	BUG();
+}
+
+/**
+ *	seccomp_chk_filter - verify seccomp filter code
+ *	@filter: filter to verify
+ *	@flen: length of filter
+ *
+ * Takes a previously checked filter (by sk_chk_filter) and
+ * redirects all filter code that loads struct sk_buff data
+ * and related data through seccomp_bpf_load.  It also
+ * enforces length and alignment checking of those loads.
+ *
+ * Returns 0 if the rule set is legal or -EINVAL if not.
+ */
+static int seccomp_chk_filter(struct sock_filter *filter, unsigned int flen)
+{
+	int pc;
+	for (pc = 0; pc < flen; pc++) {
+		struct sock_filter *ftest = &filter[pc];
+		u16 code = ftest->code;
+		u32 k = ftest->k;
+		switch (code) {
+		case BPF_S_LD_W_ABS:
+			ftest->code = BPF_S_ANC_SECCOMP_LD_W;
+			/* 32-bit aligned and not out of bounds. */
+			if (k >= sizeof(struct seccomp_data) || k & 3)
+				return -EINVAL;
+			continue;
+		case BPF_S_LD_W_LEN:
+			ftest->code = BPF_S_LD_IMM;
+			ftest->k = sizeof(struct seccomp_data);
+			continue;
+		case BPF_S_LDX_W_LEN:
+			ftest->code = BPF_S_LDX_IMM;
+			ftest->k = sizeof(struct seccomp_data);
+			continue;
+		/* Explicitly include allowed calls. */
+		case BPF_S_RET_K:
+		case BPF_S_RET_A:
+		case BPF_S_ALU_ADD_K:
+		case BPF_S_ALU_ADD_X:
+		case BPF_S_ALU_SUB_K:
+		case BPF_S_ALU_SUB_X:
+		case BPF_S_ALU_MUL_K:
+		case BPF_S_ALU_MUL_X:
+		case BPF_S_ALU_DIV_X:
+		case BPF_S_ALU_AND_K:
+		case BPF_S_ALU_AND_X:
+		case BPF_S_ALU_OR_K:
+		case BPF_S_ALU_OR_X:
+		case BPF_S_ALU_LSH_K:
+		case BPF_S_ALU_LSH_X:
+		case BPF_S_ALU_RSH_K:
+		case BPF_S_ALU_RSH_X:
+		case BPF_S_ALU_NEG:
+		case BPF_S_LD_IMM:
+		case BPF_S_LDX_IMM:
+		case BPF_S_MISC_TAX:
+		case BPF_S_MISC_TXA:
+		case BPF_S_ALU_DIV_K:
+		case BPF_S_LD_MEM:
+		case BPF_S_LDX_MEM:
+		case BPF_S_ST:
+		case BPF_S_STX:
+		case BPF_S_JMP_JA:
+		case BPF_S_JMP_JEQ_K:
+		case BPF_S_JMP_JEQ_X:
+		case BPF_S_JMP_JGE_K:
+		case BPF_S_JMP_JGE_X:
+		case BPF_S_JMP_JGT_K:
+		case BPF_S_JMP_JGT_X:
+		case BPF_S_JMP_JSET_K:
+		case BPF_S_JMP_JSET_X:
+			continue;
+		default:
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+/**
+ * seccomp_run_filters - evaluates all seccomp filters against @syscall
+ * @syscall: number of the current system call
+ *
+ * Returns valid seccomp BPF response codes.
+ */
+static u32 seccomp_run_filters(int syscall)
+{
+	struct seccomp_filter *f;
+	u32 ret = SECCOMP_RET_KILL;
+	/*
+	 * All filters are evaluated in order of youngest to oldest. The lowest
+	 * BPF return value always takes priority.
+	 */
+	for (f = current->seccomp.filter; f; f = f->prev) {
+		ret = sk_run_filter(NULL, f->insns);
+		if (ret != SECCOMP_RET_ALLOW)
+			break;
+	}
+	return ret;
+}
+
+/**
+ * seccomp_attach_filter: Attaches a seccomp filter to current.
+ * @fprog: BPF program to install
+ *
+ * Returns 0 on success or an errno on failure.
+ */
+static long seccomp_attach_filter(struct sock_fprog *fprog)
+{
+	struct seccomp_filter *filter;
+	unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
+	unsigned long total_insns = fprog->len;
+	long ret;
+
+	if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
+		return -EINVAL;
+
+	for (filter = current->seccomp.filter; filter; filter = filter->prev)
+		total_insns += filter->len + 4;  /* include a 4 instr penalty */
+	if (total_insns > MAX_INSNS_PER_PATH)
+		return -ENOMEM;
+
+	/*
+	 * Installing a seccomp filter requires that the task have
+	 * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
+	 * This avoids scenarios where unprivileged tasks can affect the
+	 * behavior of privileged children.
+	 */
+	if (!current->no_new_privs &&
+	    security_capable_noaudit(current_cred(), current_user_ns(),
+				     CAP_SYS_ADMIN) != 0)
+		return -EACCES;
+
+	/* Allocate a new seccomp_filter */
+	filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
+	if (!filter)
+		return -ENOMEM;
+	atomic_set(&filter->usage, 1);
+	filter->len = fprog->len;
+
+	/* Copy the instructions from fprog. */
+	ret = -EFAULT;
+	if (copy_from_user(filter->insns, fprog->filter, fp_size))
+		goto fail;
+
+	/* Check and rewrite the fprog via the skb checker */
+	ret = sk_chk_filter(filter->insns, filter->len);
+	if (ret)
+		goto fail;
+
+	/* Check and rewrite the fprog for seccomp use */
+	ret = seccomp_chk_filter(filter->insns, filter->len);
+	if (ret)
+		goto fail;
+
+	/*
+	 * If there is an existing filter, make it the prev and don't drop its
+	 * task reference.
+	 */
+	filter->prev = current->seccomp.filter;
+	current->seccomp.filter = filter;
+	return 0;
+fail:
+	kfree(filter);
+	return ret;
+}
+
+/**
+ * seccomp_attach_user_filter - attaches a user-supplied sock_fprog
+ * @user_filter: pointer to the user data containing a sock_fprog.
+ *
+ * Returns 0 on success and non-zero otherwise.
+ */
+long seccomp_attach_user_filter(char __user *user_filter)
+{
+	struct sock_fprog fprog;
+	long ret = -EFAULT;
+
+#ifdef CONFIG_COMPAT
+	if (is_compat_task()) {
+		struct compat_sock_fprog fprog32;
+		if (copy_from_user(&fprog32, user_filter, sizeof(fprog32)))
+			goto out;
+		fprog.len = fprog32.len;
+		fprog.filter = compat_ptr(fprog32.filter);
+	} else /* falls through to the if below. */
+#endif
+	if (copy_from_user(&fprog, user_filter, sizeof(fprog)))
+		goto out;
+	ret = seccomp_attach_filter(&fprog);
+out:
+	return ret;
+}
+
+/* get_seccomp_filter - increments the reference count of the filter on @tsk */
+void get_seccomp_filter(struct task_struct *tsk)
+{
+	struct seccomp_filter *orig = tsk->seccomp.filter;
+	if (!orig)
+		return;
+	/* Reference count is bounded by the number of total processes. */
+	atomic_inc(&orig->usage);
+}
+
+/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
+void put_seccomp_filter(struct task_struct *tsk)
+{
+	struct seccomp_filter *orig = tsk->seccomp.filter;
+	/* Clean up single-reference branches iteratively. */
+	while (orig && atomic_dec_and_test(&orig->usage)) {
+		struct seccomp_filter *freeme = orig;
+		orig = orig->prev;
+		kfree(freeme);
+	}
+}
+#endif	/* CONFIG_SECCOMP_FILTER */
 
 /*
  * Secure computing mode 1 allows only read/write/exit/sigreturn.
@@ -34,10 +356,11 @@ static int mode1_syscalls_32[] = {
 void __secure_computing(int this_syscall)
 {
 	int mode = current->seccomp.mode;
-	int * syscall;
+	int exit_sig = 0;
+	int *syscall;
 
 	switch (mode) {
-	case 1:
+	case SECCOMP_MODE_STRICT:
 		syscall = mode1_syscalls;
 #ifdef CONFIG_COMPAT
 		if (is_compat_task())
@@ -47,7 +370,16 @@ void __secure_computing(int this_syscall)
 			if (*syscall == this_syscall)
 				return;
 		} while (*++syscall);
+		exit_sig = SIGKILL;
+		break;
+#ifdef CONFIG_SECCOMP_FILTER
+	case SECCOMP_MODE_FILTER:
+		if (seccomp_run_filters(this_syscall) == SECCOMP_RET_ALLOW)
+			return;
+		seccomp_filter_log_failure(this_syscall);
+		exit_sig = SIGSYS;
 		break;
+#endif
 	default:
 		BUG();
 	}
@@ -56,7 +388,7 @@ void __secure_computing(int this_syscall)
 	dump_stack();
 #endif
 	audit_seccomp(this_syscall);
-	do_exit(SIGKILL);
+	do_exit(exit_sig);
 }
 
 long prctl_get_seccomp(void)
@@ -64,25 +396,48 @@ long prctl_get_seccomp(void)
 	return current->seccomp.mode;
 }
 
-long prctl_set_seccomp(unsigned long seccomp_mode)
+/**
+ * prctl_set_seccomp: configures current->seccomp.mode
+ * @seccomp_mode: requested mode to use
+ * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER
+ *
+ * This function may be called repeatedly with a @seccomp_mode of
+ * SECCOMP_MODE_FILTER to install additional filters.  Every filter
+ * successfully installed will be evaluated (in reverse order) for each system
+ * call the task makes.
+ *
+ * Once current->seccomp.mode is non-zero, it may not be changed.
+ *
+ * Returns 0 on success or -EINVAL on failure.
+ */
+long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter)
 {
-	long ret;
+	long ret = -EINVAL;
 
-	/* can set it only once to be even more secure */
-	ret = -EPERM;
-	if (unlikely(current->seccomp.mode))
+	if (current->seccomp.mode &&
+	    current->seccomp.mode != seccomp_mode)
 		goto out;
 
-	ret = -EINVAL;
-	if (seccomp_mode && seccomp_mode <= NR_SECCOMP_MODES) {
-		current->seccomp.mode = seccomp_mode;
-		set_thread_flag(TIF_SECCOMP);
+	switch (seccomp_mode) {
+	case SECCOMP_MODE_STRICT:
+		ret = 0;
 #ifdef TIF_NOTSC
 		disable_TSC();
 #endif
-		ret = 0;
+		break;
+#ifdef CONFIG_SECCOMP_FILTER
+	case SECCOMP_MODE_FILTER:
+		ret = seccomp_attach_user_filter(filter);
+		if (ret)
+			goto out;
+		break;
+#endif
+	default:
+		goto out;
 	}
 
- out:
+	current->seccomp.mode = seccomp_mode;
+	set_thread_flag(TIF_SECCOMP);
+out:
 	return ret;
 }
diff --git a/kernel/sys.c b/kernel/sys.c
index b82568b..ba0ae8e 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1908,7 +1908,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 			error = prctl_get_seccomp();
 			break;
 		case PR_SET_SECCOMP:
-			error = prctl_set_seccomp(arg2);
+			error = prctl_set_seccomp(arg2, (char __user *)arg3);
 			break;
 		case PR_GET_TSC:
 			error = GET_TSC_CTL(arg2);
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

[This patch depends on luto@mit.edu's no_new_privs patch:
   https://lkml.org/lkml/2012/1/30/264
 included in this series for ease of consumption.
]

This patch adds support for seccomp mode 2.  Mode 2 introduces the
ability for unprivileged processes to install system call filtering
policy expressed in terms of a Berkeley Packet Filter (BPF) program.
This program will be evaluated in the kernel for each system call
the task makes and computes a result based on data in the format
of struct seccomp_data.

A filter program may be installed by calling:
  struct sock_fprog fprog = { ... };
  ...
  prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &fprog);

The return value of the filter program determines if the system call is
allowed to proceed or denied.  If the first filter program installed
allows prctl(2) calls, then the above call may be made repeatedly
by a task to further reduce its access to the kernel.  All attached
programs must be evaluated before a system call will be allowed to
proceed.

Filter programs will be inherited across fork/clone and execve.
However, if the task attaching the filter is unprivileged
(!CAP_SYS_ADMIN) the no_new_privs bit will be set on the task.  This
ensures that unprivileged tasks cannot attach filters that affect
privileged tasks (e.g., setuid binary).

There are a number of benefits to this approach. A few of which are
as follows:
- BPF has been exposed to userland for a long time
- BPF optimization (and JIT'ing) are well understood
- Userland already knows its ABI: system call numbers and desired
  arguments
- No time-of-check-time-of-use vulnerable data accesses are possible.
- system call arguments are loaded on access only to minimize copying
  required for system call policy decisions.

Mode 2 support is restricted to architectures that enable
HAVE_ARCH_SECCOMP_FILTER.  In this patch, the primary dependency is on
syscall_get_arguments().  The full desired scope of this feature will
add a few minor additional requirements expressed later in this series.
Based on discussion, SECCOMP_RET_ERRNO and SECCOMP_RET_TRACE seem to be
the desired additional functionality.

No architectures are enabled in this patch.

v17: - properly guard seccomp filter needed headers (leann@ubuntu.com)
     - tighten return mask to 0x7fff0000
     - rebase
v16: - no change
v15: - add a 4 instr penalty when counting a path to account for seccomp_filter
       size (indan@nul.nu)
     - drop the max insns to 256KB (indan@nul.nu)
     - return ENOMEM if the max insns limit has been hit (indan@nul.nu)
     - move IP checks after args (indan@nul.nu)
     - drop !user_filter check (indan@nul.nu)
     - only allow explicit bpf codes (indan@nul.nu)
     - exit_code -> exit_sig
v14: - put/get_seccomp_filter takes struct task_struct
       (indan@nul.nu,keescook@chromium.org)
     - adds seccomp_chk_filter and drops general bpf_run/chk_filter user
     - add seccomp_bpf_load for use by net/core/filter.c
     - lower max per-process/per-hierarchy: 1MB
     - moved nnp/capability check prior to allocation
       (all of the above: indan@nul.nu)
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - added a maximum instruction count per path (indan@nul.nu,oleg@redhat.com)
     - removed copy_seccomp (keescook@chromium.org,indan@nul.nu)
     - reworded the prctl_set_seccomp comment (indan@nul.nu)
v11: - reorder struct seccomp_data to allow future args expansion (hpa@zytor.com)
     - style clean up, @compat dropped, compat_sock_fprog32 (indan@nul.nu)
     - do_exit(SIGSYS) (keescook@chromium.org, luto@mit.edu)
     - pare down Kconfig doc reference.
     - extra comment clean up
v10: - seccomp_data has changed again to be more aesthetically pleasing
       (hpa@zytor.com)
     - calling convention is noted in a new u32 field using syscall_get_arch.
       This allows for cross-calling convention tasks to use seccomp filters.
       (hpa@zytor.com)
     - lots of clean up (thanks, Indan!)
 v9: - n/a
 v8: - use bpf_chk_filter, bpf_run_filter. update load_fns
     - Lots of fixes courtesy of indan@nul.nu:
     -- fix up load behavior, compat fixups, and merge alloc code,
     -- renamed pc and dropped __packed, use bool compat.
     -- Added a hidden CONFIG_SECCOMP_FILTER to synthesize non-arch
        dependencies
 v7:  (massive overhaul thanks to Indan, others)
     - added CONFIG_HAVE_ARCH_SECCOMP_FILTER
     - merged into seccomp.c
     - minimal seccomp_filter.h
     - no config option (part of seccomp)
     - no new prctl
     - doesn't break seccomp on systems without asm/syscall.h
       (works but arg access always fails)
     - dropped seccomp_init_task, extra free functions, ...
     - dropped the no-asm/syscall.h code paths
     - merges with network sk_run_filter and sk_chk_filter
 v6: - fix memory leak on attach compat check failure
     - require no_new_privs || CAP_SYS_ADMIN prior to filter
       installation. (luto@mit.edu)
     - s/seccomp_struct_/seccomp_/ for macros/functions (amwang@redhat.com)
     - cleaned up Kconfig (amwang@redhat.com)
     - on block, note if the call was compat (so the # means something)
 v5: - uses syscall_get_arguments
       (indan@nul.nu,oleg@redhat.com, mcgrathr@chromium.org)
      - uses union-based arg storage with hi/lo struct to
        handle endianness.  Compromises between the two alternate
        proposals to minimize extra arg shuffling and account for
        endianness assuming userspace uses offsetof().
        (mcgrathr@chromium.org, indan@nul.nu)
      - update Kconfig description
      - add include/seccomp_filter.h and add its installation
      - (naive) on-demand syscall argument loading
      - drop seccomp_t (eparis@redhat.com)
 v4:  - adjusted prctl to make room for PR_[SG]ET_NO_NEW_PRIVS
      - now uses current->no_new_privs
        (luto@mit.edu,torvalds@linux-foundation.com)
      - assign names to seccomp modes (rdunlap@xenotime.net)
      - fix style issues (rdunlap@xenotime.net)
      - reworded Kconfig entry (rdunlap@xenotime.net)
 v3:  - macros to inline (oleg@redhat.com)
      - init_task behavior fixed (oleg@redhat.com)
      - drop creator entry and extra NULL check (oleg@redhat.com)
      - alloc returns -EINVAL on bad sizing (serge.hallyn@canonical.com)
      - adds tentative use of "always_unprivileged" as per
        torvalds@linux-foundation.org and luto@mit.edu
 v2:  - (patch 2 only)

Reviewed-by: Indan Zupancic <indan@nul.nu>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>

Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/Kconfig            |   17 ++
 include/linux/Kbuild    |    1 +
 include/linux/seccomp.h |   76 +++++++++-
 kernel/fork.c           |    3 +
 kernel/seccomp.c        |  391 ++++++++++++++++++++++++++++++++++++++++++++---
 kernel/sys.c            |    2 +-
 6 files changed, 467 insertions(+), 23 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index a6f14f6..697304d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -213,4 +213,21 @@ config HAVE_CMPXCHG_LOCAL
 config HAVE_CMPXCHG_DOUBLE
 	bool
 
+config HAVE_ARCH_SECCOMP_FILTER
+	bool
+	help
+	  This symbol should be selected by an architecure if it provides
+	  asm/syscall.h, specifically syscall_get_arguments() and
+	  syscall_get_arch().
+
+config SECCOMP_FILTER
+	def_bool y
+	depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET
+	help
+	  Enable tasks to build secure computing environments defined
+	  in terms of Berkeley Packet Filter programs which implement
+	  task-defined system call filtering polices.
+
+	  See Documentation/prctl/seccomp_filter.txt for details.
+
 source "kernel/gcov/Kconfig"
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index a255553..879e5f0 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -332,6 +332,7 @@ header-y += scc.h
 header-y += sched.h
 header-y += screen_info.h
 header-y += sdla.h
+header-y += seccomp.h
 header-y += securebits.h
 header-y += selinux_netlink.h
 header-y += sem.h
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index d61f27f..86bb68f 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -1,14 +1,67 @@
 #ifndef _LINUX_SECCOMP_H
 #define _LINUX_SECCOMP_H
 
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+
+/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */
+#define SECCOMP_MODE_DISABLED	0 /* seccomp is not in use. */
+#define SECCOMP_MODE_STRICT	1 /* uses hard-coded filter. */
+#define SECCOMP_MODE_FILTER	2 /* uses user-supplied filter. */
+
+/*
+ * All BPF programs must return a 32-bit value.
+ * The bottom 16-bits are reserved for future use.
+ * The upper 16-bits are ordered from least permissive values to most.
+ *
+ * The ordering ensures that a min_t() over composed return values always
+ * selects the least permissive choice.
+ */
+#define SECCOMP_RET_KILL	0x00000000U /* kill the task immediately */
+#define SECCOMP_RET_ALLOW	0x7fff0000U /* allow */
+
+/* Masks for the return value sections. */
+#define SECCOMP_RET_ACTION	0x7fff0000U
+#define SECCOMP_RET_DATA	0x0000ffffU
+
+/**
+ * struct seccomp_data - the format the BPF program executes over.
+ * @nr: the system call number
+ * @arch: indicates system call convention as an AUDIT_ARCH_* value
+ *        as defined in <linux/audit.h>.
+ * @instruction_pointer: at the time of the system call.
+ * @args: up to 6 system call arguments always stored as 64-bit values
+ *        regardless of the architecture.
+ */
+struct seccomp_data {
+	int nr;
+	__u32 arch;
+	__u64 instruction_pointer;
+	__u64 args[6];
+};
 
+#ifdef __KERNEL__
 #ifdef CONFIG_SECCOMP
 
 #include <linux/thread_info.h>
 #include <asm/seccomp.h>
 
+struct seccomp_filter;
+/**
+ * struct seccomp - the state of a seccomp'ed process
+ *
+ * @mode:  indicates one of the valid values above for controlled
+ *         system calls available to a process.
+ * @filter: The metadata and ruleset for determining what system calls
+ *          are allowed for a task.
+ *
+ *          @filter must only be accessed from the context of current as there
+ *          is no locking.
+ */
 struct seccomp {
 	int mode;
+	struct seccomp_filter *filter;
 };
 
 extern void __secure_computing(int);
@@ -19,7 +72,7 @@ static inline void secure_computing(int this_syscall)
 }
 
 extern long prctl_get_seccomp(void);
-extern long prctl_set_seccomp(unsigned long);
+extern long prctl_set_seccomp(unsigned long, char __user *);
 
 static inline int seccomp_mode(struct seccomp *s)
 {
@@ -31,15 +84,16 @@ static inline int seccomp_mode(struct seccomp *s)
 #include <linux/errno.h>
 
 struct seccomp { };
+struct seccomp_filter { };
 
-#define secure_computing(x) do { } while (0)
+#define secure_computing(x) 0
 
 static inline long prctl_get_seccomp(void)
 {
 	return -EINVAL;
 }
 
-static inline long prctl_set_seccomp(unsigned long arg2)
+static inline long prctl_set_seccomp(unsigned long arg2, char __user *arg3)
 {
 	return -EINVAL;
 }
@@ -48,7 +102,21 @@ static inline int seccomp_mode(struct seccomp *s)
 {
 	return 0;
 }
-
 #endif /* CONFIG_SECCOMP */
 
+#ifdef CONFIG_SECCOMP_FILTER
+extern void put_seccomp_filter(struct task_struct *tsk);
+extern void get_seccomp_filter(struct task_struct *tsk);
+extern u32 seccomp_bpf_load(int off);
+#else  /* CONFIG_SECCOMP_FILTER */
+static inline void put_seccomp_filter(struct task_struct *tsk)
+{
+	return;
+}
+static inline void get_seccomp_filter(struct task_struct *tsk)
+{
+	return;
+}
+#endif /* CONFIG_SECCOMP_FILTER */
+#endif /* __KERNEL__ */
 #endif /* _LINUX_SECCOMP_H */
diff --git a/kernel/fork.c b/kernel/fork.c
index b9372a0..f7cf6fb 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -34,6 +34,7 @@
 #include <linux/cgroup.h>
 #include <linux/security.h>
 #include <linux/hugetlb.h>
+#include <linux/seccomp.h>
 #include <linux/swap.h>
 #include <linux/syscalls.h>
 #include <linux/jiffies.h>
@@ -170,6 +171,7 @@ void free_task(struct task_struct *tsk)
 	free_thread_info(tsk->stack);
 	rt_mutex_debug_task_free(tsk);
 	ftrace_graph_exit_task(tsk);
+	put_seccomp_filter(tsk);
 	free_task_struct(tsk);
 }
 EXPORT_SYMBOL(free_task);
@@ -1162,6 +1164,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 		goto fork_out;
 
 	ftrace_graph_init_task(p);
+	get_seccomp_filter(p);
 
 	rt_mutex_init_task(p);
 
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index e8d76c5..5fb2d57 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -3,16 +3,338 @@
  *
  * Copyright 2004-2005  Andrea Arcangeli <andrea@cpushare.com>
  *
- * This defines a simple but solid secure-computing mode.
+ * Copyright (C) 2012 Google, Inc.
+ * Will Drewry <wad@chromium.org>
+ *
+ * This defines a simple but solid secure-computing facility.
+ *
+ * Mode 1 uses a fixed list of allowed system calls.
+ * Mode 2 allows user-defined system call filters in the form
+ *        of Berkeley Packet Filters/Linux Socket Filters.
  */
 
+#include <linux/atomic.h>
 #include <linux/audit.h>
-#include <linux/seccomp.h>
-#include <linux/sched.h>
 #include <linux/compat.h>
+#include <linux/sched.h>
+#include <linux/seccomp.h>
 
 /* #define SECCOMP_DEBUG 1 */
-#define NR_SECCOMP_MODES 1
+
+#ifdef CONFIG_SECCOMP_FILTER
+#include <asm/syscall.h>
+#include <linux/filter.h>
+#include <linux/security.h>
+#include <linux/slab.h>
+#include <linux/tracehook.h>
+#include <linux/uaccess.h>
+
+/**
+ * struct seccomp_filter - container for seccomp BPF programs
+ *
+ * @usage: reference count to manage the object liftime.
+ *         get/put helpers should be used when accessing an instance
+ *         outside of a lifetime-guarded section.  In general, this
+ *         is only needed for handling filters shared across tasks.
+ * @prev: points to a previously installed, or inherited, filter
+ * @len: the number of instructions in the program
+ * @insns: the BPF program instructions to evaluate
+ *
+ * seccomp_filter objects are organized in a tree linked via the @prev
+ * pointer.  For any task, it appears to be a singly-linked list starting
+ * with current->seccomp.filter, the most recently attached or inherited filter.
+ * However, multiple filters may share a @prev node, by way of fork(), which
+ * results in a unidirectional tree existing in memory.  This is similar to
+ * how namespaces work.
+ *
+ * seccomp_filter objects should never be modified after being attached
+ * to a task_struct (other than @usage).
+ */
+struct seccomp_filter {
+	atomic_t usage;
+	struct seccomp_filter *prev;
+	unsigned short len;  /* Instruction count */
+	struct sock_filter insns[];
+};
+
+/* Limit any path through the tree to 256KB worth of instructions. */
+#define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
+
+static void seccomp_filter_log_failure(int syscall)
+{
+	int compat = 0;
+#ifdef CONFIG_COMPAT
+	compat = is_compat_task();
+#endif
+	pr_info("%s[%d]: %ssystem call %d blocked at 0x%lx\n",
+		current->comm, task_pid_nr(current),
+		(compat ? "compat " : ""),
+		syscall, KSTK_EIP(current));
+}
+
+/**
+ * get_u32 - returns a u32 offset into data
+ * @data: a unsigned 64 bit value
+ * @index: 0 or 1 to return the first or second 32-bits
+ *
+ * This inline exists to hide the length of unsigned long.
+ * If a 32-bit unsigned long is passed in, it will be extended
+ * and the top 32-bits will be 0. If it is a 64-bit unsigned
+ * long, then whatever data is resident will be properly returned.
+ */
+static inline u32 get_u32(u64 data, int index)
+{
+	return ((u32 *)&data)[index];
+}
+
+/* Helper for bpf_load below. */
+#define BPF_DATA(_name) offsetof(struct seccomp_data, _name)
+/**
+ * bpf_load: checks and returns a pointer to the requested offset
+ * @off: offset into struct seccomp_data to load from
+ *
+ * Returns the requested 32-bits of data.
+ * seccomp_chk_filter() should assure that @off is 32-bit aligned
+ * and not out of bounds.  Failure to do so is a BUG.
+ */
+u32 seccomp_bpf_load(int off)
+{
+	struct pt_regs *regs = task_pt_regs(current);
+	if (off == BPF_DATA(nr))
+		return syscall_get_nr(current, regs);
+	if (off == BPF_DATA(arch))
+		return syscall_get_arch(current, regs);
+	if (off >= BPF_DATA(args[0]) && off < BPF_DATA(args[6])) {
+		unsigned long value;
+		int arg = (off - BPF_DATA(args[0])) / sizeof(u64);
+		int index = !!(off % sizeof(u64));
+		syscall_get_arguments(current, regs, arg, 1, &value);
+		return get_u32(value, index);
+	}
+	if (off == BPF_DATA(instruction_pointer))
+		return get_u32(KSTK_EIP(current), 0);
+	if (off == BPF_DATA(instruction_pointer) + sizeof(u32))
+		return get_u32(KSTK_EIP(current), 1);
+	/* seccomp_chk_filter should make this impossible. */
+	BUG();
+}
+
+/**
+ *	seccomp_chk_filter - verify seccomp filter code
+ *	@filter: filter to verify
+ *	@flen: length of filter
+ *
+ * Takes a previously checked filter (by sk_chk_filter) and
+ * redirects all filter code that loads struct sk_buff data
+ * and related data through seccomp_bpf_load.  It also
+ * enforces length and alignment checking of those loads.
+ *
+ * Returns 0 if the rule set is legal or -EINVAL if not.
+ */
+static int seccomp_chk_filter(struct sock_filter *filter, unsigned int flen)
+{
+	int pc;
+	for (pc = 0; pc < flen; pc++) {
+		struct sock_filter *ftest = &filter[pc];
+		u16 code = ftest->code;
+		u32 k = ftest->k;
+		switch (code) {
+		case BPF_S_LD_W_ABS:
+			ftest->code = BPF_S_ANC_SECCOMP_LD_W;
+			/* 32-bit aligned and not out of bounds. */
+			if (k >= sizeof(struct seccomp_data) || k & 3)
+				return -EINVAL;
+			continue;
+		case BPF_S_LD_W_LEN:
+			ftest->code = BPF_S_LD_IMM;
+			ftest->k = sizeof(struct seccomp_data);
+			continue;
+		case BPF_S_LDX_W_LEN:
+			ftest->code = BPF_S_LDX_IMM;
+			ftest->k = sizeof(struct seccomp_data);
+			continue;
+		/* Explicitly include allowed calls. */
+		case BPF_S_RET_K:
+		case BPF_S_RET_A:
+		case BPF_S_ALU_ADD_K:
+		case BPF_S_ALU_ADD_X:
+		case BPF_S_ALU_SUB_K:
+		case BPF_S_ALU_SUB_X:
+		case BPF_S_ALU_MUL_K:
+		case BPF_S_ALU_MUL_X:
+		case BPF_S_ALU_DIV_X:
+		case BPF_S_ALU_AND_K:
+		case BPF_S_ALU_AND_X:
+		case BPF_S_ALU_OR_K:
+		case BPF_S_ALU_OR_X:
+		case BPF_S_ALU_LSH_K:
+		case BPF_S_ALU_LSH_X:
+		case BPF_S_ALU_RSH_K:
+		case BPF_S_ALU_RSH_X:
+		case BPF_S_ALU_NEG:
+		case BPF_S_LD_IMM:
+		case BPF_S_LDX_IMM:
+		case BPF_S_MISC_TAX:
+		case BPF_S_MISC_TXA:
+		case BPF_S_ALU_DIV_K:
+		case BPF_S_LD_MEM:
+		case BPF_S_LDX_MEM:
+		case BPF_S_ST:
+		case BPF_S_STX:
+		case BPF_S_JMP_JA:
+		case BPF_S_JMP_JEQ_K:
+		case BPF_S_JMP_JEQ_X:
+		case BPF_S_JMP_JGE_K:
+		case BPF_S_JMP_JGE_X:
+		case BPF_S_JMP_JGT_K:
+		case BPF_S_JMP_JGT_X:
+		case BPF_S_JMP_JSET_K:
+		case BPF_S_JMP_JSET_X:
+			continue;
+		default:
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+/**
+ * seccomp_run_filters - evaluates all seccomp filters against @syscall
+ * @syscall: number of the current system call
+ *
+ * Returns valid seccomp BPF response codes.
+ */
+static u32 seccomp_run_filters(int syscall)
+{
+	struct seccomp_filter *f;
+	u32 ret = SECCOMP_RET_KILL;
+	/*
+	 * All filters are evaluated in order of youngest to oldest. The lowest
+	 * BPF return value always takes priority.
+	 */
+	for (f = current->seccomp.filter; f; f = f->prev) {
+		ret = sk_run_filter(NULL, f->insns);
+		if (ret != SECCOMP_RET_ALLOW)
+			break;
+	}
+	return ret;
+}
+
+/**
+ * seccomp_attach_filter: Attaches a seccomp filter to current.
+ * @fprog: BPF program to install
+ *
+ * Returns 0 on success or an errno on failure.
+ */
+static long seccomp_attach_filter(struct sock_fprog *fprog)
+{
+	struct seccomp_filter *filter;
+	unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
+	unsigned long total_insns = fprog->len;
+	long ret;
+
+	if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
+		return -EINVAL;
+
+	for (filter = current->seccomp.filter; filter; filter = filter->prev)
+		total_insns += filter->len + 4;  /* include a 4 instr penalty */
+	if (total_insns > MAX_INSNS_PER_PATH)
+		return -ENOMEM;
+
+	/*
+	 * Installing a seccomp filter requires that the task have
+	 * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
+	 * This avoids scenarios where unprivileged tasks can affect the
+	 * behavior of privileged children.
+	 */
+	if (!current->no_new_privs &&
+	    security_capable_noaudit(current_cred(), current_user_ns(),
+				     CAP_SYS_ADMIN) != 0)
+		return -EACCES;
+
+	/* Allocate a new seccomp_filter */
+	filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
+	if (!filter)
+		return -ENOMEM;
+	atomic_set(&filter->usage, 1);
+	filter->len = fprog->len;
+
+	/* Copy the instructions from fprog. */
+	ret = -EFAULT;
+	if (copy_from_user(filter->insns, fprog->filter, fp_size))
+		goto fail;
+
+	/* Check and rewrite the fprog via the skb checker */
+	ret = sk_chk_filter(filter->insns, filter->len);
+	if (ret)
+		goto fail;
+
+	/* Check and rewrite the fprog for seccomp use */
+	ret = seccomp_chk_filter(filter->insns, filter->len);
+	if (ret)
+		goto fail;
+
+	/*
+	 * If there is an existing filter, make it the prev and don't drop its
+	 * task reference.
+	 */
+	filter->prev = current->seccomp.filter;
+	current->seccomp.filter = filter;
+	return 0;
+fail:
+	kfree(filter);
+	return ret;
+}
+
+/**
+ * seccomp_attach_user_filter - attaches a user-supplied sock_fprog
+ * @user_filter: pointer to the user data containing a sock_fprog.
+ *
+ * Returns 0 on success and non-zero otherwise.
+ */
+long seccomp_attach_user_filter(char __user *user_filter)
+{
+	struct sock_fprog fprog;
+	long ret = -EFAULT;
+
+#ifdef CONFIG_COMPAT
+	if (is_compat_task()) {
+		struct compat_sock_fprog fprog32;
+		if (copy_from_user(&fprog32, user_filter, sizeof(fprog32)))
+			goto out;
+		fprog.len = fprog32.len;
+		fprog.filter = compat_ptr(fprog32.filter);
+	} else /* falls through to the if below. */
+#endif
+	if (copy_from_user(&fprog, user_filter, sizeof(fprog)))
+		goto out;
+	ret = seccomp_attach_filter(&fprog);
+out:
+	return ret;
+}
+
+/* get_seccomp_filter - increments the reference count of the filter on @tsk */
+void get_seccomp_filter(struct task_struct *tsk)
+{
+	struct seccomp_filter *orig = tsk->seccomp.filter;
+	if (!orig)
+		return;
+	/* Reference count is bounded by the number of total processes. */
+	atomic_inc(&orig->usage);
+}
+
+/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
+void put_seccomp_filter(struct task_struct *tsk)
+{
+	struct seccomp_filter *orig = tsk->seccomp.filter;
+	/* Clean up single-reference branches iteratively. */
+	while (orig && atomic_dec_and_test(&orig->usage)) {
+		struct seccomp_filter *freeme = orig;
+		orig = orig->prev;
+		kfree(freeme);
+	}
+}
+#endif	/* CONFIG_SECCOMP_FILTER */
 
 /*
  * Secure computing mode 1 allows only read/write/exit/sigreturn.
@@ -34,10 +356,11 @@ static int mode1_syscalls_32[] = {
 void __secure_computing(int this_syscall)
 {
 	int mode = current->seccomp.mode;
-	int * syscall;
+	int exit_sig = 0;
+	int *syscall;
 
 	switch (mode) {
-	case 1:
+	case SECCOMP_MODE_STRICT:
 		syscall = mode1_syscalls;
 #ifdef CONFIG_COMPAT
 		if (is_compat_task())
@@ -47,7 +370,16 @@ void __secure_computing(int this_syscall)
 			if (*syscall == this_syscall)
 				return;
 		} while (*++syscall);
+		exit_sig = SIGKILL;
+		break;
+#ifdef CONFIG_SECCOMP_FILTER
+	case SECCOMP_MODE_FILTER:
+		if (seccomp_run_filters(this_syscall) == SECCOMP_RET_ALLOW)
+			return;
+		seccomp_filter_log_failure(this_syscall);
+		exit_sig = SIGSYS;
 		break;
+#endif
 	default:
 		BUG();
 	}
@@ -56,7 +388,7 @@ void __secure_computing(int this_syscall)
 	dump_stack();
 #endif
 	audit_seccomp(this_syscall);
-	do_exit(SIGKILL);
+	do_exit(exit_sig);
 }
 
 long prctl_get_seccomp(void)
@@ -64,25 +396,48 @@ long prctl_get_seccomp(void)
 	return current->seccomp.mode;
 }
 
-long prctl_set_seccomp(unsigned long seccomp_mode)
+/**
+ * prctl_set_seccomp: configures current->seccomp.mode
+ * @seccomp_mode: requested mode to use
+ * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER
+ *
+ * This function may be called repeatedly with a @seccomp_mode of
+ * SECCOMP_MODE_FILTER to install additional filters.  Every filter
+ * successfully installed will be evaluated (in reverse order) for each system
+ * call the task makes.
+ *
+ * Once current->seccomp.mode is non-zero, it may not be changed.
+ *
+ * Returns 0 on success or -EINVAL on failure.
+ */
+long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter)
 {
-	long ret;
+	long ret = -EINVAL;
 
-	/* can set it only once to be even more secure */
-	ret = -EPERM;
-	if (unlikely(current->seccomp.mode))
+	if (current->seccomp.mode &&
+	    current->seccomp.mode != seccomp_mode)
 		goto out;
 
-	ret = -EINVAL;
-	if (seccomp_mode && seccomp_mode <= NR_SECCOMP_MODES) {
-		current->seccomp.mode = seccomp_mode;
-		set_thread_flag(TIF_SECCOMP);
+	switch (seccomp_mode) {
+	case SECCOMP_MODE_STRICT:
+		ret = 0;
 #ifdef TIF_NOTSC
 		disable_TSC();
 #endif
-		ret = 0;
+		break;
+#ifdef CONFIG_SECCOMP_FILTER
+	case SECCOMP_MODE_FILTER:
+		ret = seccomp_attach_user_filter(filter);
+		if (ret)
+			goto out;
+		break;
+#endif
+	default:
+		goto out;
 	}
 
- out:
+	current->seccomp.mode = seccomp_mode;
+	set_thread_flag(TIF_SECCOMP);
+out:
 	return ret;
 }
diff --git a/kernel/sys.c b/kernel/sys.c
index b82568b..ba0ae8e 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1908,7 +1908,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 			error = prctl_get_seccomp();
 			break;
 		case PR_SET_SECCOMP:
-			error = prctl_set_seccomp(arg2);
+			error = prctl_set_seccomp(arg2, (char __user *)arg3);
 			break;
 		case PR_GET_TSC:
 			error = GET_TSC_CTL(arg2);
-- 
1.7.5.4

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

* [PATCH v17 09/15] seccomp: remove duplicated failure logging
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

From: Kees Cook <keescook@chromium.org>

This consolidates the seccomp filter error logging path and adds more
details to the audit log.

Signed-off-by: Will Drewry <wad@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>

v17: rebase
v16: -
v15: added a return code to the audit_seccomp path by wad@chromium.org
     (suggested by eparis@redhat.com)
v*: original by keescook@chromium.org
---
 include/linux/audit.h |    8 ++++----
 kernel/auditsc.c      |   10 ++++++++--
 kernel/seccomp.c      |   15 +--------------
 3 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index ed3ef19..22f292a 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -463,7 +463,7 @@ extern void audit_putname(const char *name);
 extern void __audit_inode(const char *name, const struct dentry *dentry);
 extern void __audit_inode_child(const struct dentry *dentry,
 				const struct inode *parent);
-extern void __audit_seccomp(unsigned long syscall);
+extern void __audit_seccomp(unsigned long syscall, long signr, int code);
 extern void __audit_ptrace(struct task_struct *t);
 
 static inline int audit_dummy_context(void)
@@ -508,10 +508,10 @@ static inline void audit_inode_child(const struct dentry *dentry,
 }
 void audit_core_dumps(long signr);
 
-static inline void audit_seccomp(unsigned long syscall)
+static inline void audit_seccomp(unsigned long syscall, long signr, int code)
 {
 	if (unlikely(!audit_dummy_context()))
-		__audit_seccomp(syscall);
+		__audit_seccomp(syscall, signr, code);
 }
 
 static inline void audit_ptrace(struct task_struct *t)
@@ -634,7 +634,7 @@ extern int audit_signals;
 #define audit_inode(n,d) do { (void)(d); } while (0)
 #define audit_inode_child(i,p) do { ; } while (0)
 #define audit_core_dumps(i) do { ; } while (0)
-#define audit_seccomp(i) do { ; } while (0)
+#define audit_seccomp(i,s,c) do { ; } while (0)
 #define auditsc_get_stamp(c,t,s) (0)
 #define audit_get_loginuid(t) (-1)
 #define audit_get_sessionid(t) (-1)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index af1de0f..10dc528 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -67,6 +67,7 @@
 #include <linux/syscalls.h>
 #include <linux/capability.h>
 #include <linux/fs_struct.h>
+#include <linux/compat.h>
 
 #include "audit.h"
 
@@ -2710,13 +2711,18 @@ void audit_core_dumps(long signr)
 	audit_log_end(ab);
 }
 
-void __audit_seccomp(unsigned long syscall)
+void __audit_seccomp(unsigned long syscall, long signr, int code)
 {
 	struct audit_buffer *ab;
 
 	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
-	audit_log_abend(ab, "seccomp", SIGKILL);
+	audit_log_abend(ab, "seccomp", signr);
 	audit_log_format(ab, " syscall=%ld", syscall);
+#ifdef CONFIG_COMPAT
+	audit_log_format(ab, " compat=%d", is_compat_task());
+#endif
+	audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current));
+	audit_log_format(ab, " code=0x%x", code);
 	audit_log_end(ab);
 }
 
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 5fb2d57..85cbe37 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -60,18 +60,6 @@ struct seccomp_filter {
 /* Limit any path through the tree to 256KB worth of instructions. */
 #define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
 
-static void seccomp_filter_log_failure(int syscall)
-{
-	int compat = 0;
-#ifdef CONFIG_COMPAT
-	compat = is_compat_task();
-#endif
-	pr_info("%s[%d]: %ssystem call %d blocked at 0x%lx\n",
-		current->comm, task_pid_nr(current),
-		(compat ? "compat " : ""),
-		syscall, KSTK_EIP(current));
-}
-
 /**
  * get_u32 - returns a u32 offset into data
  * @data: a unsigned 64 bit value
@@ -376,7 +364,6 @@ void __secure_computing(int this_syscall)
 	case SECCOMP_MODE_FILTER:
 		if (seccomp_run_filters(this_syscall) == SECCOMP_RET_ALLOW)
 			return;
-		seccomp_filter_log_failure(this_syscall);
 		exit_sig = SIGSYS;
 		break;
 #endif
@@ -387,7 +374,7 @@ void __secure_computing(int this_syscall)
 #ifdef SECCOMP_DEBUG
 	dump_stack();
 #endif
-	audit_seccomp(this_syscall);
+	audit_seccomp(this_syscall, exit_code, SECCOMP_RET_KILL);
 	do_exit(exit_sig);
 }
 
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 09/15] seccomp: remove duplicated failure logging
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

From: Kees Cook <keescook@chromium.org>

This consolidates the seccomp filter error logging path and adds more
details to the audit log.

Signed-off-by: Will Drewry <wad@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>

v17: rebase
v16: -
v15: added a return code to the audit_seccomp path by wad@chromium.org
     (suggested by eparis@redhat.com)
v*: original by keescook@chromium.org
---
 include/linux/audit.h |    8 ++++----
 kernel/auditsc.c      |   10 ++++++++--
 kernel/seccomp.c      |   15 +--------------
 3 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index ed3ef19..22f292a 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -463,7 +463,7 @@ extern void audit_putname(const char *name);
 extern void __audit_inode(const char *name, const struct dentry *dentry);
 extern void __audit_inode_child(const struct dentry *dentry,
 				const struct inode *parent);
-extern void __audit_seccomp(unsigned long syscall);
+extern void __audit_seccomp(unsigned long syscall, long signr, int code);
 extern void __audit_ptrace(struct task_struct *t);
 
 static inline int audit_dummy_context(void)
@@ -508,10 +508,10 @@ static inline void audit_inode_child(const struct dentry *dentry,
 }
 void audit_core_dumps(long signr);
 
-static inline void audit_seccomp(unsigned long syscall)
+static inline void audit_seccomp(unsigned long syscall, long signr, int code)
 {
 	if (unlikely(!audit_dummy_context()))
-		__audit_seccomp(syscall);
+		__audit_seccomp(syscall, signr, code);
 }
 
 static inline void audit_ptrace(struct task_struct *t)
@@ -634,7 +634,7 @@ extern int audit_signals;
 #define audit_inode(n,d) do { (void)(d); } while (0)
 #define audit_inode_child(i,p) do { ; } while (0)
 #define audit_core_dumps(i) do { ; } while (0)
-#define audit_seccomp(i) do { ; } while (0)
+#define audit_seccomp(i,s,c) do { ; } while (0)
 #define auditsc_get_stamp(c,t,s) (0)
 #define audit_get_loginuid(t) (-1)
 #define audit_get_sessionid(t) (-1)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index af1de0f..10dc528 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -67,6 +67,7 @@
 #include <linux/syscalls.h>
 #include <linux/capability.h>
 #include <linux/fs_struct.h>
+#include <linux/compat.h>
 
 #include "audit.h"
 
@@ -2710,13 +2711,18 @@ void audit_core_dumps(long signr)
 	audit_log_end(ab);
 }
 
-void __audit_seccomp(unsigned long syscall)
+void __audit_seccomp(unsigned long syscall, long signr, int code)
 {
 	struct audit_buffer *ab;
 
 	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
-	audit_log_abend(ab, "seccomp", SIGKILL);
+	audit_log_abend(ab, "seccomp", signr);
 	audit_log_format(ab, " syscall=%ld", syscall);
+#ifdef CONFIG_COMPAT
+	audit_log_format(ab, " compat=%d", is_compat_task());
+#endif
+	audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current));
+	audit_log_format(ab, " code=0x%x", code);
 	audit_log_end(ab);
 }
 
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 5fb2d57..85cbe37 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -60,18 +60,6 @@ struct seccomp_filter {
 /* Limit any path through the tree to 256KB worth of instructions. */
 #define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
 
-static void seccomp_filter_log_failure(int syscall)
-{
-	int compat = 0;
-#ifdef CONFIG_COMPAT
-	compat = is_compat_task();
-#endif
-	pr_info("%s[%d]: %ssystem call %d blocked at 0x%lx\n",
-		current->comm, task_pid_nr(current),
-		(compat ? "compat " : ""),
-		syscall, KSTK_EIP(current));
-}
-
 /**
  * get_u32 - returns a u32 offset into data
  * @data: a unsigned 64 bit value
@@ -376,7 +364,6 @@ void __secure_computing(int this_syscall)
 	case SECCOMP_MODE_FILTER:
 		if (seccomp_run_filters(this_syscall) == SECCOMP_RET_ALLOW)
 			return;
-		seccomp_filter_log_failure(this_syscall);
 		exit_sig = SIGSYS;
 		break;
 #endif
@@ -387,7 +374,7 @@ void __secure_computing(int this_syscall)
 #ifdef SECCOMP_DEBUG
 	dump_stack();
 #endif
-	audit_seccomp(this_syscall);
+	audit_seccomp(this_syscall, exit_code, SECCOMP_RET_KILL);
 	do_exit(exit_sig);
 }
 
-- 
1.7.5.4

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

* [PATCH v17 10/15] seccomp: add SECCOMP_RET_ERRNO
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

This change adds the SECCOMP_RET_ERRNO as a valid return value from a
seccomp filter.  Additionally, it makes the first use of the lower
16-bits for storing a filter-supplied errno.  16-bits is more than
enough for the errno-base.h calls.

Returning errors instead of immediately terminating processes that
violate seccomp policy allow for broader use of this functionality
for kernel attack surface reduction.  For example, a linux container
could maintain a whitelist of pre-existing system calls but drop
all new ones with errnos.  This would keep a logically static attack
surface while providing errnos that may allow for graceful failure
without the downside of do_exit() on a bad call.

v17: rebase
v16: -
v15: - use audit_seccomp and add a skip label. (eparis@redhat.com)
     - clean up and pad out return codes (indan@nul.nu)
v14: - no change/rebase
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - move to WARN_ON if filter is NULL
       (oleg@redhat.com, luto@mit.edu, keescook@chromium.org)
     - return immediately for filter==NULL (keescook@chromium.org)
     - change evaluation to only compare the ACTION so that layered
       errnos don't result in the lowest one being returned.
       (keeschook@chromium.org)
v11: - check for NULL filter (keescook@chromium.org)
v10: - change loaders to fn
 v9: - n/a
 v8: - update Kconfig to note new need for syscall_set_return_value.
     - reordered such that TRAP behavior follows on later.
     - made the for loop a little less indent-y
 v7: - introduced

Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/Kconfig            |    6 ++++--
 include/linux/seccomp.h |   15 +++++++++++----
 kernel/seccomp.c        |   47 ++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 697304d..9ba3003 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -217,8 +217,10 @@ config HAVE_ARCH_SECCOMP_FILTER
 	bool
 	help
 	  This symbol should be selected by an architecure if it provides
-	  asm/syscall.h, specifically syscall_get_arguments() and
-	  syscall_get_arch().
+	  asm/syscall.h, specifically syscall_get_arguments(),
+	  syscall_get_arch(), and syscall_set_return_value().  Additionally,
+	  its system call entry path must respect a return value of -1 from
+	  __secure_computing_int() and/or secure_computing().
 
 config SECCOMP_FILTER
 	def_bool y
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 86bb68f..44004df 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -12,13 +12,14 @@
 
 /*
  * All BPF programs must return a 32-bit value.
- * The bottom 16-bits are reserved for future use.
+ * The bottom 16-bits are for optional return data.
  * The upper 16-bits are ordered from least permissive values to most.
  *
  * The ordering ensures that a min_t() over composed return values always
  * selects the least permissive choice.
  */
 #define SECCOMP_RET_KILL	0x00000000U /* kill the task immediately */
+#define SECCOMP_RET_ERRNO	0x00050000U /* returns an errno */
 #define SECCOMP_RET_ALLOW	0x7fff0000U /* allow */
 
 /* Masks for the return value sections. */
@@ -64,11 +65,17 @@ struct seccomp {
 	struct seccomp_filter *filter;
 };
 
-extern void __secure_computing(int);
-static inline void secure_computing(int this_syscall)
+/*
+ * Direct callers to __secure_computing should be updated as
+ * CONFIG_HAVE_ARCH_SECCOMP_FILTER propagates.
+ */
+extern void __secure_computing(int) __deprecated;
+extern int __secure_computing_int(int);
+static inline int secure_computing(int this_syscall)
 {
 	if (unlikely(test_thread_flag(TIF_SECCOMP)))
-		__secure_computing(this_syscall);
+		return  __secure_computing_int(this_syscall);
+	return 0;
 }
 
 extern long prctl_get_seccomp(void);
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 85cbe37..06b97aa 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -195,15 +195,20 @@ static int seccomp_chk_filter(struct sock_filter *filter, unsigned int flen)
 static u32 seccomp_run_filters(int syscall)
 {
 	struct seccomp_filter *f;
-	u32 ret = SECCOMP_RET_KILL;
+	u32 ret = SECCOMP_RET_ALLOW;
+
+	/* Ensure unexpected behavior doesn't result in failing open. */
+	if (WARN_ON(current->seccomp.filter == NULL))
+		return SECCOMP_RET_KILL;
+
 	/*
 	 * All filters are evaluated in order of youngest to oldest. The lowest
-	 * BPF return value always takes priority.
+	 * BPF return value (ignoring the DATA) always takes priority.
 	 */
 	for (f = current->seccomp.filter; f; f = f->prev) {
-		ret = sk_run_filter(NULL, f->insns);
-		if (ret != SECCOMP_RET_ALLOW)
-			break;
+		u32 cur_ret = sk_run_filter(NULL, f->insns);
+		if ((cur_ret & SECCOMP_RET_ACTION) < (ret & SECCOMP_RET_ACTION))
+			ret = cur_ret;
 	}
 	return ret;
 }
@@ -343,9 +348,18 @@ static int mode1_syscalls_32[] = {
 
 void __secure_computing(int this_syscall)
 {
+	/* Filter calls should never use this function. */
+	BUG_ON(current->seccomp.mode == SECCOMP_MODE_FILTER);
+	__secure_computing_int(this_syscall);
+}
+
+int __secure_computing_int(int this_syscall)
+{
 	int mode = current->seccomp.mode;
 	int exit_sig = 0;
 	int *syscall;
+	u32 ret = SECCOMP_RET_KILL;
+	int data;
 
 	switch (mode) {
 	case SECCOMP_MODE_STRICT:
@@ -356,14 +370,26 @@ void __secure_computing(int this_syscall)
 #endif
 		do {
 			if (*syscall == this_syscall)
-				return;
+				return 0;
 		} while (*++syscall);
 		exit_sig = SIGKILL;
 		break;
 #ifdef CONFIG_SECCOMP_FILTER
 	case SECCOMP_MODE_FILTER:
-		if (seccomp_run_filters(this_syscall) == SECCOMP_RET_ALLOW)
-			return;
+		ret = seccomp_run_filters(this_syscall);
+		data = ret & SECCOMP_RET_DATA;
+		switch (code & SECCOMP_RET_ACTION) {
+		case SECCOMP_RET_ERRNO:
+			/* Set the low-order 16-bits as a errno. */
+			syscall_set_return_value(current, task_pt_regs(current),
+						 -data, 0);
+			goto skip;
+		case SECCOMP_RET_ALLOW:
+			return 0;
+		case SECCOMP_RET_KILL:
+		default:
+			break;
+		}
 		exit_sig = SIGSYS;
 		break;
 #endif
@@ -374,8 +400,11 @@ void __secure_computing(int this_syscall)
 #ifdef SECCOMP_DEBUG
 	dump_stack();
 #endif
-	audit_seccomp(this_syscall, exit_code, SECCOMP_RET_KILL);
+	audit_seccomp(this_syscall, exit_sig, ret);
 	do_exit(exit_sig);
+skip:
+	audit_seccomp(this_syscall, exit_sig, ret);
+	return -1;
 }
 
 long prctl_get_seccomp(void)
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 10/15] seccomp: add SECCOMP_RET_ERRNO
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

This change adds the SECCOMP_RET_ERRNO as a valid return value from a
seccomp filter.  Additionally, it makes the first use of the lower
16-bits for storing a filter-supplied errno.  16-bits is more than
enough for the errno-base.h calls.

Returning errors instead of immediately terminating processes that
violate seccomp policy allow for broader use of this functionality
for kernel attack surface reduction.  For example, a linux container
could maintain a whitelist of pre-existing system calls but drop
all new ones with errnos.  This would keep a logically static attack
surface while providing errnos that may allow for graceful failure
without the downside of do_exit() on a bad call.

v17: rebase
v16: -
v15: - use audit_seccomp and add a skip label. (eparis@redhat.com)
     - clean up and pad out return codes (indan@nul.nu)
v14: - no change/rebase
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - move to WARN_ON if filter is NULL
       (oleg@redhat.com, luto@mit.edu, keescook@chromium.org)
     - return immediately for filter==NULL (keescook@chromium.org)
     - change evaluation to only compare the ACTION so that layered
       errnos don't result in the lowest one being returned.
       (keeschook@chromium.org)
v11: - check for NULL filter (keescook@chromium.org)
v10: - change loaders to fn
 v9: - n/a
 v8: - update Kconfig to note new need for syscall_set_return_value.
     - reordered such that TRAP behavior follows on later.
     - made the for loop a little less indent-y
 v7: - introduced

Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/Kconfig            |    6 ++++--
 include/linux/seccomp.h |   15 +++++++++++----
 kernel/seccomp.c        |   47 ++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 697304d..9ba3003 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -217,8 +217,10 @@ config HAVE_ARCH_SECCOMP_FILTER
 	bool
 	help
 	  This symbol should be selected by an architecure if it provides
-	  asm/syscall.h, specifically syscall_get_arguments() and
-	  syscall_get_arch().
+	  asm/syscall.h, specifically syscall_get_arguments(),
+	  syscall_get_arch(), and syscall_set_return_value().  Additionally,
+	  its system call entry path must respect a return value of -1 from
+	  __secure_computing_int() and/or secure_computing().
 
 config SECCOMP_FILTER
 	def_bool y
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 86bb68f..44004df 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -12,13 +12,14 @@
 
 /*
  * All BPF programs must return a 32-bit value.
- * The bottom 16-bits are reserved for future use.
+ * The bottom 16-bits are for optional return data.
  * The upper 16-bits are ordered from least permissive values to most.
  *
  * The ordering ensures that a min_t() over composed return values always
  * selects the least permissive choice.
  */
 #define SECCOMP_RET_KILL	0x00000000U /* kill the task immediately */
+#define SECCOMP_RET_ERRNO	0x00050000U /* returns an errno */
 #define SECCOMP_RET_ALLOW	0x7fff0000U /* allow */
 
 /* Masks for the return value sections. */
@@ -64,11 +65,17 @@ struct seccomp {
 	struct seccomp_filter *filter;
 };
 
-extern void __secure_computing(int);
-static inline void secure_computing(int this_syscall)
+/*
+ * Direct callers to __secure_computing should be updated as
+ * CONFIG_HAVE_ARCH_SECCOMP_FILTER propagates.
+ */
+extern void __secure_computing(int) __deprecated;
+extern int __secure_computing_int(int);
+static inline int secure_computing(int this_syscall)
 {
 	if (unlikely(test_thread_flag(TIF_SECCOMP)))
-		__secure_computing(this_syscall);
+		return  __secure_computing_int(this_syscall);
+	return 0;
 }
 
 extern long prctl_get_seccomp(void);
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 85cbe37..06b97aa 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -195,15 +195,20 @@ static int seccomp_chk_filter(struct sock_filter *filter, unsigned int flen)
 static u32 seccomp_run_filters(int syscall)
 {
 	struct seccomp_filter *f;
-	u32 ret = SECCOMP_RET_KILL;
+	u32 ret = SECCOMP_RET_ALLOW;
+
+	/* Ensure unexpected behavior doesn't result in failing open. */
+	if (WARN_ON(current->seccomp.filter == NULL))
+		return SECCOMP_RET_KILL;
+
 	/*
 	 * All filters are evaluated in order of youngest to oldest. The lowest
-	 * BPF return value always takes priority.
+	 * BPF return value (ignoring the DATA) always takes priority.
 	 */
 	for (f = current->seccomp.filter; f; f = f->prev) {
-		ret = sk_run_filter(NULL, f->insns);
-		if (ret != SECCOMP_RET_ALLOW)
-			break;
+		u32 cur_ret = sk_run_filter(NULL, f->insns);
+		if ((cur_ret & SECCOMP_RET_ACTION) < (ret & SECCOMP_RET_ACTION))
+			ret = cur_ret;
 	}
 	return ret;
 }
@@ -343,9 +348,18 @@ static int mode1_syscalls_32[] = {
 
 void __secure_computing(int this_syscall)
 {
+	/* Filter calls should never use this function. */
+	BUG_ON(current->seccomp.mode == SECCOMP_MODE_FILTER);
+	__secure_computing_int(this_syscall);
+}
+
+int __secure_computing_int(int this_syscall)
+{
 	int mode = current->seccomp.mode;
 	int exit_sig = 0;
 	int *syscall;
+	u32 ret = SECCOMP_RET_KILL;
+	int data;
 
 	switch (mode) {
 	case SECCOMP_MODE_STRICT:
@@ -356,14 +370,26 @@ void __secure_computing(int this_syscall)
 #endif
 		do {
 			if (*syscall == this_syscall)
-				return;
+				return 0;
 		} while (*++syscall);
 		exit_sig = SIGKILL;
 		break;
 #ifdef CONFIG_SECCOMP_FILTER
 	case SECCOMP_MODE_FILTER:
-		if (seccomp_run_filters(this_syscall) == SECCOMP_RET_ALLOW)
-			return;
+		ret = seccomp_run_filters(this_syscall);
+		data = ret & SECCOMP_RET_DATA;
+		switch (code & SECCOMP_RET_ACTION) {
+		case SECCOMP_RET_ERRNO:
+			/* Set the low-order 16-bits as a errno. */
+			syscall_set_return_value(current, task_pt_regs(current),
+						 -data, 0);
+			goto skip;
+		case SECCOMP_RET_ALLOW:
+			return 0;
+		case SECCOMP_RET_KILL:
+		default:
+			break;
+		}
 		exit_sig = SIGSYS;
 		break;
 #endif
@@ -374,8 +400,11 @@ void __secure_computing(int this_syscall)
 #ifdef SECCOMP_DEBUG
 	dump_stack();
 #endif
-	audit_seccomp(this_syscall, exit_code, SECCOMP_RET_KILL);
+	audit_seccomp(this_syscall, exit_sig, ret);
 	do_exit(exit_sig);
+skip:
+	audit_seccomp(this_syscall, exit_sig, ret);
+	return -1;
 }
 
 long prctl_get_seccomp(void)
-- 
1.7.5.4

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

* [PATCH v17 11/15] signal, x86: add SIGSYS info and make it synchronous.
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

This change enables SIGSYS, defines _sigfields._sigsys, and adds
x86 (compat) arch support.  _sigsys defines fields which allow
a signal handler to receive the triggering system call number,
the relevant AUDIT_ARCH_* value for that number, and the address
of the callsite.

SIGSYS is added to the SYNCHRONOUS_MASK because it is desirable for it
to have setup_frame() called for it. The goal is to ensure that
ucontext_t reflects the machine state from the time-of-syscall and not
from another signal handler.

The first consumer of SIGSYS would be seccomp filter.  In particular,
a filter program could specify a new return value, SECCOMP_RET_TRAP,
which would result in the system call being denied and the calling
thread signaled.  This also means that implementing arch-specific
support can be dependent upon HAVE_ARCH_SECCOMP_FILTER.

v17: - rebase and reviewed-by addition
v14: - rebase/nochanges
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - reworded changelog (oleg@redhat.com)
v11: - fix dropped words in the change description
     - added fallback copy_siginfo support.
     - added __ARCH_SIGSYS define to allow stepped arch support.
v10: - first version based on suggestion

Reviewed-by: H. Peter Anvin <hpa@zytor.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Suggested-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/x86/ia32/ia32_signal.c   |    4 ++++
 arch/x86/include/asm/ia32.h   |    6 ++++++
 include/asm-generic/siginfo.h |   22 ++++++++++++++++++++++
 kernel/signal.c               |    9 ++++++++-
 4 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 5563ba1..97521e8 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -74,6 +74,10 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 			switch (from->si_code >> 16) {
 			case __SI_FAULT >> 16:
 				break;
+			case __SI_SYS >> 16:
+				put_user_ex(from->si_syscall, &to->si_syscall);
+				put_user_ex(from->si_arch, &to->si_arch);
+				break;
 			case __SI_CHLD >> 16:
 				put_user_ex(from->si_utime, &to->si_utime);
 				put_user_ex(from->si_stime, &to->si_stime);
diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h
index 1f7e625..541485f 100644
--- a/arch/x86/include/asm/ia32.h
+++ b/arch/x86/include/asm/ia32.h
@@ -126,6 +126,12 @@ typedef struct compat_siginfo {
 			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
+
+		struct {
+			unsigned int _call_addr; /* calling insn */
+			int _syscall;	/* triggering system call number */
+			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
+		} _sigsys;
 	} _sifields;
 } compat_siginfo_t;
 
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
index 0dd4e87..31306f5 100644
--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -90,9 +90,18 @@ typedef struct siginfo {
 			__ARCH_SI_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
+
+		/* SIGSYS */
+		struct {
+			void __user *_call_addr; /* calling insn */
+			int _syscall;	/* triggering system call number */
+			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
+		} _sigsys;
 	} _sifields;
 } siginfo_t;
 
+/* If the arch shares siginfo, then it has SIGSYS. */
+#define __ARCH_SIGSYS
 #endif
 
 /*
@@ -116,6 +125,11 @@ typedef struct siginfo {
 #define si_addr_lsb	_sifields._sigfault._addr_lsb
 #define si_band		_sifields._sigpoll._band
 #define si_fd		_sifields._sigpoll._fd
+#ifdef __ARCH_SIGSYS
+#define si_call_addr	_sifields._sigsys._call_addr
+#define si_syscall	_sifields._sigsys._syscall
+#define si_arch		_sifields._sigsys._arch
+#endif
 
 #ifdef __KERNEL__
 #define __SI_MASK	0xffff0000u
@@ -126,6 +140,7 @@ typedef struct siginfo {
 #define __SI_CHLD	(4 << 16)
 #define __SI_RT		(5 << 16)
 #define __SI_MESGQ	(6 << 16)
+#define __SI_SYS	(7 << 16)
 #define __SI_CODE(T,N)	((T) | ((N) & 0xffff))
 #else
 #define __SI_KILL	0
@@ -135,6 +150,7 @@ typedef struct siginfo {
 #define __SI_CHLD	0
 #define __SI_RT		0
 #define __SI_MESGQ	0
+#define __SI_SYS	0
 #define __SI_CODE(T,N)	(N)
 #endif
 
@@ -232,6 +248,12 @@ typedef struct siginfo {
 #define NSIGPOLL	6
 
 /*
+ * SIGSYS si_codes
+ */
+#define SYS_SECCOMP		(__SI_SYS|1)	/* seccomp triggered */
+#define NSIGSYS	1
+
+/*
  * sigevent definitions
  * 
  * It seems likely that SIGEV_THREAD will have to be handled from 
diff --git a/kernel/signal.c b/kernel/signal.c
index 17afcaf..1a006b5 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -160,7 +160,7 @@ void recalc_sigpending(void)
 
 #define SYNCHRONOUS_MASK \
 	(sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \
-	 sigmask(SIGTRAP) | sigmask(SIGFPE))
+	 sigmask(SIGTRAP) | sigmask(SIGFPE) | sigmask(SIGSYS))
 
 int next_signal(struct sigpending *pending, sigset_t *mask)
 {
@@ -2706,6 +2706,13 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from)
 		err |= __put_user(from->si_uid, &to->si_uid);
 		err |= __put_user(from->si_ptr, &to->si_ptr);
 		break;
+#ifdef __ARCH_SIGSYS
+	case __SI_SYS:
+		err |= __put_user(from->si_call_addr, &to->si_call_addr);
+		err |= __put_user(from->si_syscall, &to->si_syscall);
+		err |= __put_user(from->si_arch, &to->si_arch);
+		break;
+#endif
 	default: /* this is just in case for now ... */
 		err |= __put_user(from->si_pid, &to->si_pid);
 		err |= __put_user(from->si_uid, &to->si_uid);
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 11/15] signal, x86: add SIGSYS info and make it synchronous.
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

This change enables SIGSYS, defines _sigfields._sigsys, and adds
x86 (compat) arch support.  _sigsys defines fields which allow
a signal handler to receive the triggering system call number,
the relevant AUDIT_ARCH_* value for that number, and the address
of the callsite.

SIGSYS is added to the SYNCHRONOUS_MASK because it is desirable for it
to have setup_frame() called for it. The goal is to ensure that
ucontext_t reflects the machine state from the time-of-syscall and not
from another signal handler.

The first consumer of SIGSYS would be seccomp filter.  In particular,
a filter program could specify a new return value, SECCOMP_RET_TRAP,
which would result in the system call being denied and the calling
thread signaled.  This also means that implementing arch-specific
support can be dependent upon HAVE_ARCH_SECCOMP_FILTER.

v17: - rebase and reviewed-by addition
v14: - rebase/nochanges
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - reworded changelog (oleg@redhat.com)
v11: - fix dropped words in the change description
     - added fallback copy_siginfo support.
     - added __ARCH_SIGSYS define to allow stepped arch support.
v10: - first version based on suggestion

Reviewed-by: H. Peter Anvin <hpa@zytor.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Suggested-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/x86/ia32/ia32_signal.c   |    4 ++++
 arch/x86/include/asm/ia32.h   |    6 ++++++
 include/asm-generic/siginfo.h |   22 ++++++++++++++++++++++
 kernel/signal.c               |    9 ++++++++-
 4 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 5563ba1..97521e8 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -74,6 +74,10 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 			switch (from->si_code >> 16) {
 			case __SI_FAULT >> 16:
 				break;
+			case __SI_SYS >> 16:
+				put_user_ex(from->si_syscall, &to->si_syscall);
+				put_user_ex(from->si_arch, &to->si_arch);
+				break;
 			case __SI_CHLD >> 16:
 				put_user_ex(from->si_utime, &to->si_utime);
 				put_user_ex(from->si_stime, &to->si_stime);
diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h
index 1f7e625..541485f 100644
--- a/arch/x86/include/asm/ia32.h
+++ b/arch/x86/include/asm/ia32.h
@@ -126,6 +126,12 @@ typedef struct compat_siginfo {
 			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
+
+		struct {
+			unsigned int _call_addr; /* calling insn */
+			int _syscall;	/* triggering system call number */
+			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
+		} _sigsys;
 	} _sifields;
 } compat_siginfo_t;
 
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
index 0dd4e87..31306f5 100644
--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -90,9 +90,18 @@ typedef struct siginfo {
 			__ARCH_SI_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
+
+		/* SIGSYS */
+		struct {
+			void __user *_call_addr; /* calling insn */
+			int _syscall;	/* triggering system call number */
+			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
+		} _sigsys;
 	} _sifields;
 } siginfo_t;
 
+/* If the arch shares siginfo, then it has SIGSYS. */
+#define __ARCH_SIGSYS
 #endif
 
 /*
@@ -116,6 +125,11 @@ typedef struct siginfo {
 #define si_addr_lsb	_sifields._sigfault._addr_lsb
 #define si_band		_sifields._sigpoll._band
 #define si_fd		_sifields._sigpoll._fd
+#ifdef __ARCH_SIGSYS
+#define si_call_addr	_sifields._sigsys._call_addr
+#define si_syscall	_sifields._sigsys._syscall
+#define si_arch		_sifields._sigsys._arch
+#endif
 
 #ifdef __KERNEL__
 #define __SI_MASK	0xffff0000u
@@ -126,6 +140,7 @@ typedef struct siginfo {
 #define __SI_CHLD	(4 << 16)
 #define __SI_RT		(5 << 16)
 #define __SI_MESGQ	(6 << 16)
+#define __SI_SYS	(7 << 16)
 #define __SI_CODE(T,N)	((T) | ((N) & 0xffff))
 #else
 #define __SI_KILL	0
@@ -135,6 +150,7 @@ typedef struct siginfo {
 #define __SI_CHLD	0
 #define __SI_RT		0
 #define __SI_MESGQ	0
+#define __SI_SYS	0
 #define __SI_CODE(T,N)	(N)
 #endif
 
@@ -232,6 +248,12 @@ typedef struct siginfo {
 #define NSIGPOLL	6
 
 /*
+ * SIGSYS si_codes
+ */
+#define SYS_SECCOMP		(__SI_SYS|1)	/* seccomp triggered */
+#define NSIGSYS	1
+
+/*
  * sigevent definitions
  * 
  * It seems likely that SIGEV_THREAD will have to be handled from 
diff --git a/kernel/signal.c b/kernel/signal.c
index 17afcaf..1a006b5 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -160,7 +160,7 @@ void recalc_sigpending(void)
 
 #define SYNCHRONOUS_MASK \
 	(sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \
-	 sigmask(SIGTRAP) | sigmask(SIGFPE))
+	 sigmask(SIGTRAP) | sigmask(SIGFPE) | sigmask(SIGSYS))
 
 int next_signal(struct sigpending *pending, sigset_t *mask)
 {
@@ -2706,6 +2706,13 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from)
 		err |= __put_user(from->si_uid, &to->si_uid);
 		err |= __put_user(from->si_ptr, &to->si_ptr);
 		break;
+#ifdef __ARCH_SIGSYS
+	case __SI_SYS:
+		err |= __put_user(from->si_call_addr, &to->si_call_addr);
+		err |= __put_user(from->si_syscall, &to->si_syscall);
+		err |= __put_user(from->si_arch, &to->si_arch);
+		break;
+#endif
 	default: /* this is just in case for now ... */
 		err |= __put_user(from->si_pid, &to->si_pid);
 		err |= __put_user(from->si_uid, &to->si_uid);
-- 
1.7.5.4

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

* [PATCH v17 12/15] seccomp: Add SECCOMP_RET_TRAP
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Adds a new return value to seccomp filters that triggers a SIGSYS to be
delivered with the new SYS_SECCOMP si_code.

This allows in-process system call emulation, including just specifying
an errno or cleanly dumping core, rather than just dying.

v17: - rebase
v16: -
v15: - use audit_seccomp/skip
     - pad out error spacing; clean up switch (indan@nul.nu)
v14: - n/a
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - rebase on to linux-next
v11: - clarify the comment (indan@nul.nu)
     - s/sigtrap/sigsys
v10: - use SIGSYS, syscall_get_arch, updates arch/Kconfig
       note suggested-by (though original suggestion had other behaviors)
v9:  - changes to SIGILL
v8:  - clean up based on changes to dependent patches
v7:  - introduction

Suggested-by: Markus Gutschke <markus@chromium.org>
Suggested-by: Julien Tinnes <jln@chromium.org>
Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/Kconfig                  |   14 +++++++++-----
 include/asm-generic/siginfo.h |    2 +-
 include/linux/seccomp.h       |    1 +
 kernel/seccomp.c              |   26 ++++++++++++++++++++++++++
 4 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 9ba3003..a24d213 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -216,11 +216,15 @@ config HAVE_CMPXCHG_DOUBLE
 config HAVE_ARCH_SECCOMP_FILTER
 	bool
 	help
-	  This symbol should be selected by an architecure if it provides
-	  asm/syscall.h, specifically syscall_get_arguments(),
-	  syscall_get_arch(), and syscall_set_return_value().  Additionally,
-	  its system call entry path must respect a return value of -1 from
-	  __secure_computing_int() and/or secure_computing().
+	  This symbol should be selected by an architecure if it provides:
+	  asm/syscall.h:
+	  - syscall_get_arch()
+	  - syscall_get_arguments()
+	  - syscall_rollback()
+	  - syscall_set_return_value()
+	  SIGSYS siginfo_t support must be implemented.
+	  __secure_computing_int()/secure_computing()'s return value must be
+	  checked, with -1 resulting in the syscall being skipped.
 
 config SECCOMP_FILTER
 	def_bool y
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
index 31306f5..af5d035 100644
--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -93,7 +93,7 @@ typedef struct siginfo {
 
 		/* SIGSYS */
 		struct {
-			void __user *_call_addr; /* calling insn */
+			void __user *_call_addr; /* calling user insn */
 			int _syscall;	/* triggering system call number */
 			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
 		} _sigsys;
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 44004df..ecec06c 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -19,6 +19,7 @@
  * selects the least permissive choice.
  */
 #define SECCOMP_RET_KILL	0x00000000U /* kill the task immediately */
+#define SECCOMP_RET_TRAP	0x00030000U /* disallow and force a SIGSYS */
 #define SECCOMP_RET_ERRNO	0x00050000U /* returns an errno */
 #define SECCOMP_RET_ALLOW	0x7fff0000U /* allow */
 
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 06b97aa..9a59c93 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -327,6 +327,26 @@ void put_seccomp_filter(struct task_struct *tsk)
 		kfree(freeme);
 	}
 }
+
+/**
+ * seccomp_send_sigsys - signals the task to allow in-process syscall emulation
+ * @syscall: syscall number to send to userland
+ * @reason: filter-supplied reason code to send to userland (via si_errno)
+ *
+ * Forces a SIGSYS with a code of SYS_SECCOMP and related sigsys info.
+ */
+static void seccomp_send_sigsys(int syscall, int reason)
+{
+	struct siginfo info;
+	memset(&info, 0, sizeof(info));
+	info.si_signo = SIGSYS;
+	info.si_code = SYS_SECCOMP;
+	info.si_call_addr = (void __user *)KSTK_EIP(current);
+	info.si_errno = reason;
+	info.si_arch = syscall_get_arch(current, task_pt_regs(current));
+	info.si_syscall = syscall;
+	force_sig_info(SIGSYS, &info, current);
+}
 #endif	/* CONFIG_SECCOMP_FILTER */
 
 /*
@@ -384,6 +404,12 @@ int __secure_computing_int(int this_syscall)
 			syscall_set_return_value(current, task_pt_regs(current),
 						 -data, 0);
 			goto skip;
+		case SECCOMP_RET_TRAP:
+			/* Show the handler the original registers. */
+			syscall_rollback(current, task_pt_regs(current));
+			/* Let the filter pass back 16 bits of data. */
+			seccomp_send_sigsys(this_syscall, data);
+			goto skip;
 		case SECCOMP_RET_ALLOW:
 			return 0;
 		case SECCOMP_RET_KILL:
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 12/15] seccomp: Add SECCOMP_RET_TRAP
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Adds a new return value to seccomp filters that triggers a SIGSYS to be
delivered with the new SYS_SECCOMP si_code.

This allows in-process system call emulation, including just specifying
an errno or cleanly dumping core, rather than just dying.

v17: - rebase
v16: -
v15: - use audit_seccomp/skip
     - pad out error spacing; clean up switch (indan@nul.nu)
v14: - n/a
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - rebase on to linux-next
v11: - clarify the comment (indan@nul.nu)
     - s/sigtrap/sigsys
v10: - use SIGSYS, syscall_get_arch, updates arch/Kconfig
       note suggested-by (though original suggestion had other behaviors)
v9:  - changes to SIGILL
v8:  - clean up based on changes to dependent patches
v7:  - introduction

Suggested-by: Markus Gutschke <markus@chromium.org>
Suggested-by: Julien Tinnes <jln@chromium.org>
Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/Kconfig                  |   14 +++++++++-----
 include/asm-generic/siginfo.h |    2 +-
 include/linux/seccomp.h       |    1 +
 kernel/seccomp.c              |   26 ++++++++++++++++++++++++++
 4 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 9ba3003..a24d213 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -216,11 +216,15 @@ config HAVE_CMPXCHG_DOUBLE
 config HAVE_ARCH_SECCOMP_FILTER
 	bool
 	help
-	  This symbol should be selected by an architecure if it provides
-	  asm/syscall.h, specifically syscall_get_arguments(),
-	  syscall_get_arch(), and syscall_set_return_value().  Additionally,
-	  its system call entry path must respect a return value of -1 from
-	  __secure_computing_int() and/or secure_computing().
+	  This symbol should be selected by an architecure if it provides:
+	  asm/syscall.h:
+	  - syscall_get_arch()
+	  - syscall_get_arguments()
+	  - syscall_rollback()
+	  - syscall_set_return_value()
+	  SIGSYS siginfo_t support must be implemented.
+	  __secure_computing_int()/secure_computing()'s return value must be
+	  checked, with -1 resulting in the syscall being skipped.
 
 config SECCOMP_FILTER
 	def_bool y
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
index 31306f5..af5d035 100644
--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -93,7 +93,7 @@ typedef struct siginfo {
 
 		/* SIGSYS */
 		struct {
-			void __user *_call_addr; /* calling insn */
+			void __user *_call_addr; /* calling user insn */
 			int _syscall;	/* triggering system call number */
 			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
 		} _sigsys;
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 44004df..ecec06c 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -19,6 +19,7 @@
  * selects the least permissive choice.
  */
 #define SECCOMP_RET_KILL	0x00000000U /* kill the task immediately */
+#define SECCOMP_RET_TRAP	0x00030000U /* disallow and force a SIGSYS */
 #define SECCOMP_RET_ERRNO	0x00050000U /* returns an errno */
 #define SECCOMP_RET_ALLOW	0x7fff0000U /* allow */
 
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 06b97aa..9a59c93 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -327,6 +327,26 @@ void put_seccomp_filter(struct task_struct *tsk)
 		kfree(freeme);
 	}
 }
+
+/**
+ * seccomp_send_sigsys - signals the task to allow in-process syscall emulation
+ * @syscall: syscall number to send to userland
+ * @reason: filter-supplied reason code to send to userland (via si_errno)
+ *
+ * Forces a SIGSYS with a code of SYS_SECCOMP and related sigsys info.
+ */
+static void seccomp_send_sigsys(int syscall, int reason)
+{
+	struct siginfo info;
+	memset(&info, 0, sizeof(info));
+	info.si_signo = SIGSYS;
+	info.si_code = SYS_SECCOMP;
+	info.si_call_addr = (void __user *)KSTK_EIP(current);
+	info.si_errno = reason;
+	info.si_arch = syscall_get_arch(current, task_pt_regs(current));
+	info.si_syscall = syscall;
+	force_sig_info(SIGSYS, &info, current);
+}
 #endif	/* CONFIG_SECCOMP_FILTER */
 
 /*
@@ -384,6 +404,12 @@ int __secure_computing_int(int this_syscall)
 			syscall_set_return_value(current, task_pt_regs(current),
 						 -data, 0);
 			goto skip;
+		case SECCOMP_RET_TRAP:
+			/* Show the handler the original registers. */
+			syscall_rollback(current, task_pt_regs(current));
+			/* Let the filter pass back 16 bits of data. */
+			seccomp_send_sigsys(this_syscall, data);
+			goto skip;
 		case SECCOMP_RET_ALLOW:
 			return 0;
 		case SECCOMP_RET_KILL:
-- 
1.7.5.4

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

* [PATCH v17 13/15] ptrace,seccomp: Add PTRACE_SECCOMP support
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

This change adds support for a new ptrace option, PTRACE_O_TRACESECCOMP,
and a new return value for seccomp BPF programs, SECCOMP_RET_TRACE.

When a tracer specifies the PTRACE_O_TRACESECCOMP ptrace option, the
tracer will be notified, via PTRACE_EVENT_SECCOMP, for any syscall that
results in a BPF program returning SECCOMP_RET_TRACE.  The 16-bit
SECCOMP_RET_DATA mask of the BPF program return value will be passed as
the ptrace_message and may be retrieved using PTRACE_GETEVENTMSG.

If the subordinate process is not using seccomp filter, then no
system call notifications will occur even if the option is specified.

If there is no tracer with PTRACE_O_TRACESECCOMP when SECCOMP_RET_TRACE
is returned, the system call will not be executed and an -ENOSYS errno
will be returned to userspace.

This change adds a dependency on the system call slow path.  Any future
efforts to use the system call fast path for seccomp filter will need to
address this restriction.

v17: - rebase onto refactored ptrace code now in -linus
v16: - update PT_TRACE_MASK to 0xbf4 so that STOP isn't clear on SETOPTIONS call (indan@nul.nu)
       [note PT_TRACE_MASK disappears in linux-next]
v15: - add audit support for non-zero return codes
     - clean up style (indan@nul.nu)
v14: - rebase/nochanges
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
       (Brings back a change to ptrace.c and the masks.)
v12: - rebase to linux-next
     - use ptrace_event and update arch/Kconfig to mention slow-path dependency
     - drop all tracehook changes and inclusion (oleg@redhat.com)
v11: - invert the logic to just make it a PTRACE_SYSCALL accelerator
       (indan@nul.nu)
v10: - moved to PTRACE_O_SECCOMP / PT_TRACE_SECCOMP
v9:  - n/a
v8:  - guarded PTRACE_SECCOMP use with an ifdef
v7:  - introduced

Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/Kconfig            |   11 ++++++-----
 include/linux/ptrace.h  |    5 ++++-
 include/linux/seccomp.h |    1 +
 kernel/seccomp.c        |   12 +++++++++++-
 4 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index a24d213..fafefe6 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -216,15 +216,16 @@ config HAVE_CMPXCHG_DOUBLE
 config HAVE_ARCH_SECCOMP_FILTER
 	bool
 	help
-	  This symbol should be selected by an architecure if it provides:
-	  asm/syscall.h:
+	  An arch should select this symbol if it provides all of these things:
 	  - syscall_get_arch()
 	  - syscall_get_arguments()
 	  - syscall_rollback()
 	  - syscall_set_return_value()
-	  SIGSYS siginfo_t support must be implemented.
-	  __secure_computing_int()/secure_computing()'s return value must be
-	  checked, with -1 resulting in the syscall being skipped.
+	  - SIGSYS siginfo_t support
+	  - uses __secure_computing_int() or secure_computing()
+	  - secure_computing is called from a ptrace_event()-safe context
+	  - secure_computing return value is checked and a return value of -1
+	    results in the system call being skipped immediately.
 
 config SECCOMP_FILTER
 	def_bool y
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 5c71962..597e4fd 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -58,6 +58,7 @@
 #define PTRACE_EVENT_EXEC	4
 #define PTRACE_EVENT_VFORK_DONE	5
 #define PTRACE_EVENT_EXIT	6
+#define PTRACE_EVENT_SECCOMP	7
 /* Extended result codes which enabled by means other than options.  */
 #define PTRACE_EVENT_STOP	128
 
@@ -69,8 +70,9 @@
 #define PTRACE_O_TRACEEXEC	(1 << PTRACE_EVENT_EXEC)
 #define PTRACE_O_TRACEVFORKDONE	(1 << PTRACE_EVENT_VFORK_DONE)
 #define PTRACE_O_TRACEEXIT	(1 << PTRACE_EVENT_EXIT)
+#define PTRACE_O_TRACESECCOMP	(1 << PTRACE_EVENT_SECCOMP)
 
-#define PTRACE_O_MASK		0x0000007f
+#define PTRACE_O_MASK		0x000000ff
 
 #include <asm/ptrace.h>
 
@@ -98,6 +100,7 @@
 #define PT_TRACE_EXEC		PT_EVENT_FLAG(PTRACE_EVENT_EXEC)
 #define PT_TRACE_VFORK_DONE	PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE)
 #define PT_TRACE_EXIT		PT_EVENT_FLAG(PTRACE_EVENT_EXIT)
+#define PT_TRACE_SECCOMP	PT_EVENT_FLAG(PTRACE_EVENT_SECCOMP)
 
 /* single stepping state bits (used on ARM and PA-RISC) */
 #define PT_SINGLESTEP_BIT	31
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index ecec06c..41ff13b 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -21,6 +21,7 @@
 #define SECCOMP_RET_KILL	0x00000000U /* kill the task immediately */
 #define SECCOMP_RET_TRAP	0x00030000U /* disallow and force a SIGSYS */
 #define SECCOMP_RET_ERRNO	0x00050000U /* returns an errno */
+#define SECCOMP_RET_TRACE	0x7ff00000U /* pass to a tracer or disallow */
 #define SECCOMP_RET_ALLOW	0x7fff0000U /* allow */
 
 /* Masks for the return value sections. */
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 9a59c93..4b5affa 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -24,6 +24,7 @@
 #ifdef CONFIG_SECCOMP_FILTER
 #include <asm/syscall.h>
 #include <linux/filter.h>
+#include <linux/ptrace.h>
 #include <linux/security.h>
 #include <linux/slab.h>
 #include <linux/tracehook.h>
@@ -398,7 +399,7 @@ int __secure_computing_int(int this_syscall)
 	case SECCOMP_MODE_FILTER:
 		ret = seccomp_run_filters(this_syscall);
 		data = ret & SECCOMP_RET_DATA;
-		switch (code & SECCOMP_RET_ACTION) {
+		switch (ret & SECCOMP_RET_ACTION) {
 		case SECCOMP_RET_ERRNO:
 			/* Set the low-order 16-bits as a errno. */
 			syscall_set_return_value(current, task_pt_regs(current),
@@ -410,6 +411,15 @@ int __secure_computing_int(int this_syscall)
 			/* Let the filter pass back 16 bits of data. */
 			seccomp_send_sigsys(this_syscall, data);
 			goto skip;
+		case SECCOMP_RET_TRACE:
+			/* Skip these calls if there is no tracer. */
+			if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP))
+				goto skip;
+			/* Allow the BPF to provide the event message */
+			ptrace_event(PTRACE_EVENT_SECCOMP, data);
+			if (fatal_signal_pending(current))
+				break;
+			return 0;
 		case SECCOMP_RET_ALLOW:
 			return 0;
 		case SECCOMP_RET_KILL:
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 13/15] ptrace,seccomp: Add PTRACE_SECCOMP support
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

This change adds support for a new ptrace option, PTRACE_O_TRACESECCOMP,
and a new return value for seccomp BPF programs, SECCOMP_RET_TRACE.

When a tracer specifies the PTRACE_O_TRACESECCOMP ptrace option, the
tracer will be notified, via PTRACE_EVENT_SECCOMP, for any syscall that
results in a BPF program returning SECCOMP_RET_TRACE.  The 16-bit
SECCOMP_RET_DATA mask of the BPF program return value will be passed as
the ptrace_message and may be retrieved using PTRACE_GETEVENTMSG.

If the subordinate process is not using seccomp filter, then no
system call notifications will occur even if the option is specified.

If there is no tracer with PTRACE_O_TRACESECCOMP when SECCOMP_RET_TRACE
is returned, the system call will not be executed and an -ENOSYS errno
will be returned to userspace.

This change adds a dependency on the system call slow path.  Any future
efforts to use the system call fast path for seccomp filter will need to
address this restriction.

v17: - rebase onto refactored ptrace code now in -linus
v16: - update PT_TRACE_MASK to 0xbf4 so that STOP isn't clear on SETOPTIONS call (indan@nul.nu)
       [note PT_TRACE_MASK disappears in linux-next]
v15: - add audit support for non-zero return codes
     - clean up style (indan@nul.nu)
v14: - rebase/nochanges
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
       (Brings back a change to ptrace.c and the masks.)
v12: - rebase to linux-next
     - use ptrace_event and update arch/Kconfig to mention slow-path dependency
     - drop all tracehook changes and inclusion (oleg@redhat.com)
v11: - invert the logic to just make it a PTRACE_SYSCALL accelerator
       (indan@nul.nu)
v10: - moved to PTRACE_O_SECCOMP / PT_TRACE_SECCOMP
v9:  - n/a
v8:  - guarded PTRACE_SECCOMP use with an ifdef
v7:  - introduced

Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/Kconfig            |   11 ++++++-----
 include/linux/ptrace.h  |    5 ++++-
 include/linux/seccomp.h |    1 +
 kernel/seccomp.c        |   12 +++++++++++-
 4 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index a24d213..fafefe6 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -216,15 +216,16 @@ config HAVE_CMPXCHG_DOUBLE
 config HAVE_ARCH_SECCOMP_FILTER
 	bool
 	help
-	  This symbol should be selected by an architecure if it provides:
-	  asm/syscall.h:
+	  An arch should select this symbol if it provides all of these things:
 	  - syscall_get_arch()
 	  - syscall_get_arguments()
 	  - syscall_rollback()
 	  - syscall_set_return_value()
-	  SIGSYS siginfo_t support must be implemented.
-	  __secure_computing_int()/secure_computing()'s return value must be
-	  checked, with -1 resulting in the syscall being skipped.
+	  - SIGSYS siginfo_t support
+	  - uses __secure_computing_int() or secure_computing()
+	  - secure_computing is called from a ptrace_event()-safe context
+	  - secure_computing return value is checked and a return value of -1
+	    results in the system call being skipped immediately.
 
 config SECCOMP_FILTER
 	def_bool y
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 5c71962..597e4fd 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -58,6 +58,7 @@
 #define PTRACE_EVENT_EXEC	4
 #define PTRACE_EVENT_VFORK_DONE	5
 #define PTRACE_EVENT_EXIT	6
+#define PTRACE_EVENT_SECCOMP	7
 /* Extended result codes which enabled by means other than options.  */
 #define PTRACE_EVENT_STOP	128
 
@@ -69,8 +70,9 @@
 #define PTRACE_O_TRACEEXEC	(1 << PTRACE_EVENT_EXEC)
 #define PTRACE_O_TRACEVFORKDONE	(1 << PTRACE_EVENT_VFORK_DONE)
 #define PTRACE_O_TRACEEXIT	(1 << PTRACE_EVENT_EXIT)
+#define PTRACE_O_TRACESECCOMP	(1 << PTRACE_EVENT_SECCOMP)
 
-#define PTRACE_O_MASK		0x0000007f
+#define PTRACE_O_MASK		0x000000ff
 
 #include <asm/ptrace.h>
 
@@ -98,6 +100,7 @@
 #define PT_TRACE_EXEC		PT_EVENT_FLAG(PTRACE_EVENT_EXEC)
 #define PT_TRACE_VFORK_DONE	PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE)
 #define PT_TRACE_EXIT		PT_EVENT_FLAG(PTRACE_EVENT_EXIT)
+#define PT_TRACE_SECCOMP	PT_EVENT_FLAG(PTRACE_EVENT_SECCOMP)
 
 /* single stepping state bits (used on ARM and PA-RISC) */
 #define PT_SINGLESTEP_BIT	31
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index ecec06c..41ff13b 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -21,6 +21,7 @@
 #define SECCOMP_RET_KILL	0x00000000U /* kill the task immediately */
 #define SECCOMP_RET_TRAP	0x00030000U /* disallow and force a SIGSYS */
 #define SECCOMP_RET_ERRNO	0x00050000U /* returns an errno */
+#define SECCOMP_RET_TRACE	0x7ff00000U /* pass to a tracer or disallow */
 #define SECCOMP_RET_ALLOW	0x7fff0000U /* allow */
 
 /* Masks for the return value sections. */
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 9a59c93..4b5affa 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -24,6 +24,7 @@
 #ifdef CONFIG_SECCOMP_FILTER
 #include <asm/syscall.h>
 #include <linux/filter.h>
+#include <linux/ptrace.h>
 #include <linux/security.h>
 #include <linux/slab.h>
 #include <linux/tracehook.h>
@@ -398,7 +399,7 @@ int __secure_computing_int(int this_syscall)
 	case SECCOMP_MODE_FILTER:
 		ret = seccomp_run_filters(this_syscall);
 		data = ret & SECCOMP_RET_DATA;
-		switch (code & SECCOMP_RET_ACTION) {
+		switch (ret & SECCOMP_RET_ACTION) {
 		case SECCOMP_RET_ERRNO:
 			/* Set the low-order 16-bits as a errno. */
 			syscall_set_return_value(current, task_pt_regs(current),
@@ -410,6 +411,15 @@ int __secure_computing_int(int this_syscall)
 			/* Let the filter pass back 16 bits of data. */
 			seccomp_send_sigsys(this_syscall, data);
 			goto skip;
+		case SECCOMP_RET_TRACE:
+			/* Skip these calls if there is no tracer. */
+			if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP))
+				goto skip;
+			/* Allow the BPF to provide the event message */
+			ptrace_event(PTRACE_EVENT_SECCOMP, data);
+			if (fatal_signal_pending(current))
+				break;
+			return 0;
 		case SECCOMP_RET_ALLOW:
 			return 0;
 		case SECCOMP_RET_KILL:
-- 
1.7.5.4

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

* [PATCH v17 14/15] x86: Enable HAVE_ARCH_SECCOMP_FILTER
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:01   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Enable support for seccomp filter on x86:
- asm/tracehook.h exists
- syscall_get_arguments() works
- syscall_rollback() works
- ptrace_report_syscall() works
- secure_computing() return value is honored (see below)

This also adds support for honoring the return
value from secure_computing().

SECCOMP_RET_TRACE and SECCOMP_RET_TRAP may result in seccomp needing to
skip a system call without killing the process.  This is done by
returning a non-zero (-1) value from secure_computing.  This change
makes x86 respect that return value.

To ensure that minimal kernel code is exposed, a non-zero return value
results in an immediate return to user space (with an invalid syscall
number).

v17: added reviewed by and rebased
v..: all rebases since original introduction.

Reviewed-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/x86/Kconfig         |    1 +
 arch/x86/kernel/ptrace.c |    7 ++++++-
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 3ad653d..1f23136 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -83,6 +83,7 @@ config X86
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_IOMAP
 	select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC
+	select HAVE_ARCH_SECCOMP_FILTER
 
 config INSTRUCTION_DECODER
 	def_bool (KPROBES || PERF_EVENTS)
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 8a634c8..a8d3cf9 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -1380,7 +1380,11 @@ long syscall_trace_enter(struct pt_regs *regs)
 		regs->flags |= X86_EFLAGS_TF;
 
 	/* do the secure computing check first */
-	secure_computing(regs->orig_ax);
+	if (secure_computing(regs->orig_ax)) {
+		/* seccomp failures shouldn't expose any additional code. */
+		ret = -1L;
+		goto out;
+	}
 
 	if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
 		ret = -1L;
@@ -1405,6 +1409,7 @@ long syscall_trace_enter(struct pt_regs *regs)
 				    regs->dx, regs->r10);
 #endif
 
+out:
 	return ret ?: regs->orig_ax;
 }
 
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 14/15] x86: Enable HAVE_ARCH_SECCOMP_FILTER
@ 2012-03-29 20:01   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Enable support for seccomp filter on x86:
- asm/tracehook.h exists
- syscall_get_arguments() works
- syscall_rollback() works
- ptrace_report_syscall() works
- secure_computing() return value is honored (see below)

This also adds support for honoring the return
value from secure_computing().

SECCOMP_RET_TRACE and SECCOMP_RET_TRAP may result in seccomp needing to
skip a system call without killing the process.  This is done by
returning a non-zero (-1) value from secure_computing.  This change
makes x86 respect that return value.

To ensure that minimal kernel code is exposed, a non-zero return value
results in an immediate return to user space (with an invalid syscall
number).

v17: added reviewed by and rebased
v..: all rebases since original introduction.

Reviewed-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Will Drewry <wad@chromium.org>
---
 arch/x86/Kconfig         |    1 +
 arch/x86/kernel/ptrace.c |    7 ++++++-
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 3ad653d..1f23136 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -83,6 +83,7 @@ config X86
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_IOMAP
 	select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC
+	select HAVE_ARCH_SECCOMP_FILTER
 
 config INSTRUCTION_DECODER
 	def_bool (KPROBES || PERF_EVENTS)
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 8a634c8..a8d3cf9 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -1380,7 +1380,11 @@ long syscall_trace_enter(struct pt_regs *regs)
 		regs->flags |= X86_EFLAGS_TF;
 
 	/* do the secure computing check first */
-	secure_computing(regs->orig_ax);
+	if (secure_computing(regs->orig_ax)) {
+		/* seccomp failures shouldn't expose any additional code. */
+		ret = -1L;
+		goto out;
+	}
 
 	if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
 		ret = -1L;
@@ -1405,6 +1409,7 @@ long syscall_trace_enter(struct pt_regs *regs)
 				    regs->dx, regs->r10);
 #endif
 
+out:
 	return ret ?: regs->orig_ax;
 }
 
-- 
1.7.5.4

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

* [PATCH v17 15/15] Documentation: prctl/seccomp_filter
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 20:02   ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:02 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Documents how system call filtering using Berkeley Packet
Filter programs works and how it may be used.
Includes an example for x86 and a semi-generic
example using a macro-based code generator.

v17: - remove @compat note and add Pitfalls section for arch checking
       (keescook@chromium.org)
     - rebase
v14...v16: - rebase/nochanges
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - comment on the ptrace_event use
     - update arch support comment
     - note the behavior of SECCOMP_RET_DATA when there are multiple filters
       (keescook@chromium.org)
     - lots of samples/ clean up incl 64-bit bpf-direct support
       (markus@chromium.org)
     - rebase to linux-next
v11: - overhaul return value language, updates (keescook@chromium.org)
     - comment on do_exit(SIGSYS)
v10: - update for SIGSYS
     - update for new seccomp_data layout
     - update for ptrace option use
v9: - updated bpf-direct.c for SIGILL
v8: - add PR_SET_NO_NEW_PRIVS to the samples.
v7: - updated for all the new stuff in v7: TRAP, TRACE
    - only talk about PR_SET_SECCOMP now
    - fixed bad JLE32 check (coreyb@linux.vnet.ibm.com)
    - adds dropper.c: a simple system call disabler
v6: - tweak the language to note the requirement of
      PR_SET_NO_NEW_PRIVS being called prior to use. (luto@mit.edu)
v5: - update sample to use system call arguments
    - adds a "fancy" example using a macro-based generator
    - cleaned up bpf in the sample
    - update docs to mention arguments
    - fix prctl value (eparis@redhat.com)
    - language cleanup (rdunlap@xenotime.net)
v4: - update for no_new_privs use
    - minor tweaks
v3: - call out BPF <-> Berkeley Packet Filter (rdunlap@xenotime.net)
    - document use of tentative always-unprivileged
    - guard sample compilation for i386 and x86_64
v2: - move code to samples (corbet@lwn.net)

Signed-off-by: Will Drewry <wad@chromium.org>
---
 Documentation/prctl/seccomp_filter.txt |  163 ++++++++++++++++++++++
 samples/Makefile                       |    2 +-
 samples/seccomp/Makefile               |   38 +++++
 samples/seccomp/bpf-direct.c           |  176 +++++++++++++++++++++++
 samples/seccomp/bpf-fancy.c            |  102 ++++++++++++++
 samples/seccomp/bpf-helper.c           |   89 ++++++++++++
 samples/seccomp/bpf-helper.h           |  238 ++++++++++++++++++++++++++++++++
 samples/seccomp/dropper.c              |   68 +++++++++
 8 files changed, 875 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/prctl/seccomp_filter.txt
 create mode 100644 samples/seccomp/Makefile
 create mode 100644 samples/seccomp/bpf-direct.c
 create mode 100644 samples/seccomp/bpf-fancy.c
 create mode 100644 samples/seccomp/bpf-helper.c
 create mode 100644 samples/seccomp/bpf-helper.h
 create mode 100644 samples/seccomp/dropper.c

diff --git a/Documentation/prctl/seccomp_filter.txt b/Documentation/prctl/seccomp_filter.txt
new file mode 100644
index 0000000..597c3c5
--- /dev/null
+++ b/Documentation/prctl/seccomp_filter.txt
@@ -0,0 +1,163 @@
+		SECure COMPuting with filters
+		=============================
+
+Introduction
+------------
+
+A large number of system calls are exposed to every userland process
+with many of them going unused for the entire lifetime of the process.
+As system calls change and mature, bugs are found and eradicated.  A
+certain subset of userland applications benefit by having a reduced set
+of available system calls.  The resulting set reduces the total kernel
+surface exposed to the application.  System call filtering is meant for
+use with those applications.
+
+Seccomp filtering provides a means for a process to specify a filter for
+incoming system calls.  The filter is expressed as a Berkeley Packet
+Filter (BPF) program, as with socket filters, except that the data
+operated on is related to the system call being made: system call
+number and the system call arguments.  This allows for expressive
+filtering of system calls using a filter program language with a long
+history of being exposed to userland and a straightforward data set.
+
+Additionally, BPF makes it impossible for users of seccomp to fall prey
+to time-of-check-time-of-use (TOCTOU) attacks that are common in system
+call interposition frameworks.  BPF programs may not dereference
+pointers which constrains all filters to solely evaluating the system
+call arguments directly.
+
+What it isn't
+-------------
+
+System call filtering isn't a sandbox.  It provides a clearly defined
+mechanism for minimizing the exposed kernel surface.  It is meant to be
+a tool for sandbox developers to use.  Beyond that, policy for logical
+behavior and information flow should be managed with a combination of
+other system hardening techniques and, potentially, an LSM of your
+choosing.  Expressive, dynamic filters provide further options down this
+path (avoiding pathological sizes or selecting which of the multiplexed
+system calls in socketcall() is allowed, for instance) which could be
+construed, incorrectly, as a more complete sandboxing solution.
+
+Usage
+-----
+
+An additional seccomp mode is added and is enabled using the same
+prctl(2) call as the strict seccomp.  If the architecture has
+CONFIG_HAVE_ARCH_SECCOMP_FILTER, then filters may be added as below:
+
+PR_SET_SECCOMP:
+	Now takes an additional argument which specifies a new filter
+	using a BPF program.
+	The BPF program will be executed over struct seccomp_data
+	reflecting the system call number, arguments, and other
+	metadata.  The BPF program must then return one of the
+	acceptable values to inform the kernel which action should be
+	taken.
+
+	Usage:
+		prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog);
+
+	The 'prog' argument is a pointer to a struct sock_fprog which
+	will contain the filter program.  If the program is invalid, the
+	call will return -1 and set errno to EINVAL.
+
+	If fork/clone and execve are allowed by @prog, any child
+	processes will be constrained to the same filters and system
+	call ABI as the parent.
+
+	Prior to use, the task must call prctl(PR_SET_NO_NEW_PRIVS, 1) or
+	run with CAP_SYS_ADMIN privileges in its namespace.  If these are not
+	true, -EACCES will be returned.  This requirement ensures that filter
+	programs cannot be applied to child processes with greater privileges
+	than the task that installed them.
+
+	Additionally, if prctl(2) is allowed by the attached filter,
+	additional filters may be layered on which will increase evaluation
+	time, but allow for further decreasing the attack surface during
+	execution of a process.
+
+The above call returns 0 on success and non-zero on error.
+
+Return values
+-------------
+A seccomp filter may return any of the following values. If multiple
+filters exist, the return value for the evaluation of a given system
+call will always use the highest precedent value. (For example,
+SECCOMP_RET_KILL will always take precedence.)
+
+In precedence order, they are:
+
+SECCOMP_RET_KILL:
+	Results in the task exiting immediately without executing the
+	system call.  The exit status of the task (status & 0x7f) will
+	be SIGSYS, not SIGKILL.
+
+SECCOMP_RET_TRAP:
+	Results in the kernel sending a SIGSYS signal to the triggering
+	task without executing the system call.  The kernel will
+	rollback the register state to just before the system call
+	entry such that a signal handler in the task will be able to
+	inspect the ucontext_t->uc_mcontext registers and emulate
+	system call success or failure upon return from the signal
+	handler.
+
+	The SECCOMP_RET_DATA portion of the return value will be passed
+	as si_errno.
+
+	SIGSYS triggered by seccomp will have a si_code of SYS_SECCOMP.
+
+SECCOMP_RET_ERRNO:
+	Results in the lower 16-bits of the return value being passed
+	to userland as the errno without executing the system call.
+
+SECCOMP_RET_TRACE:
+	When returned, this value will cause the kernel to attempt to
+	notify a ptrace()-based tracer prior to executing the system
+	call.  If there is no tracer present, -ENOSYS is returned to
+	userland and the system call is not executed.
+
+	A tracer will be notified if it requests PTRACE_O_TRACESECCOMP
+	using ptrace(PTRACE_SETOPTIONS).  The tracer will be notified
+	of a PTRACE_EVENT_SECCOMP and the SECCOMP_RET_DATA portion of
+	the BPF program return value will be available to the tracer
+	via PTRACE_GETEVENTMSG.
+
+SECCOMP_RET_ALLOW:
+	Results in the system call being executed.
+
+If multiple filters exist, the return value for the evaluation of a
+given system call will always use the highest precedent value.
+
+Precedence is only determined using the SECCOMP_RET_ACTION mask.  When
+multiple filters return values of the same precedence, only the
+SECCOMP_RET_DATA from the most recently installed filter will be
+returned.
+
+Pitfalls
+--------
+
+The biggest pitfall to avoid during use is filtering on system call
+number without checking the architecture value.  Why?  On any
+architecture that supports multiple system call invocation conventions,
+the system call numbers may vary based on the specific invocation.  If
+the numbers in the different calling conventions overlap, then checks in
+the filters may be abused.  Always check the arch value!
+
+Example
+-------
+
+The samples/seccomp/ directory contains both an x86-specific example
+and a more generic example of a higher level macro interface for BPF
+program generation.
+
+
+
+Adding architecture support
+-----------------------
+
+See arch/Kconfig for the authoritative requirements.  In general, if an
+architecture supports both ptrace_event and seccomp, it will be able to
+support seccomp filter with minor fixup: SIGSYS support and seccomp return
+value checking.  Then it must just add CONFIG_HAVE_ARCH_SECCOMP_FILTER
+to its arch-specific Kconfig.
diff --git a/samples/Makefile b/samples/Makefile
index 2f75851..5ef08bb 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,4 +1,4 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)	+= kobject/ kprobes/ tracepoints/ trace_events/ \
-			   hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/
+			   hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/
diff --git a/samples/seccomp/Makefile b/samples/seccomp/Makefile
new file mode 100644
index 0000000..e8fe0f5
--- /dev/null
+++ b/samples/seccomp/Makefile
@@ -0,0 +1,38 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
+
+hostprogs-$(CONFIG_SECCOMP) := bpf-fancy dropper
+bpf-fancy-objs := bpf-fancy.o bpf-helper.o
+
+HOSTCFLAGS_bpf-fancy.o += -I$(objtree)/usr/include
+HOSTCFLAGS_bpf-fancy.o += -idirafter $(objtree)/include
+HOSTCFLAGS_bpf-helper.o += -I$(objtree)/usr/include
+HOSTCFLAGS_bpf-helper.o += -idirafter $(objtree)/include
+
+HOSTCFLAGS_dropper.o += -I$(objtree)/usr/include
+HOSTCFLAGS_dropper.o += -idirafter $(objtree)/include
+dropper-objs := dropper.o
+
+# bpf-direct.c is x86-only.
+ifeq ($(SRCARCH),x86)
+# List of programs to build
+hostprogs-$(CONFIG_SECCOMP) += bpf-direct
+bpf-direct-objs := bpf-direct.o
+endif
+
+HOSTCFLAGS_bpf-direct.o += -I$(objtree)/usr/include
+HOSTCFLAGS_bpf-direct.o += -idirafter $(objtree)/include
+
+# Try to match the kernel target.
+ifeq ($(CONFIG_64BIT),)
+HOSTCFLAGS_bpf-direct.o += -m32
+HOSTCFLAGS_dropper.o += -m32
+HOSTCFLAGS_bpf-helper.o += -m32
+HOSTCFLAGS_bpf-fancy.o += -m32
+HOSTLOADLIBES_bpf-direct += -m32
+HOSTLOADLIBES_bpf-fancy += -m32
+HOSTLOADLIBES_dropper += -m32
+endif
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
diff --git a/samples/seccomp/bpf-direct.c b/samples/seccomp/bpf-direct.c
new file mode 100644
index 0000000..f1567ad
--- /dev/null
+++ b/samples/seccomp/bpf-direct.c
@@ -0,0 +1,176 @@
+/*
+ * Seccomp filter example for x86 (32-bit and 64-bit) with BPF macros
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_SET_SECCOMP, 2, ...).
+ */
+#define __USE_GNU 1
+#define _GNU_SOURCE 1
+
+#include <linux/types.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+#include <linux/unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))
+#define syscall_nr (offsetof(struct seccomp_data, nr))
+
+#if defined(__i386__)
+#define REG_RESULT	REG_EAX
+#define REG_SYSCALL	REG_EAX
+#define REG_ARG0	REG_EBX
+#define REG_ARG1	REG_ECX
+#define REG_ARG2	REG_EDX
+#define REG_ARG3	REG_ESI
+#define REG_ARG4	REG_EDI
+#define REG_ARG5	REG_EBP
+#elif defined(__x86_64__)
+#define REG_RESULT	REG_RAX
+#define REG_SYSCALL	REG_RAX
+#define REG_ARG0	REG_RDI
+#define REG_ARG1	REG_RSI
+#define REG_ARG2	REG_RDX
+#define REG_ARG3	REG_R10
+#define REG_ARG4	REG_R8
+#define REG_ARG5	REG_R9
+#else
+#error Unsupported platform
+#endif
+
+#ifndef PR_SET_NO_NEW_PRIVS
+#define PR_SET_NO_NEW_PRIVS 36
+#endif
+
+#ifndef SYS_SECCOMP
+#define SYS_SECCOMP 1
+#endif
+
+static void emulator(int nr, siginfo_t *info, void *void_context)
+{
+	ucontext_t *ctx = (ucontext_t *)(void_context);
+	int syscall;
+	char *buf;
+	ssize_t bytes;
+	size_t len;
+	if (info->si_code != SYS_SECCOMP)
+		return;
+	if (!ctx)
+		return;
+	syscall = ctx->uc_mcontext.gregs[REG_SYSCALL];
+	buf = (char *) ctx->uc_mcontext.gregs[REG_ARG1];
+	len = (size_t) ctx->uc_mcontext.gregs[REG_ARG2];
+
+	if (syscall != __NR_write)
+		return;
+	if (ctx->uc_mcontext.gregs[REG_ARG0] != STDERR_FILENO)
+		return;
+	/* Redirect stderr messages to stdout. Doesn't handle EINTR, etc */
+	ctx->uc_mcontext.gregs[REG_RESULT] = -1;
+	if (write(STDOUT_FILENO, "[ERR] ", 6) > 0) {
+		bytes = write(STDOUT_FILENO, buf, len);
+		ctx->uc_mcontext.gregs[REG_RESULT] = bytes;
+	}
+	return;
+}
+
+static int install_emulator(void)
+{
+	struct sigaction act;
+	sigset_t mask;
+	memset(&act, 0, sizeof(act));
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGSYS);
+
+	act.sa_sigaction = &emulator;
+	act.sa_flags = SA_SIGINFO;
+	if (sigaction(SIGSYS, &act, NULL) < 0) {
+		perror("sigaction");
+		return -1;
+	}
+	if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
+		perror("sigprocmask");
+		return -1;
+	}
+	return 0;
+}
+
+static int install_filter(void)
+{
+	struct sock_filter filter[] = {
+		/* Grab the system call number */
+		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr),
+		/* Jump table for the allowed syscalls */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_rt_sigreturn, 0, 1),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+#ifdef __NR_sigreturn
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_sigreturn, 0, 1),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+#endif
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit_group, 0, 1),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit, 0, 1),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_read, 1, 0),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_write, 3, 2),
+
+		/* Check that read is only using stdin. */
+		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDIN_FILENO, 4, 0),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
+
+		/* Check that write is only using stdout */
+		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDOUT_FILENO, 1, 0),
+		/* Trap attempts to write to stderr */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDERR_FILENO, 1, 2),
+
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+		perror("prctl(NO_NEW_PRIVS)");
+		return 1;
+	}
+
+
+	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
+		perror("prctl");
+		return 1;
+	}
+	return 0;
+}
+
+#define payload(_c) (_c), sizeof((_c))
+int main(int argc, char **argv)
+{
+	char buf[4096];
+	ssize_t bytes = 0;
+	if (install_emulator())
+		return 1;
+	if (install_filter())
+		return 1;
+	syscall(__NR_write, STDOUT_FILENO,
+		payload("OHAI! WHAT IS YOUR NAME? "));
+	bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf));
+	syscall(__NR_write, STDOUT_FILENO, payload("HELLO, "));
+	syscall(__NR_write, STDOUT_FILENO, buf, bytes);
+	syscall(__NR_write, STDERR_FILENO,
+		payload("Error message going to STDERR\n"));
+	return 0;
+}
diff --git a/samples/seccomp/bpf-fancy.c b/samples/seccomp/bpf-fancy.c
new file mode 100644
index 0000000..bf1f6b5
--- /dev/null
+++ b/samples/seccomp/bpf-fancy.c
@@ -0,0 +1,102 @@
+/*
+ * Seccomp BPF example using a macro-based generator.
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_ATTACH_SECCOMP_FILTER).
+ */
+
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+#include <linux/unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+#include "bpf-helper.h"
+
+#ifndef PR_SET_NO_NEW_PRIVS
+#define PR_SET_NO_NEW_PRIVS 36
+#endif
+
+int main(int argc, char **argv)
+{
+	struct bpf_labels l;
+	static const char msg1[] = "Please type something: ";
+	static const char msg2[] = "You typed: ";
+	char buf[256];
+	struct sock_filter filter[] = {
+		/* TODO: LOAD_SYSCALL_NR(arch) and enforce an arch */
+		LOAD_SYSCALL_NR,
+		SYSCALL(__NR_exit, ALLOW),
+		SYSCALL(__NR_exit_group, ALLOW),
+		SYSCALL(__NR_write, JUMP(&l, write_fd)),
+		SYSCALL(__NR_read, JUMP(&l, read)),
+		DENY,  /* Don't passthrough into a label */
+
+		LABEL(&l, read),
+		ARG(0),
+		JNE(STDIN_FILENO, DENY),
+		ARG(1),
+		JNE((unsigned long)buf, DENY),
+		ARG(2),
+		JGE(sizeof(buf), DENY),
+		ALLOW,
+
+		LABEL(&l, write_fd),
+		ARG(0),
+		JEQ(STDOUT_FILENO, JUMP(&l, write_buf)),
+		JEQ(STDERR_FILENO, JUMP(&l, write_buf)),
+		DENY,
+
+		LABEL(&l, write_buf),
+		ARG(1),
+		JEQ((unsigned long)msg1, JUMP(&l, msg1_len)),
+		JEQ((unsigned long)msg2, JUMP(&l, msg2_len)),
+		JEQ((unsigned long)buf, JUMP(&l, buf_len)),
+		DENY,
+
+		LABEL(&l, msg1_len),
+		ARG(2),
+		JLT(sizeof(msg1), ALLOW),
+		DENY,
+
+		LABEL(&l, msg2_len),
+		ARG(2),
+		JLT(sizeof(msg2), ALLOW),
+		DENY,
+
+		LABEL(&l, buf_len),
+		ARG(2),
+		JLT(sizeof(buf), ALLOW),
+		DENY,
+	};
+	struct sock_fprog prog = {
+		.filter = filter,
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+	};
+	ssize_t bytes;
+	bpf_resolve_jumps(&l, filter, sizeof(filter)/sizeof(*filter));
+
+	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+		perror("prctl(NO_NEW_PRIVS)");
+		return 1;
+	}
+
+	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
+		perror("prctl(SECCOMP)");
+		return 1;
+	}
+	syscall(__NR_write, STDOUT_FILENO, msg1, strlen(msg1));
+	bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf)-1);
+	bytes = (bytes > 0 ? bytes : 0);
+	syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2));
+	syscall(__NR_write, STDERR_FILENO, buf, bytes);
+	/* Now get killed */
+	syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2)+2);
+	return 0;
+}
diff --git a/samples/seccomp/bpf-helper.c b/samples/seccomp/bpf-helper.c
new file mode 100644
index 0000000..579cfe3
--- /dev/null
+++ b/samples/seccomp/bpf-helper.c
@@ -0,0 +1,89 @@
+/*
+ * Seccomp BPF helper functions
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_ATTACH_SECCOMP_FILTER).
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "bpf-helper.h"
+
+int bpf_resolve_jumps(struct bpf_labels *labels,
+		      struct sock_filter *filter, size_t count)
+{
+	struct sock_filter *begin = filter;
+	__u8 insn = count - 1;
+
+	if (count < 1)
+		return -1;
+	/*
+	* Walk it once, backwards, to build the label table and do fixups.
+	* Since backward jumps are disallowed by BPF, this is easy.
+	*/
+	filter += insn;
+	for (; filter >= begin; --insn, --filter) {
+		if (filter->code != (BPF_JMP+BPF_JA))
+			continue;
+		switch ((filter->jt<<8)|filter->jf) {
+		case (JUMP_JT<<8)|JUMP_JF:
+			if (labels->labels[filter->k].location == 0xffffffff) {
+				fprintf(stderr, "Unresolved label: '%s'\n",
+					labels->labels[filter->k].label);
+				return 1;
+			}
+			filter->k = labels->labels[filter->k].location -
+				    (insn + 1);
+			filter->jt = 0;
+			filter->jf = 0;
+			continue;
+		case (LABEL_JT<<8)|LABEL_JF:
+			if (labels->labels[filter->k].location != 0xffffffff) {
+				fprintf(stderr, "Duplicate label use: '%s'\n",
+					labels->labels[filter->k].label);
+				return 1;
+			}
+			labels->labels[filter->k].location = insn;
+			filter->k = 0; /* fall through */
+			filter->jt = 0;
+			filter->jf = 0;
+			continue;
+		}
+	}
+	return 0;
+}
+
+/* Simple lookup table for labels. */
+__u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label)
+{
+	struct __bpf_label *begin = labels->labels, *end;
+	int id;
+	if (labels->count == 0) {
+		begin->label = label;
+		begin->location = 0xffffffff;
+		labels->count++;
+		return 0;
+	}
+	end = begin + labels->count;
+	for (id = 0; begin < end; ++begin, ++id) {
+		if (!strcmp(label, begin->label))
+			return id;
+	}
+	begin->label = label;
+	begin->location = 0xffffffff;
+	labels->count++;
+	return id;
+}
+
+void seccomp_bpf_print(struct sock_filter *filter, size_t count)
+{
+	struct sock_filter *end = filter + count;
+	for ( ; filter < end; ++filter)
+		printf("{ code=%u,jt=%u,jf=%u,k=%u },\n",
+			filter->code, filter->jt, filter->jf, filter->k);
+}
diff --git a/samples/seccomp/bpf-helper.h b/samples/seccomp/bpf-helper.h
new file mode 100644
index 0000000..643279d
--- /dev/null
+++ b/samples/seccomp/bpf-helper.h
@@ -0,0 +1,238 @@
+/*
+ * Example wrapper around BPF macros.
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_SET_SECCOMP, 2, ...).
+ *
+ * No guarantees are provided with respect to the correctness
+ * or functionality of this code.
+ */
+#ifndef __BPF_HELPER_H__
+#define __BPF_HELPER_H__
+
+#include <asm/bitsperlong.h>	/* for __BITS_PER_LONG */
+#include <endian.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>	/* for seccomp_data */
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <stddef.h>
+
+#define BPF_LABELS_MAX 256
+struct bpf_labels {
+	int count;
+	struct __bpf_label {
+		const char *label;
+		__u32 location;
+	} labels[BPF_LABELS_MAX];
+};
+
+int bpf_resolve_jumps(struct bpf_labels *labels,
+		      struct sock_filter *filter, size_t count);
+__u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label);
+void seccomp_bpf_print(struct sock_filter *filter, size_t count);
+
+#define JUMP_JT 0xff
+#define JUMP_JF 0xff
+#define LABEL_JT 0xfe
+#define LABEL_JF 0xfe
+
+#define ALLOW \
+	BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
+#define DENY \
+	BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
+#define JUMP(labels, label) \
+	BPF_JUMP(BPF_JMP+BPF_JA, FIND_LABEL((labels), (label)), \
+		 JUMP_JT, JUMP_JF)
+#define LABEL(labels, label) \
+	BPF_JUMP(BPF_JMP+BPF_JA, FIND_LABEL((labels), (label)), \
+		 LABEL_JT, LABEL_JF)
+#define SYSCALL(nr, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (nr), 0, 1), \
+	jt
+
+/* Lame, but just an example */
+#define FIND_LABEL(labels, label) seccomp_bpf_label((labels), #label)
+
+#define EXPAND(...) __VA_ARGS__
+/* Map all width-sensitive operations */
+#if __BITS_PER_LONG == 32
+
+#define JEQ(x, jt) JEQ32(x, EXPAND(jt))
+#define JNE(x, jt) JNE32(x, EXPAND(jt))
+#define JGT(x, jt) JGT32(x, EXPAND(jt))
+#define JLT(x, jt) JLT32(x, EXPAND(jt))
+#define JGE(x, jt) JGE32(x, EXPAND(jt))
+#define JLE(x, jt) JLE32(x, EXPAND(jt))
+#define JA(x, jt) JA32(x, EXPAND(jt))
+#define ARG(i) ARG_32(i)
+#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
+
+#elif __BITS_PER_LONG == 64
+
+/* Ensure that we load the logically correct offset. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define ENDIAN(_lo, _hi) _lo, _hi
+#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
+#define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define ENDIAN(_lo, _hi) _hi, _lo
+#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
+#define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
+#else
+#error "Unknown endianness"
+#endif
+
+union arg64 {
+	struct {
+		__u32 ENDIAN(lo32, hi32);
+	};
+	__u64 u64;
+};
+
+#define JEQ(x, jt) \
+	JEQ64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+#define JGT(x, jt) \
+	JGT64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+#define JGE(x, jt) \
+	JGE64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+#define JNE(x, jt) \
+	JNE64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+#define JLT(x, jt) \
+	JLT64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+#define JLE(x, jt) \
+	JLE64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+
+#define JA(x, jt) \
+	JA64(((union arg64){.u64 = (x)}).lo32, \
+	       ((union arg64){.u64 = (x)}).hi32, \
+	       EXPAND(jt))
+#define ARG(i) ARG_64(i)
+
+#else
+#error __BITS_PER_LONG value unusable.
+#endif
+
+/* Loads the arg into A */
+#define ARG_32(idx) \
+	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx))
+
+/* Loads hi into A and lo in X */
+#define ARG_64(idx) \
+	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx)), \
+	BPF_STMT(BPF_ST, 0), /* lo -> M[0] */ \
+	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, HI_ARG(idx)), \
+	BPF_STMT(BPF_ST, 1) /* hi -> M[1] */
+
+#define JEQ32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 0, 1), \
+	jt
+
+#define JNE32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 1, 0), \
+	jt
+
+/* Checks the lo, then swaps to check the hi. A=lo,X=hi */
+#define JEQ64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 0, 2), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JNE64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 5, 0), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 2, 0), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JA32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
+	jt
+
+#define JA64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (hi), 3, 0), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (lo), 0, 2), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JGE32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
+	jt
+
+#define JLT32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
+	jt
+
+/* Shortcut checking if hi > arg.hi. */
+#define JGE64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 0, 2), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JLT64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JGT32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
+	jt
+
+#define JLE32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
+	jt
+
+/* Check hi > args.hi first, then do the GE checking */
+#define JGT64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 0, 2), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JLE64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 6, 0), \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define LOAD_SYSCALL_NR \
+	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
+		 offsetof(struct seccomp_data, nr))
+
+#endif  /* __BPF_HELPER_H__ */
diff --git a/samples/seccomp/dropper.c b/samples/seccomp/dropper.c
new file mode 100644
index 0000000..c69c347
--- /dev/null
+++ b/samples/seccomp/dropper.c
@@ -0,0 +1,68 @@
+/*
+ * Naive system call dropper built on seccomp_filter.
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_SET_SECCOMP, 2, ...).
+ *
+ * When run, returns the specified errno for the specified
+ * system call number against the given architecture.
+ *
+ * Run this one as root as PR_SET_NO_NEW_PRIVS is not called.
+ */
+
+#include <errno.h>
+#include <linux/audit.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+#include <linux/unistd.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+static int install_filter(int nr, int arch, int error)
+{
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+			 (offsetof(struct seccomp_data, arch))),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, arch, 0, 3),
+		BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+			 (offsetof(struct seccomp_data, nr))),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, nr, 0, 1),
+		BPF_STMT(BPF_RET+BPF_K,
+			 SECCOMP_RET_ERRNO|(error & SECCOMP_RET_DATA)),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	if (prctl(PR_SET_SECCOMP, 2, &prog)) {
+		perror("prctl");
+		return 1;
+	}
+	return 0;
+}
+
+int main(int argc, char **argv)
+{
+	if (argc < 5) {
+		fprintf(stderr, "Usage:\n"
+			"dropper <syscall_nr> <arch> <errno> <prog> [<args>]\n"
+			"Hint:	AUDIT_ARCH_I386: 0x%X\n"
+			"	AUDIT_ARCH_X86_64: 0x%X\n"
+			"\n", AUDIT_ARCH_I386, AUDIT_ARCH_X86_64);
+		return 1;
+	}
+	if (install_filter(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0),
+			   strtol(argv[3], NULL, 0)))
+		return 1;
+	execv(argv[4], &argv[4]);
+	printf("Failed to execv\n");
+	return 255;
+}
-- 
1.7.5.4


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

* [kernel-hardening] [PATCH v17 15/15] Documentation: prctl/seccomp_filter
@ 2012-03-29 20:02   ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-29 20:02 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	indan, pmoore, akpm, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Will Drewry

Documents how system call filtering using Berkeley Packet
Filter programs works and how it may be used.
Includes an example for x86 and a semi-generic
example using a macro-based code generator.

v17: - remove @compat note and add Pitfalls section for arch checking
       (keescook@chromium.org)
     - rebase
v14...v16: - rebase/nochanges
v13: - rebase on to 88ebdda6159ffc15699f204c33feb3e431bf9bdc
v12: - comment on the ptrace_event use
     - update arch support comment
     - note the behavior of SECCOMP_RET_DATA when there are multiple filters
       (keescook@chromium.org)
     - lots of samples/ clean up incl 64-bit bpf-direct support
       (markus@chromium.org)
     - rebase to linux-next
v11: - overhaul return value language, updates (keescook@chromium.org)
     - comment on do_exit(SIGSYS)
v10: - update for SIGSYS
     - update for new seccomp_data layout
     - update for ptrace option use
v9: - updated bpf-direct.c for SIGILL
v8: - add PR_SET_NO_NEW_PRIVS to the samples.
v7: - updated for all the new stuff in v7: TRAP, TRACE
    - only talk about PR_SET_SECCOMP now
    - fixed bad JLE32 check (coreyb@linux.vnet.ibm.com)
    - adds dropper.c: a simple system call disabler
v6: - tweak the language to note the requirement of
      PR_SET_NO_NEW_PRIVS being called prior to use. (luto@mit.edu)
v5: - update sample to use system call arguments
    - adds a "fancy" example using a macro-based generator
    - cleaned up bpf in the sample
    - update docs to mention arguments
    - fix prctl value (eparis@redhat.com)
    - language cleanup (rdunlap@xenotime.net)
v4: - update for no_new_privs use
    - minor tweaks
v3: - call out BPF <-> Berkeley Packet Filter (rdunlap@xenotime.net)
    - document use of tentative always-unprivileged
    - guard sample compilation for i386 and x86_64
v2: - move code to samples (corbet@lwn.net)

Signed-off-by: Will Drewry <wad@chromium.org>
---
 Documentation/prctl/seccomp_filter.txt |  163 ++++++++++++++++++++++
 samples/Makefile                       |    2 +-
 samples/seccomp/Makefile               |   38 +++++
 samples/seccomp/bpf-direct.c           |  176 +++++++++++++++++++++++
 samples/seccomp/bpf-fancy.c            |  102 ++++++++++++++
 samples/seccomp/bpf-helper.c           |   89 ++++++++++++
 samples/seccomp/bpf-helper.h           |  238 ++++++++++++++++++++++++++++++++
 samples/seccomp/dropper.c              |   68 +++++++++
 8 files changed, 875 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/prctl/seccomp_filter.txt
 create mode 100644 samples/seccomp/Makefile
 create mode 100644 samples/seccomp/bpf-direct.c
 create mode 100644 samples/seccomp/bpf-fancy.c
 create mode 100644 samples/seccomp/bpf-helper.c
 create mode 100644 samples/seccomp/bpf-helper.h
 create mode 100644 samples/seccomp/dropper.c

diff --git a/Documentation/prctl/seccomp_filter.txt b/Documentation/prctl/seccomp_filter.txt
new file mode 100644
index 0000000..597c3c5
--- /dev/null
+++ b/Documentation/prctl/seccomp_filter.txt
@@ -0,0 +1,163 @@
+		SECure COMPuting with filters
+		=============================
+
+Introduction
+------------
+
+A large number of system calls are exposed to every userland process
+with many of them going unused for the entire lifetime of the process.
+As system calls change and mature, bugs are found and eradicated.  A
+certain subset of userland applications benefit by having a reduced set
+of available system calls.  The resulting set reduces the total kernel
+surface exposed to the application.  System call filtering is meant for
+use with those applications.
+
+Seccomp filtering provides a means for a process to specify a filter for
+incoming system calls.  The filter is expressed as a Berkeley Packet
+Filter (BPF) program, as with socket filters, except that the data
+operated on is related to the system call being made: system call
+number and the system call arguments.  This allows for expressive
+filtering of system calls using a filter program language with a long
+history of being exposed to userland and a straightforward data set.
+
+Additionally, BPF makes it impossible for users of seccomp to fall prey
+to time-of-check-time-of-use (TOCTOU) attacks that are common in system
+call interposition frameworks.  BPF programs may not dereference
+pointers which constrains all filters to solely evaluating the system
+call arguments directly.
+
+What it isn't
+-------------
+
+System call filtering isn't a sandbox.  It provides a clearly defined
+mechanism for minimizing the exposed kernel surface.  It is meant to be
+a tool for sandbox developers to use.  Beyond that, policy for logical
+behavior and information flow should be managed with a combination of
+other system hardening techniques and, potentially, an LSM of your
+choosing.  Expressive, dynamic filters provide further options down this
+path (avoiding pathological sizes or selecting which of the multiplexed
+system calls in socketcall() is allowed, for instance) which could be
+construed, incorrectly, as a more complete sandboxing solution.
+
+Usage
+-----
+
+An additional seccomp mode is added and is enabled using the same
+prctl(2) call as the strict seccomp.  If the architecture has
+CONFIG_HAVE_ARCH_SECCOMP_FILTER, then filters may be added as below:
+
+PR_SET_SECCOMP:
+	Now takes an additional argument which specifies a new filter
+	using a BPF program.
+	The BPF program will be executed over struct seccomp_data
+	reflecting the system call number, arguments, and other
+	metadata.  The BPF program must then return one of the
+	acceptable values to inform the kernel which action should be
+	taken.
+
+	Usage:
+		prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog);
+
+	The 'prog' argument is a pointer to a struct sock_fprog which
+	will contain the filter program.  If the program is invalid, the
+	call will return -1 and set errno to EINVAL.
+
+	If fork/clone and execve are allowed by @prog, any child
+	processes will be constrained to the same filters and system
+	call ABI as the parent.
+
+	Prior to use, the task must call prctl(PR_SET_NO_NEW_PRIVS, 1) or
+	run with CAP_SYS_ADMIN privileges in its namespace.  If these are not
+	true, -EACCES will be returned.  This requirement ensures that filter
+	programs cannot be applied to child processes with greater privileges
+	than the task that installed them.
+
+	Additionally, if prctl(2) is allowed by the attached filter,
+	additional filters may be layered on which will increase evaluation
+	time, but allow for further decreasing the attack surface during
+	execution of a process.
+
+The above call returns 0 on success and non-zero on error.
+
+Return values
+-------------
+A seccomp filter may return any of the following values. If multiple
+filters exist, the return value for the evaluation of a given system
+call will always use the highest precedent value. (For example,
+SECCOMP_RET_KILL will always take precedence.)
+
+In precedence order, they are:
+
+SECCOMP_RET_KILL:
+	Results in the task exiting immediately without executing the
+	system call.  The exit status of the task (status & 0x7f) will
+	be SIGSYS, not SIGKILL.
+
+SECCOMP_RET_TRAP:
+	Results in the kernel sending a SIGSYS signal to the triggering
+	task without executing the system call.  The kernel will
+	rollback the register state to just before the system call
+	entry such that a signal handler in the task will be able to
+	inspect the ucontext_t->uc_mcontext registers and emulate
+	system call success or failure upon return from the signal
+	handler.
+
+	The SECCOMP_RET_DATA portion of the return value will be passed
+	as si_errno.
+
+	SIGSYS triggered by seccomp will have a si_code of SYS_SECCOMP.
+
+SECCOMP_RET_ERRNO:
+	Results in the lower 16-bits of the return value being passed
+	to userland as the errno without executing the system call.
+
+SECCOMP_RET_TRACE:
+	When returned, this value will cause the kernel to attempt to
+	notify a ptrace()-based tracer prior to executing the system
+	call.  If there is no tracer present, -ENOSYS is returned to
+	userland and the system call is not executed.
+
+	A tracer will be notified if it requests PTRACE_O_TRACESECCOMP
+	using ptrace(PTRACE_SETOPTIONS).  The tracer will be notified
+	of a PTRACE_EVENT_SECCOMP and the SECCOMP_RET_DATA portion of
+	the BPF program return value will be available to the tracer
+	via PTRACE_GETEVENTMSG.
+
+SECCOMP_RET_ALLOW:
+	Results in the system call being executed.
+
+If multiple filters exist, the return value for the evaluation of a
+given system call will always use the highest precedent value.
+
+Precedence is only determined using the SECCOMP_RET_ACTION mask.  When
+multiple filters return values of the same precedence, only the
+SECCOMP_RET_DATA from the most recently installed filter will be
+returned.
+
+Pitfalls
+--------
+
+The biggest pitfall to avoid during use is filtering on system call
+number without checking the architecture value.  Why?  On any
+architecture that supports multiple system call invocation conventions,
+the system call numbers may vary based on the specific invocation.  If
+the numbers in the different calling conventions overlap, then checks in
+the filters may be abused.  Always check the arch value!
+
+Example
+-------
+
+The samples/seccomp/ directory contains both an x86-specific example
+and a more generic example of a higher level macro interface for BPF
+program generation.
+
+
+
+Adding architecture support
+-----------------------
+
+See arch/Kconfig for the authoritative requirements.  In general, if an
+architecture supports both ptrace_event and seccomp, it will be able to
+support seccomp filter with minor fixup: SIGSYS support and seccomp return
+value checking.  Then it must just add CONFIG_HAVE_ARCH_SECCOMP_FILTER
+to its arch-specific Kconfig.
diff --git a/samples/Makefile b/samples/Makefile
index 2f75851..5ef08bb 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,4 +1,4 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)	+= kobject/ kprobes/ tracepoints/ trace_events/ \
-			   hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/
+			   hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/
diff --git a/samples/seccomp/Makefile b/samples/seccomp/Makefile
new file mode 100644
index 0000000..e8fe0f5
--- /dev/null
+++ b/samples/seccomp/Makefile
@@ -0,0 +1,38 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
+
+hostprogs-$(CONFIG_SECCOMP) := bpf-fancy dropper
+bpf-fancy-objs := bpf-fancy.o bpf-helper.o
+
+HOSTCFLAGS_bpf-fancy.o += -I$(objtree)/usr/include
+HOSTCFLAGS_bpf-fancy.o += -idirafter $(objtree)/include
+HOSTCFLAGS_bpf-helper.o += -I$(objtree)/usr/include
+HOSTCFLAGS_bpf-helper.o += -idirafter $(objtree)/include
+
+HOSTCFLAGS_dropper.o += -I$(objtree)/usr/include
+HOSTCFLAGS_dropper.o += -idirafter $(objtree)/include
+dropper-objs := dropper.o
+
+# bpf-direct.c is x86-only.
+ifeq ($(SRCARCH),x86)
+# List of programs to build
+hostprogs-$(CONFIG_SECCOMP) += bpf-direct
+bpf-direct-objs := bpf-direct.o
+endif
+
+HOSTCFLAGS_bpf-direct.o += -I$(objtree)/usr/include
+HOSTCFLAGS_bpf-direct.o += -idirafter $(objtree)/include
+
+# Try to match the kernel target.
+ifeq ($(CONFIG_64BIT),)
+HOSTCFLAGS_bpf-direct.o += -m32
+HOSTCFLAGS_dropper.o += -m32
+HOSTCFLAGS_bpf-helper.o += -m32
+HOSTCFLAGS_bpf-fancy.o += -m32
+HOSTLOADLIBES_bpf-direct += -m32
+HOSTLOADLIBES_bpf-fancy += -m32
+HOSTLOADLIBES_dropper += -m32
+endif
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
diff --git a/samples/seccomp/bpf-direct.c b/samples/seccomp/bpf-direct.c
new file mode 100644
index 0000000..f1567ad
--- /dev/null
+++ b/samples/seccomp/bpf-direct.c
@@ -0,0 +1,176 @@
+/*
+ * Seccomp filter example for x86 (32-bit and 64-bit) with BPF macros
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_SET_SECCOMP, 2, ...).
+ */
+#define __USE_GNU 1
+#define _GNU_SOURCE 1
+
+#include <linux/types.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+#include <linux/unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))
+#define syscall_nr (offsetof(struct seccomp_data, nr))
+
+#if defined(__i386__)
+#define REG_RESULT	REG_EAX
+#define REG_SYSCALL	REG_EAX
+#define REG_ARG0	REG_EBX
+#define REG_ARG1	REG_ECX
+#define REG_ARG2	REG_EDX
+#define REG_ARG3	REG_ESI
+#define REG_ARG4	REG_EDI
+#define REG_ARG5	REG_EBP
+#elif defined(__x86_64__)
+#define REG_RESULT	REG_RAX
+#define REG_SYSCALL	REG_RAX
+#define REG_ARG0	REG_RDI
+#define REG_ARG1	REG_RSI
+#define REG_ARG2	REG_RDX
+#define REG_ARG3	REG_R10
+#define REG_ARG4	REG_R8
+#define REG_ARG5	REG_R9
+#else
+#error Unsupported platform
+#endif
+
+#ifndef PR_SET_NO_NEW_PRIVS
+#define PR_SET_NO_NEW_PRIVS 36
+#endif
+
+#ifndef SYS_SECCOMP
+#define SYS_SECCOMP 1
+#endif
+
+static void emulator(int nr, siginfo_t *info, void *void_context)
+{
+	ucontext_t *ctx = (ucontext_t *)(void_context);
+	int syscall;
+	char *buf;
+	ssize_t bytes;
+	size_t len;
+	if (info->si_code != SYS_SECCOMP)
+		return;
+	if (!ctx)
+		return;
+	syscall = ctx->uc_mcontext.gregs[REG_SYSCALL];
+	buf = (char *) ctx->uc_mcontext.gregs[REG_ARG1];
+	len = (size_t) ctx->uc_mcontext.gregs[REG_ARG2];
+
+	if (syscall != __NR_write)
+		return;
+	if (ctx->uc_mcontext.gregs[REG_ARG0] != STDERR_FILENO)
+		return;
+	/* Redirect stderr messages to stdout. Doesn't handle EINTR, etc */
+	ctx->uc_mcontext.gregs[REG_RESULT] = -1;
+	if (write(STDOUT_FILENO, "[ERR] ", 6) > 0) {
+		bytes = write(STDOUT_FILENO, buf, len);
+		ctx->uc_mcontext.gregs[REG_RESULT] = bytes;
+	}
+	return;
+}
+
+static int install_emulator(void)
+{
+	struct sigaction act;
+	sigset_t mask;
+	memset(&act, 0, sizeof(act));
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGSYS);
+
+	act.sa_sigaction = &emulator;
+	act.sa_flags = SA_SIGINFO;
+	if (sigaction(SIGSYS, &act, NULL) < 0) {
+		perror("sigaction");
+		return -1;
+	}
+	if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
+		perror("sigprocmask");
+		return -1;
+	}
+	return 0;
+}
+
+static int install_filter(void)
+{
+	struct sock_filter filter[] = {
+		/* Grab the system call number */
+		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr),
+		/* Jump table for the allowed syscalls */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_rt_sigreturn, 0, 1),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+#ifdef __NR_sigreturn
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_sigreturn, 0, 1),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+#endif
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit_group, 0, 1),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit, 0, 1),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_read, 1, 0),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_write, 3, 2),
+
+		/* Check that read is only using stdin. */
+		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDIN_FILENO, 4, 0),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
+
+		/* Check that write is only using stdout */
+		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDOUT_FILENO, 1, 0),
+		/* Trap attempts to write to stderr */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDERR_FILENO, 1, 2),
+
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+		perror("prctl(NO_NEW_PRIVS)");
+		return 1;
+	}
+
+
+	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
+		perror("prctl");
+		return 1;
+	}
+	return 0;
+}
+
+#define payload(_c) (_c), sizeof((_c))
+int main(int argc, char **argv)
+{
+	char buf[4096];
+	ssize_t bytes = 0;
+	if (install_emulator())
+		return 1;
+	if (install_filter())
+		return 1;
+	syscall(__NR_write, STDOUT_FILENO,
+		payload("OHAI! WHAT IS YOUR NAME? "));
+	bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf));
+	syscall(__NR_write, STDOUT_FILENO, payload("HELLO, "));
+	syscall(__NR_write, STDOUT_FILENO, buf, bytes);
+	syscall(__NR_write, STDERR_FILENO,
+		payload("Error message going to STDERR\n"));
+	return 0;
+}
diff --git a/samples/seccomp/bpf-fancy.c b/samples/seccomp/bpf-fancy.c
new file mode 100644
index 0000000..bf1f6b5
--- /dev/null
+++ b/samples/seccomp/bpf-fancy.c
@@ -0,0 +1,102 @@
+/*
+ * Seccomp BPF example using a macro-based generator.
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_ATTACH_SECCOMP_FILTER).
+ */
+
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+#include <linux/unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+#include "bpf-helper.h"
+
+#ifndef PR_SET_NO_NEW_PRIVS
+#define PR_SET_NO_NEW_PRIVS 36
+#endif
+
+int main(int argc, char **argv)
+{
+	struct bpf_labels l;
+	static const char msg1[] = "Please type something: ";
+	static const char msg2[] = "You typed: ";
+	char buf[256];
+	struct sock_filter filter[] = {
+		/* TODO: LOAD_SYSCALL_NR(arch) and enforce an arch */
+		LOAD_SYSCALL_NR,
+		SYSCALL(__NR_exit, ALLOW),
+		SYSCALL(__NR_exit_group, ALLOW),
+		SYSCALL(__NR_write, JUMP(&l, write_fd)),
+		SYSCALL(__NR_read, JUMP(&l, read)),
+		DENY,  /* Don't passthrough into a label */
+
+		LABEL(&l, read),
+		ARG(0),
+		JNE(STDIN_FILENO, DENY),
+		ARG(1),
+		JNE((unsigned long)buf, DENY),
+		ARG(2),
+		JGE(sizeof(buf), DENY),
+		ALLOW,
+
+		LABEL(&l, write_fd),
+		ARG(0),
+		JEQ(STDOUT_FILENO, JUMP(&l, write_buf)),
+		JEQ(STDERR_FILENO, JUMP(&l, write_buf)),
+		DENY,
+
+		LABEL(&l, write_buf),
+		ARG(1),
+		JEQ((unsigned long)msg1, JUMP(&l, msg1_len)),
+		JEQ((unsigned long)msg2, JUMP(&l, msg2_len)),
+		JEQ((unsigned long)buf, JUMP(&l, buf_len)),
+		DENY,
+
+		LABEL(&l, msg1_len),
+		ARG(2),
+		JLT(sizeof(msg1), ALLOW),
+		DENY,
+
+		LABEL(&l, msg2_len),
+		ARG(2),
+		JLT(sizeof(msg2), ALLOW),
+		DENY,
+
+		LABEL(&l, buf_len),
+		ARG(2),
+		JLT(sizeof(buf), ALLOW),
+		DENY,
+	};
+	struct sock_fprog prog = {
+		.filter = filter,
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+	};
+	ssize_t bytes;
+	bpf_resolve_jumps(&l, filter, sizeof(filter)/sizeof(*filter));
+
+	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+		perror("prctl(NO_NEW_PRIVS)");
+		return 1;
+	}
+
+	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
+		perror("prctl(SECCOMP)");
+		return 1;
+	}
+	syscall(__NR_write, STDOUT_FILENO, msg1, strlen(msg1));
+	bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf)-1);
+	bytes = (bytes > 0 ? bytes : 0);
+	syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2));
+	syscall(__NR_write, STDERR_FILENO, buf, bytes);
+	/* Now get killed */
+	syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2)+2);
+	return 0;
+}
diff --git a/samples/seccomp/bpf-helper.c b/samples/seccomp/bpf-helper.c
new file mode 100644
index 0000000..579cfe3
--- /dev/null
+++ b/samples/seccomp/bpf-helper.c
@@ -0,0 +1,89 @@
+/*
+ * Seccomp BPF helper functions
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_ATTACH_SECCOMP_FILTER).
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "bpf-helper.h"
+
+int bpf_resolve_jumps(struct bpf_labels *labels,
+		      struct sock_filter *filter, size_t count)
+{
+	struct sock_filter *begin = filter;
+	__u8 insn = count - 1;
+
+	if (count < 1)
+		return -1;
+	/*
+	* Walk it once, backwards, to build the label table and do fixups.
+	* Since backward jumps are disallowed by BPF, this is easy.
+	*/
+	filter += insn;
+	for (; filter >= begin; --insn, --filter) {
+		if (filter->code != (BPF_JMP+BPF_JA))
+			continue;
+		switch ((filter->jt<<8)|filter->jf) {
+		case (JUMP_JT<<8)|JUMP_JF:
+			if (labels->labels[filter->k].location == 0xffffffff) {
+				fprintf(stderr, "Unresolved label: '%s'\n",
+					labels->labels[filter->k].label);
+				return 1;
+			}
+			filter->k = labels->labels[filter->k].location -
+				    (insn + 1);
+			filter->jt = 0;
+			filter->jf = 0;
+			continue;
+		case (LABEL_JT<<8)|LABEL_JF:
+			if (labels->labels[filter->k].location != 0xffffffff) {
+				fprintf(stderr, "Duplicate label use: '%s'\n",
+					labels->labels[filter->k].label);
+				return 1;
+			}
+			labels->labels[filter->k].location = insn;
+			filter->k = 0; /* fall through */
+			filter->jt = 0;
+			filter->jf = 0;
+			continue;
+		}
+	}
+	return 0;
+}
+
+/* Simple lookup table for labels. */
+__u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label)
+{
+	struct __bpf_label *begin = labels->labels, *end;
+	int id;
+	if (labels->count == 0) {
+		begin->label = label;
+		begin->location = 0xffffffff;
+		labels->count++;
+		return 0;
+	}
+	end = begin + labels->count;
+	for (id = 0; begin < end; ++begin, ++id) {
+		if (!strcmp(label, begin->label))
+			return id;
+	}
+	begin->label = label;
+	begin->location = 0xffffffff;
+	labels->count++;
+	return id;
+}
+
+void seccomp_bpf_print(struct sock_filter *filter, size_t count)
+{
+	struct sock_filter *end = filter + count;
+	for ( ; filter < end; ++filter)
+		printf("{ code=%u,jt=%u,jf=%u,k=%u },\n",
+			filter->code, filter->jt, filter->jf, filter->k);
+}
diff --git a/samples/seccomp/bpf-helper.h b/samples/seccomp/bpf-helper.h
new file mode 100644
index 0000000..643279d
--- /dev/null
+++ b/samples/seccomp/bpf-helper.h
@@ -0,0 +1,238 @@
+/*
+ * Example wrapper around BPF macros.
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_SET_SECCOMP, 2, ...).
+ *
+ * No guarantees are provided with respect to the correctness
+ * or functionality of this code.
+ */
+#ifndef __BPF_HELPER_H__
+#define __BPF_HELPER_H__
+
+#include <asm/bitsperlong.h>	/* for __BITS_PER_LONG */
+#include <endian.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>	/* for seccomp_data */
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <stddef.h>
+
+#define BPF_LABELS_MAX 256
+struct bpf_labels {
+	int count;
+	struct __bpf_label {
+		const char *label;
+		__u32 location;
+	} labels[BPF_LABELS_MAX];
+};
+
+int bpf_resolve_jumps(struct bpf_labels *labels,
+		      struct sock_filter *filter, size_t count);
+__u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label);
+void seccomp_bpf_print(struct sock_filter *filter, size_t count);
+
+#define JUMP_JT 0xff
+#define JUMP_JF 0xff
+#define LABEL_JT 0xfe
+#define LABEL_JF 0xfe
+
+#define ALLOW \
+	BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
+#define DENY \
+	BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
+#define JUMP(labels, label) \
+	BPF_JUMP(BPF_JMP+BPF_JA, FIND_LABEL((labels), (label)), \
+		 JUMP_JT, JUMP_JF)
+#define LABEL(labels, label) \
+	BPF_JUMP(BPF_JMP+BPF_JA, FIND_LABEL((labels), (label)), \
+		 LABEL_JT, LABEL_JF)
+#define SYSCALL(nr, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (nr), 0, 1), \
+	jt
+
+/* Lame, but just an example */
+#define FIND_LABEL(labels, label) seccomp_bpf_label((labels), #label)
+
+#define EXPAND(...) __VA_ARGS__
+/* Map all width-sensitive operations */
+#if __BITS_PER_LONG == 32
+
+#define JEQ(x, jt) JEQ32(x, EXPAND(jt))
+#define JNE(x, jt) JNE32(x, EXPAND(jt))
+#define JGT(x, jt) JGT32(x, EXPAND(jt))
+#define JLT(x, jt) JLT32(x, EXPAND(jt))
+#define JGE(x, jt) JGE32(x, EXPAND(jt))
+#define JLE(x, jt) JLE32(x, EXPAND(jt))
+#define JA(x, jt) JA32(x, EXPAND(jt))
+#define ARG(i) ARG_32(i)
+#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
+
+#elif __BITS_PER_LONG == 64
+
+/* Ensure that we load the logically correct offset. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define ENDIAN(_lo, _hi) _lo, _hi
+#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
+#define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define ENDIAN(_lo, _hi) _hi, _lo
+#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
+#define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
+#else
+#error "Unknown endianness"
+#endif
+
+union arg64 {
+	struct {
+		__u32 ENDIAN(lo32, hi32);
+	};
+	__u64 u64;
+};
+
+#define JEQ(x, jt) \
+	JEQ64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+#define JGT(x, jt) \
+	JGT64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+#define JGE(x, jt) \
+	JGE64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+#define JNE(x, jt) \
+	JNE64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+#define JLT(x, jt) \
+	JLT64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+#define JLE(x, jt) \
+	JLE64(((union arg64){.u64 = (x)}).lo32, \
+	      ((union arg64){.u64 = (x)}).hi32, \
+	      EXPAND(jt))
+
+#define JA(x, jt) \
+	JA64(((union arg64){.u64 = (x)}).lo32, \
+	       ((union arg64){.u64 = (x)}).hi32, \
+	       EXPAND(jt))
+#define ARG(i) ARG_64(i)
+
+#else
+#error __BITS_PER_LONG value unusable.
+#endif
+
+/* Loads the arg into A */
+#define ARG_32(idx) \
+	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx))
+
+/* Loads hi into A and lo in X */
+#define ARG_64(idx) \
+	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx)), \
+	BPF_STMT(BPF_ST, 0), /* lo -> M[0] */ \
+	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, HI_ARG(idx)), \
+	BPF_STMT(BPF_ST, 1) /* hi -> M[1] */
+
+#define JEQ32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 0, 1), \
+	jt
+
+#define JNE32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 1, 0), \
+	jt
+
+/* Checks the lo, then swaps to check the hi. A=lo,X=hi */
+#define JEQ64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 0, 2), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JNE64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 5, 0), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 2, 0), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JA32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
+	jt
+
+#define JA64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (hi), 3, 0), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (lo), 0, 2), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JGE32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
+	jt
+
+#define JLT32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
+	jt
+
+/* Shortcut checking if hi > arg.hi. */
+#define JGE64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 0, 2), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JLT64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JGT32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
+	jt
+
+#define JLE32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
+	jt
+
+/* Check hi > args.hi first, then do the GE checking */
+#define JGT64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 0, 2), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define JLE64(lo, hi, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 6, 0), \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+
+#define LOAD_SYSCALL_NR \
+	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
+		 offsetof(struct seccomp_data, nr))
+
+#endif  /* __BPF_HELPER_H__ */
diff --git a/samples/seccomp/dropper.c b/samples/seccomp/dropper.c
new file mode 100644
index 0000000..c69c347
--- /dev/null
+++ b/samples/seccomp/dropper.c
@@ -0,0 +1,68 @@
+/*
+ * Naive system call dropper built on seccomp_filter.
+ *
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
+ * Author: Will Drewry <wad@chromium.org>
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using prctl(PR_SET_SECCOMP, 2, ...).
+ *
+ * When run, returns the specified errno for the specified
+ * system call number against the given architecture.
+ *
+ * Run this one as root as PR_SET_NO_NEW_PRIVS is not called.
+ */
+
+#include <errno.h>
+#include <linux/audit.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+#include <linux/unistd.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+static int install_filter(int nr, int arch, int error)
+{
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+			 (offsetof(struct seccomp_data, arch))),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, arch, 0, 3),
+		BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+			 (offsetof(struct seccomp_data, nr))),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, nr, 0, 1),
+		BPF_STMT(BPF_RET+BPF_K,
+			 SECCOMP_RET_ERRNO|(error & SECCOMP_RET_DATA)),
+		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	if (prctl(PR_SET_SECCOMP, 2, &prog)) {
+		perror("prctl");
+		return 1;
+	}
+	return 0;
+}
+
+int main(int argc, char **argv)
+{
+	if (argc < 5) {
+		fprintf(stderr, "Usage:\n"
+			"dropper <syscall_nr> <arch> <errno> <prog> [<args>]\n"
+			"Hint:	AUDIT_ARCH_I386: 0x%X\n"
+			"	AUDIT_ARCH_X86_64: 0x%X\n"
+			"\n", AUDIT_ARCH_I386, AUDIT_ARCH_X86_64);
+		return 1;
+	}
+	if (install_filter(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0),
+			   strtol(argv[3], NULL, 0)))
+		return 1;
+	execv(argv[4], &argv[4]);
+	printf("Failed to execv\n");
+	return 255;
+}
-- 
1.7.5.4

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

* Re: [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering
  2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
@ 2012-03-29 23:11   ` James Morris
  -1 siblings, 0 replies; 146+ messages in thread
From: James Morris @ 2012-03-29 23:11 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, akpm, corbet, eric.dumazet, markus,
	coreyb, keescook

On Thu, 29 Mar 2012, Will Drewry wrote:

> Please see prior revisions for a detailed discussion of this patch
> series.
> 
> This series is a rebase on to:
>   b5174fa3a7f4f8f150bfa3b917c92608953dfa0f
> with very minor changes due to rebasing and tweaks noticed by a few
> initial users.  (I will rebase again for v3.4-rc1 when that time comes.)

I've offered to take this via my tree -- if anyone else wants to merge it 
via theirs instead, holler.

-- 
James Morris
<jmorris@namei.org>

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

* [kernel-hardening] Re: [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering
@ 2012-03-29 23:11   ` James Morris
  0 siblings, 0 replies; 146+ messages in thread
From: James Morris @ 2012-03-29 23:11 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, akpm, corbet, eric.dumazet, markus,
	coreyb, keescook

On Thu, 29 Mar 2012, Will Drewry wrote:

> Please see prior revisions for a detailed discussion of this patch
> series.
> 
> This series is a rebase on to:
>   b5174fa3a7f4f8f150bfa3b917c92608953dfa0f
> with very minor changes due to rebasing and tweaks noticed by a few
> initial users.  (I will rebase again for v3.4-rc1 when that time comes.)

I've offered to take this via my tree -- if anyone else wants to merge it 
via theirs instead, holler.

-- 
James Morris
<jmorris@namei.org>

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
@ 2012-03-31  4:40     ` Vladimir Murzin
  -1 siblings, 0 replies; 146+ messages in thread
From: Vladimir Murzin @ 2012-03-31  4:40 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, akpm, corbet, eric.dumazet, markus,
	coreyb, keescook, jmorris

Hi Will,

On Thu, Mar 29, 2012 at 03:01:53PM -0500, Will Drewry wrote:

snipped

> +
> +/* Limit any path through the tree to 256KB worth of instructions. */
> +#define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
> +
> +static void seccomp_filter_log_failure(int syscall)
> +{
> +	int compat = 0;
> +#ifdef CONFIG_COMPAT
> +	compat = is_compat_task();
> +#endif
> +	pr_info("%s[%d]: %ssystem call %d blocked at 0x%lx\n",
> +		current->comm, task_pid_nr(current),
> +		(compat ? "compat " : ""),
> +		syscall, KSTK_EIP(current));
> +}

snipped

> +/**
> + * seccomp_attach_user_filter - attaches a user-supplied sock_fprog
> + * @user_filter: pointer to the user data containing a sock_fprog.
> + *
> + * Returns 0 on success and non-zero otherwise.
> + */
> +long seccomp_attach_user_filter(char __user *user_filter)
> +{
> +	struct sock_fprog fprog;
> +	long ret = -EFAULT;
> +
> +#ifdef CONFIG_COMPAT
> +	if (is_compat_task()) {
> +		struct compat_sock_fprog fprog32;
> +		if (copy_from_user(&fprog32, user_filter, sizeof(fprog32)))
> +			goto out;
> +		fprog.len = fprog32.len;
> +		fprog.filter = compat_ptr(fprog32.filter);
> +	} else /* falls through to the if below. */
> +#endif
> +	if (copy_from_user(&fprog, user_filter, sizeof(fprog)))
> +		goto out;
> +	ret = seccomp_attach_filter(&fprog);
> +out:
> +	return ret;
> +}

Do we really need to surround is_compat_task() with CNFIG_COMPAT?
It seems that this case has already handled in compat.h [1]

[1] http://lxr.linux.no/#linux+v3.3/include/linux/compat.h#L566

Best wishes
Vladimir Murzin


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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-03-31  4:40     ` Vladimir Murzin
  0 siblings, 0 replies; 146+ messages in thread
From: Vladimir Murzin @ 2012-03-31  4:40 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, akpm, corbet, eric.dumazet, markus,
	coreyb, keescook, jmorris

Hi Will,

On Thu, Mar 29, 2012 at 03:01:53PM -0500, Will Drewry wrote:

snipped

> +
> +/* Limit any path through the tree to 256KB worth of instructions. */
> +#define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
> +
> +static void seccomp_filter_log_failure(int syscall)
> +{
> +	int compat = 0;
> +#ifdef CONFIG_COMPAT
> +	compat = is_compat_task();
> +#endif
> +	pr_info("%s[%d]: %ssystem call %d blocked at 0x%lx\n",
> +		current->comm, task_pid_nr(current),
> +		(compat ? "compat " : ""),
> +		syscall, KSTK_EIP(current));
> +}

snipped

> +/**
> + * seccomp_attach_user_filter - attaches a user-supplied sock_fprog
> + * @user_filter: pointer to the user data containing a sock_fprog.
> + *
> + * Returns 0 on success and non-zero otherwise.
> + */
> +long seccomp_attach_user_filter(char __user *user_filter)
> +{
> +	struct sock_fprog fprog;
> +	long ret = -EFAULT;
> +
> +#ifdef CONFIG_COMPAT
> +	if (is_compat_task()) {
> +		struct compat_sock_fprog fprog32;
> +		if (copy_from_user(&fprog32, user_filter, sizeof(fprog32)))
> +			goto out;
> +		fprog.len = fprog32.len;
> +		fprog.filter = compat_ptr(fprog32.filter);
> +	} else /* falls through to the if below. */
> +#endif
> +	if (copy_from_user(&fprog, user_filter, sizeof(fprog)))
> +		goto out;
> +	ret = seccomp_attach_filter(&fprog);
> +out:
> +	return ret;
> +}

Do we really need to surround is_compat_task() with CNFIG_COMPAT?
It seems that this case has already handled in compat.h [1]

[1] http://lxr.linux.no/#linux+v3.3/include/linux/compat.h#L566

Best wishes
Vladimir Murzin

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-03-31  4:40     ` [kernel-hardening] " Vladimir Murzin
@ 2012-03-31 18:14       ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-31 18:14 UTC (permalink / raw)
  To: Vladimir Murzin
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, akpm, corbet, eric.dumazet, markus,
	coreyb, keescook, jmorris

2012/3/30 Vladimir Murzin <murzin.v@gmail.com>:
> Hi Will,
>
> On Thu, Mar 29, 2012 at 03:01:53PM -0500, Will Drewry wrote:
>
> snipped
>
>> +
>> +/* Limit any path through the tree to 256KB worth of instructions. */
>> +#define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
>> +
>> +static void seccomp_filter_log_failure(int syscall)
>> +{
>> +     int compat = 0;
>> +#ifdef CONFIG_COMPAT
>> +     compat = is_compat_task();
>> +#endif
>> +     pr_info("%s[%d]: %ssystem call %d blocked at 0x%lx\n",
>> +             current->comm, task_pid_nr(current),
>> +             (compat ? "compat " : ""),
>> +             syscall, KSTK_EIP(current));
>> +}
>
> snipped
>
>> +/**
>> + * seccomp_attach_user_filter - attaches a user-supplied sock_fprog
>> + * @user_filter: pointer to the user data containing a sock_fprog.
>> + *
>> + * Returns 0 on success and non-zero otherwise.
>> + */
>> +long seccomp_attach_user_filter(char __user *user_filter)
>> +{
>> +     struct sock_fprog fprog;
>> +     long ret = -EFAULT;
>> +
>> +#ifdef CONFIG_COMPAT
>> +     if (is_compat_task()) {
>> +             struct compat_sock_fprog fprog32;
>> +             if (copy_from_user(&fprog32, user_filter, sizeof(fprog32)))
>> +                     goto out;
>> +             fprog.len = fprog32.len;
>> +             fprog.filter = compat_ptr(fprog32.filter);
>> +     } else /* falls through to the if below. */
>> +#endif
>> +     if (copy_from_user(&fprog, user_filter, sizeof(fprog)))
>> +             goto out;
>> +     ret = seccomp_attach_filter(&fprog);
>> +out:
>> +     return ret;
>> +}
>
> Do we really need to surround is_compat_task() with CNFIG_COMPAT?
> It seems that this case has already handled in compat.h [1]
>
> [1] http://lxr.linux.no/#linux+v3.3/include/linux/compat.h#L566

In log_failure, it's not needed at all, but that function disappears
in a subsequent patch in the series that converts over to using the
auditing framework.  For the next use of CONFIG_COMPAT, it is more
important for guarding the compat_sock_fprog struct (which isn't
doubly defined) rather than the is_compat_task.

Thanks!
will

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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-03-31 18:14       ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-03-31 18:14 UTC (permalink / raw)
  To: Vladimir Murzin
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, akpm, corbet, eric.dumazet, markus,
	coreyb, keescook, jmorris

2012/3/30 Vladimir Murzin <murzin.v@gmail.com>:
> Hi Will,
>
> On Thu, Mar 29, 2012 at 03:01:53PM -0500, Will Drewry wrote:
>
> snipped
>
>> +
>> +/* Limit any path through the tree to 256KB worth of instructions. */
>> +#define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
>> +
>> +static void seccomp_filter_log_failure(int syscall)
>> +{
>> +     int compat = 0;
>> +#ifdef CONFIG_COMPAT
>> +     compat = is_compat_task();
>> +#endif
>> +     pr_info("%s[%d]: %ssystem call %d blocked at 0x%lx\n",
>> +             current->comm, task_pid_nr(current),
>> +             (compat ? "compat " : ""),
>> +             syscall, KSTK_EIP(current));
>> +}
>
> snipped
>
>> +/**
>> + * seccomp_attach_user_filter - attaches a user-supplied sock_fprog
>> + * @user_filter: pointer to the user data containing a sock_fprog.
>> + *
>> + * Returns 0 on success and non-zero otherwise.
>> + */
>> +long seccomp_attach_user_filter(char __user *user_filter)
>> +{
>> +     struct sock_fprog fprog;
>> +     long ret = -EFAULT;
>> +
>> +#ifdef CONFIG_COMPAT
>> +     if (is_compat_task()) {
>> +             struct compat_sock_fprog fprog32;
>> +             if (copy_from_user(&fprog32, user_filter, sizeof(fprog32)))
>> +                     goto out;
>> +             fprog.len = fprog32.len;
>> +             fprog.filter = compat_ptr(fprog32.filter);
>> +     } else /* falls through to the if below. */
>> +#endif
>> +     if (copy_from_user(&fprog, user_filter, sizeof(fprog)))
>> +             goto out;
>> +     ret = seccomp_attach_filter(&fprog);
>> +out:
>> +     return ret;
>> +}
>
> Do we really need to surround is_compat_task() with CNFIG_COMPAT?
> It seems that this case has already handled in compat.h [1]
>
> [1] http://lxr.linux.no/#linux+v3.3/include/linux/compat.h#L566

In log_failure, it's not needed at all, but that function disappears
in a subsequent patch in the series that converts over to using the
auditing framework.  For the next use of CONFIG_COMPAT, it is more
important for guarding the compat_sock_fprog struct (which isn't
doubly defined) rather than the is_compat_task.

Thanks!
will

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
@ 2012-04-06 19:49     ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 19:49 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski

On Thu, 29 Mar 2012 15:01:46 -0500
Will Drewry <wad@chromium.org> wrote:

> From: Andy Lutomirski <luto@amacapital.net>
> 
> With this set, a lot of dangerous operations (chroot, unshare, etc)
> become a lot less dangerous because there is no possibility of
> subverting privileged binaries.
> 
> This patch completely breaks apparmor.  Someone who understands (and
> uses) apparmor should fix it or at least give me a hint.

So [patch 2/15] fixes all this up?

I guess we should join the two patches into one, to avoid a silly
breakage window.  That means that John loses a brownie point, but we
can mention him in the changelog, include his signed-off-by:

> Signed-off-by: Andy Lutomirski <luto@amacapital.net>

Several of these patches are missing your signed-off-by:.  They should
all have your SOB, because you sent them. 
Documentation/SubmittingPatches explains this.

I'm trying to find a way to merge all this code without reviewing it ;)
Alas, this is against my rules.  Given the length of time for which
this patchset has been floating around, I'm a little surprised by the
lack of acked-by's and reviewed-by's.  Have you been gathering them all
up?  Are the networking guys all happy about this patchset?



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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 19:49     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 19:49 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski

On Thu, 29 Mar 2012 15:01:46 -0500
Will Drewry <wad@chromium.org> wrote:

> From: Andy Lutomirski <luto@amacapital.net>
> 
> With this set, a lot of dangerous operations (chroot, unshare, etc)
> become a lot less dangerous because there is no possibility of
> subverting privileged binaries.
> 
> This patch completely breaks apparmor.  Someone who understands (and
> uses) apparmor should fix it or at least give me a hint.

So [patch 2/15] fixes all this up?

I guess we should join the two patches into one, to avoid a silly
breakage window.  That means that John loses a brownie point, but we
can mention him in the changelog, include his signed-off-by:

> Signed-off-by: Andy Lutomirski <luto@amacapital.net>

Several of these patches are missing your signed-off-by:.  They should
all have your SOB, because you sent them. 
Documentation/SubmittingPatches explains this.

I'm trying to find a way to merge all this code without reviewing it ;)
Alas, this is against my rules.  Given the length of time for which
this patchset has been floating around, I'm a little surprised by the
lack of acked-by's and reviewed-by's.  Have you been gathering them all
up?  Are the networking guys all happy about this patchset?

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 19:49     ` [kernel-hardening] " Andrew Morton
  (?)
@ 2012-04-06 19:55       ` Andy Lutomirski
  -1 siblings, 0 replies; 146+ messages in thread
From: Andy Lutomirski @ 2012-04-06 19:55 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook, jmorris

On Fri, Apr 6, 2012 at 12:49 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:46 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Andy Lutomirski <luto@amacapital.net>
>>
>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>> become a lot less dangerous because there is no possibility of
>> subverting privileged binaries.
>>
>> This patch completely breaks apparmor.  Someone who understands (and
>> uses) apparmor should fix it or at least give me a hint.
>
> So [patch 2/15] fixes all this up?
>
> I guess we should join the two patches into one, to avoid a silly
> breakage window.  That means that John loses a brownie point, but we
> can mention him in the changelog, include his signed-off-by:

Or just fix the commit message.  It no longer completely breaks
AppArmor.  It just causes execve to fail when PR_SET_NO_NEW_PRIVS is
set and AppArmor is in use.

--Andy

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 19:55       ` Andy Lutomirski
  0 siblings, 0 replies; 146+ messages in thread
From: Andy Lutomirski @ 2012-04-06 19:55 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook, jmorris

On Fri, Apr 6, 2012 at 12:49 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:46 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Andy Lutomirski <luto@amacapital.net>
>>
>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>> become a lot less dangerous because there is no possibility of
>> subverting privileged binaries.
>>
>> This patch completely breaks apparmor.  Someone who understands (and
>> uses) apparmor should fix it or at least give me a hint.
>
> So [patch 2/15] fixes all this up?
>
> I guess we should join the two patches into one, to avoid a silly
> breakage window.  That means that John loses a brownie point, but we
> can mention him in the changelog, include his signed-off-by:

Or just fix the commit message.  It no longer completely breaks
AppArmor.  It just causes execve to fail when PR_SET_NO_NEW_PRIVS is
set and AppArmor is in use.

--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 19:55       ` Andy Lutomirski
  0 siblings, 0 replies; 146+ messages in thread
From: Andy Lutomirski @ 2012-04-06 19:55 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook, jmorris

On Fri, Apr 6, 2012 at 12:49 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:46 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Andy Lutomirski <luto@amacapital.net>
>>
>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>> become a lot less dangerous because there is no possibility of
>> subverting privileged binaries.
>>
>> This patch completely breaks apparmor.  Someone who understands (and
>> uses) apparmor should fix it or at least give me a hint.
>
> So [patch 2/15] fixes all this up?
>
> I guess we should join the two patches into one, to avoid a silly
> breakage window.  That means that John loses a brownie point, but we
> can mention him in the changelog, include his signed-off-by:

Or just fix the commit message.  It no longer completely breaks
AppArmor.  It just causes execve to fail when PR_SET_NO_NEW_PRIVS is
set and AppArmor is in use.

--Andy

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 19:55     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 19:55 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski, linux-man

On Thu, 29 Mar 2012 15:01:46 -0500
Will Drewry <wad@chromium.org> wrote:

> From: Andy Lutomirski <luto@amacapital.net>
> 
> With this set, a lot of dangerous operations (chroot, unshare, etc)
> become a lot less dangerous because there is no possibility of
> subverting privileged binaries.

The changelog doesn't explain the semantics of the new syscall. 
There's a comment way-down-there which I guess suffices, if you hunt
for it.

And the changelog doesn't explain why this is being added.  Presumably
seccomp_filter wants/needs this feature but whowhatwherewhenwhy?  Spell
it all out, please.

The new syscall mode will be documented in the prctl manpage.  Please
cc linux-man@vger.kernel.org and work with Michael on getting this
done?

>
> ...
>

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 19:55     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 19:55 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	kernel-hardening-ZwoEplunGu1jrUoiu81ncdBPR1lH4CV8,
	netdev-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	arnd-r2nGTMty4D4, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	hpa-YMNOUZJC4hwAvxtiuMwx3w, mingo-H+wXaHxf7aLQT0dZR+AlfA,
	oleg-H+wXaHxf7aLQT0dZR+AlfA, peterz-wEGCiKHe2LqWVfeAwA7xHQ,
	rdunlap-/UHa2rfvQTnk1uMJSBkQmQ, mcgrathr-F7+t8E8rja9g9hUCZPvPmw,
	tglx-hfZtesqFncYOwBW4kG4KsQ, luto-3s7WtUTddSA,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	serge.hallyn-Z7WLFzj8eWMS+FvcfC7Uqw, djm-ilwOsaqNJrtAfugRpC6u6w,
	scarybeasts-Re5JQEeQqe8AvxtiuMwx3w, indan-1J6HnF7K7zE,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, corbet-T1hC0tSOHrs,
	eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
	markus-F7+t8E8rja9g9hUCZPvPmw,
	coreyb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	keescook-F7+t8E8rja9g9hUCZPvPmw, jmorris-gx6/JNMH7DfYtjvyW6yDsg,
	Andy Lutomirski, linux-man-u79uwXL29TY76Z2rM5mHXA

On Thu, 29 Mar 2012 15:01:46 -0500
Will Drewry <wad-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:

> From: Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>
> 
> With this set, a lot of dangerous operations (chroot, unshare, etc)
> become a lot less dangerous because there is no possibility of
> subverting privileged binaries.

The changelog doesn't explain the semantics of the new syscall. 
There's a comment way-down-there which I guess suffices, if you hunt
for it.

And the changelog doesn't explain why this is being added.  Presumably
seccomp_filter wants/needs this feature but whowhatwherewhenwhy?  Spell
it all out, please.

The new syscall mode will be documented in the prctl manpage.  Please
cc linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org and work with Michael on getting this
done?

>
> ...
>
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 19:55     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 19:55 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski, linux-man

On Thu, 29 Mar 2012 15:01:46 -0500
Will Drewry <wad@chromium.org> wrote:

> From: Andy Lutomirski <luto@amacapital.net>
> 
> With this set, a lot of dangerous operations (chroot, unshare, etc)
> become a lot less dangerous because there is no possibility of
> subverting privileged binaries.

The changelog doesn't explain the semantics of the new syscall. 
There's a comment way-down-there which I guess suffices, if you hunt
for it.

And the changelog doesn't explain why this is being added.  Presumably
seccomp_filter wants/needs this feature but whowhatwherewhenwhy?  Spell
it all out, please.

The new syscall mode will be documented in the prctl manpage.  Please
cc linux-man@vger.kernel.org and work with Michael on getting this
done?

>
> ...
>

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 19:55     ` Andrew Morton
@ 2012-04-06 20:01       ` Andrew Lutomirski
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Lutomirski @ 2012-04-06 20:01 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook, jmorris, Andy Lutomirski,
	linux-man

On Fri, Apr 6, 2012 at 12:55 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:46 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Andy Lutomirski <luto@amacapital.net>
>>
>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>> become a lot less dangerous because there is no possibility of
>> subverting privileged binaries.
>
> The changelog doesn't explain the semantics of the new syscall.
> There's a comment way-down-there which I guess suffices, if you hunt
> for it.
>
> And the changelog doesn't explain why this is being added.  Presumably
> seccomp_filter wants/needs this feature but whowhatwherewhenwhy?  Spell
> it all out, please.
>
> The new syscall mode will be documented in the prctl manpage.  Please
> cc linux-man@vger.kernel.org and work with Michael on getting this
> done?

This has been bugging me for awhile.  Is there any interest in moving
the manpages into the kernel source tree?  Then there could be a
general requirement that new APIs get documented when they're written.

(There are plenty of barely- or incompletely-documented syscalls.
futex and relatives come to mind.)

--Andy

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 20:01       ` Andrew Lutomirski
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Lutomirski @ 2012-04-06 20:01 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook, jmorris, Andy Lutomirski,
	linux-man

On Fri, Apr 6, 2012 at 12:55 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:46 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Andy Lutomirski <luto@amacapital.net>
>>
>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>> become a lot less dangerous because there is no possibility of
>> subverting privileged binaries.
>
> The changelog doesn't explain the semantics of the new syscall.
> There's a comment way-down-there which I guess suffices, if you hunt
> for it.
>
> And the changelog doesn't explain why this is being added.  Presumably
> seccomp_filter wants/needs this feature but whowhatwherewhenwhy?  Spell
> it all out, please.
>
> The new syscall mode will be documented in the prctl manpage.  Please
> cc linux-man@vger.kernel.org and work with Michael on getting this
> done?

This has been bugging me for awhile.  Is there any interest in moving
the manpages into the kernel source tree?  Then there could be a
general requirement that new APIs get documented when they're written.

(There are plenty of barely- or incompletely-documented syscalls.
futex and relatives come to mind.)

--Andy

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

* Re: [PATCH v17 07/15] asm/syscall.h: add syscall_get_arch
  2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
@ 2012-04-06 20:05     ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 20:05 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:01:52 -0500
Will Drewry <wad@chromium.org> wrote:

> Adds a stub for a function that will return the AUDIT_ARCH_*
> value appropriate to the supplied task based on the system
> call convention.
> 
> For audit's use, the value can generally be hard-coded at the
> audit-site.  However, for other functionality not inlined into
> syscall entry/exit, this makes that information available.
> seccomp_filter is the first planned consumer and, as such,
> the comment indicates a tie to HAVE_ARCH_SECCOMP_FILTER.  That

Should be "CONFIG_HAVE_ARCH_SECCOMP_FILTER", I hope.

> is probably an unneeded detail.
> 
> ...
>
> --- a/include/asm-generic/syscall.h
> +++ b/include/asm-generic/syscall.h
> @@ -142,4 +142,18 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
>  			   unsigned int i, unsigned int n,
>  			   const unsigned long *args);
>  
> +/**
> + * syscall_get_arch - return the AUDIT_ARCH for the current system call
> + * @task:	task of interest, must be in system call entry tracing
> + * @regs:	task_pt_regs() of @task
> + *
> + * Returns the AUDIT_ARCH_* based on the system call convention in use.
> + *
> + * It's only valid to call this when @task is stopped on entry to a system
> + * call, due to %TIF_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or %TIF_SECCOMP.
> + *
> + * Note, at present this function is only required with
> + * CONFIG_HAVE_ARCH_SECCOMP_FILTER.
> + */
> +int syscall_get_arch(struct task_struct *task, struct pt_regs *regs);
>  #endif	/* _ASM_SYSCALL_H */

So architectures which permit CONFIG_HAVE_ARCH_SECCOMP_FILTER must
provide an implementation of this.


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

* [kernel-hardening] Re: [PATCH v17 07/15] asm/syscall.h: add syscall_get_arch
@ 2012-04-06 20:05     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 20:05 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:01:52 -0500
Will Drewry <wad@chromium.org> wrote:

> Adds a stub for a function that will return the AUDIT_ARCH_*
> value appropriate to the supplied task based on the system
> call convention.
> 
> For audit's use, the value can generally be hard-coded at the
> audit-site.  However, for other functionality not inlined into
> syscall entry/exit, this makes that information available.
> seccomp_filter is the first planned consumer and, as such,
> the comment indicates a tie to HAVE_ARCH_SECCOMP_FILTER.  That

Should be "CONFIG_HAVE_ARCH_SECCOMP_FILTER", I hope.

> is probably an unneeded detail.
> 
> ...
>
> --- a/include/asm-generic/syscall.h
> +++ b/include/asm-generic/syscall.h
> @@ -142,4 +142,18 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
>  			   unsigned int i, unsigned int n,
>  			   const unsigned long *args);
>  
> +/**
> + * syscall_get_arch - return the AUDIT_ARCH for the current system call
> + * @task:	task of interest, must be in system call entry tracing
> + * @regs:	task_pt_regs() of @task
> + *
> + * Returns the AUDIT_ARCH_* based on the system call convention in use.
> + *
> + * It's only valid to call this when @task is stopped on entry to a system
> + * call, due to %TIF_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or %TIF_SECCOMP.
> + *
> + * Note, at present this function is only required with
> + * CONFIG_HAVE_ARCH_SECCOMP_FILTER.
> + */
> +int syscall_get_arch(struct task_struct *task, struct pt_regs *regs);
>  #endif	/* _ASM_SYSCALL_H */

So architectures which permit CONFIG_HAVE_ARCH_SECCOMP_FILTER must
provide an implementation of this.

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
@ 2012-04-06 20:23     ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 20:23 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:01:53 -0500
Will Drewry <wad@chromium.org> wrote:

> [This patch depends on luto@mit.edu's no_new_privs patch:
>    https://lkml.org/lkml/2012/1/30/264
>  included in this series for ease of consumption.
> ]
> 
> This patch adds support for seccomp mode 2.  Mode 2 introduces the
> ability for unprivileged processes to install system call filtering
> policy expressed in terms of a Berkeley Packet Filter (BPF) program.
> This program will be evaluated in the kernel for each system call
> the task makes and computes a result based on data in the format
> of struct seccomp_data.
> 
> A filter program may be installed by calling:
>   struct sock_fprog fprog = { ... };
>   ...
>   prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &fprog);
> 
> The return value of the filter program determines if the system call is
> allowed to proceed or denied.  If the first filter program installed
> allows prctl(2) calls, then the above call may be made repeatedly
> by a task to further reduce its access to the kernel.  All attached
> programs must be evaluated before a system call will be allowed to
> proceed.
> 
> Filter programs will be inherited across fork/clone and execve.
> However, if the task attaching the filter is unprivileged
> (!CAP_SYS_ADMIN) the no_new_privs bit will be set on the task.  This
> ensures that unprivileged tasks cannot attach filters that affect
> privileged tasks (e.g., setuid binary).
> 
> There are a number of benefits to this approach. A few of which are
> as follows:
> - BPF has been exposed to userland for a long time
> - BPF optimization (and JIT'ing) are well understood
> - Userland already knows its ABI: system call numbers and desired
>   arguments
> - No time-of-check-time-of-use vulnerable data accesses are possible.
> - system call arguments are loaded on access only to minimize copying
>   required for system call policy decisions.
> 
> Mode 2 support is restricted to architectures that enable
> HAVE_ARCH_SECCOMP_FILTER.  In this patch, the primary dependency is on
> syscall_get_arguments().  The full desired scope of this feature will
> add a few minor additional requirements expressed later in this series.
> Based on discussion, SECCOMP_RET_ERRNO and SECCOMP_RET_TRACE seem to be
> the desired additional functionality.
> 
> No architectures are enabled in this patch.
> 
>
> ...
>
> +/**
> + * struct seccomp_filter - container for seccomp BPF programs
> + *
> + * @usage: reference count to manage the object liftime.

i found a bug

> + *         get/put helpers should be used when accessing an instance
> + *         outside of a lifetime-guarded section.  In general, this
> + *         is only needed for handling filters shared across tasks.
> + * @prev: points to a previously installed, or inherited, filter
> + * @len: the number of instructions in the program
> + * @insns: the BPF program instructions to evaluate
> + *
> + * seccomp_filter objects are organized in a tree linked via the @prev
> + * pointer.  For any task, it appears to be a singly-linked list starting
> + * with current->seccomp.filter, the most recently attached or inherited filter.
> + * However, multiple filters may share a @prev node, by way of fork(), which
> + * results in a unidirectional tree existing in memory.  This is similar to
> + * how namespaces work.
> + *
> + * seccomp_filter objects should never be modified after being attached
> + * to a task_struct (other than @usage).
> + */
> +struct seccomp_filter {
> +	atomic_t usage;
> +	struct seccomp_filter *prev;
> +	unsigned short len;  /* Instruction count */
> +	struct sock_filter insns[];
> +};
> +
> +/* Limit any path through the tree to 256KB worth of instructions. */
> +#define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
> +
> +static void seccomp_filter_log_failure(int syscall)
> +{
> +	int compat = 0;
> +#ifdef CONFIG_COMPAT
> +	compat = is_compat_task();
> +#endif

hm, I'm surprised that we don't have a zero-returning implementation of
is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.

> +	pr_info("%s[%d]: %ssystem call %d blocked at 0x%lx\n",
> +		current->comm, task_pid_nr(current),
> +		(compat ? "compat " : ""),
> +		syscall, KSTK_EIP(current));
> +}
> +
> +/**
> + * get_u32 - returns a u32 offset into data
> + * @data: a unsigned 64 bit value
> + * @index: 0 or 1 to return the first or second 32-bits
> + *
> + * This inline exists to hide the length of unsigned long.
> + * If a 32-bit unsigned long is passed in, it will be extended
> + * and the top 32-bits will be 0. If it is a 64-bit unsigned
> + * long, then whatever data is resident will be properly returned.
> + */
> +static inline u32 get_u32(u64 data, int index)
> +{
> +	return ((u32 *)&data)[index];
> +}

This seems utterly broken on big-endian machines.  If so: fix.  If not:
add comment explaining why?

>
> ...
>
> +/**
> + *	seccomp_chk_filter - verify seccomp filter code
> + *	@filter: filter to verify
> + *	@flen: length of filter
> + *
> + * Takes a previously checked filter (by sk_chk_filter) and
> + * redirects all filter code that loads struct sk_buff data
> + * and related data through seccomp_bpf_load.  It also
> + * enforces length and alignment checking of those loads.
> + *
> + * Returns 0 if the rule set is legal or -EINVAL if not.
> + */
> +static int seccomp_chk_filter(struct sock_filter *filter, unsigned int flen)
> +{
> +	int pc;
> +	for (pc = 0; pc < flen; pc++) {
> +		struct sock_filter *ftest = &filter[pc];
> +		u16 code = ftest->code;
> +		u32 k = ftest->k;
> +		switch (code) {

It's conventional to have a blank line between end-of-locals and
start-of-code.


> +		case BPF_S_LD_W_ABS:
> +			ftest->code = BPF_S_ANC_SECCOMP_LD_W;
> +			/* 32-bit aligned and not out of bounds. */
> +			if (k >= sizeof(struct seccomp_data) || k & 3)
> +				return -EINVAL;
>
> ...
>
> +static u32 seccomp_run_filters(int syscall)
> +{
> +	struct seccomp_filter *f;
> +	u32 ret = SECCOMP_RET_KILL;
> +	/*
> +	 * All filters are evaluated in order of youngest to oldest. The lowest
> +	 * BPF return value always takes priority.
> +	 */

The youngest-first design surprised me.  It wasn't mentioned at all in
the changelog.  Thinking about it, I guess it just doesn't matter.  But
some description of the reasons for and implications of this decision
for the uninitiated would be welcome.

> +	for (f = current->seccomp.filter; f; f = f->prev) {
> +		ret = sk_run_filter(NULL, f->insns);
> +		if (ret != SECCOMP_RET_ALLOW)
> +			break;
> +	}
> +	return ret;
> +}
> +
> +/**
> + * seccomp_attach_filter: Attaches a seccomp filter to current.
> + * @fprog: BPF program to install
> + *
> + * Returns 0 on success or an errno on failure.
> + */
> +static long seccomp_attach_filter(struct sock_fprog *fprog)
> +{
> +	struct seccomp_filter *filter;
> +	unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
> +	unsigned long total_insns = fprog->len;
> +	long ret;
> +
> +	if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
> +		return -EINVAL;
> +
> +	for (filter = current->seccomp.filter; filter; filter = filter->prev)
> +		total_insns += filter->len + 4;  /* include a 4 instr penalty */

So tasks don't share filters?  We copy them by value at fork?  Do we do
this at vfork() too?

> +	if (total_insns > MAX_INSNS_PER_PATH)
> +		return -ENOMEM;
> +
> +	/*
> +	 * Installing a seccomp filter requires that the task have
> +	 * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
> +	 * This avoids scenarios where unprivileged tasks can affect the
> +	 * behavior of privileged children.
> +	 */
> +	if (!current->no_new_privs &&
> +	    security_capable_noaudit(current_cred(), current_user_ns(),
> +				     CAP_SYS_ADMIN) != 0)
> +		return -EACCES;
> +
> +	/* Allocate a new seccomp_filter */
> +	filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);

I think this gives userspace an easy way of causing page allocation
failure warnings, by permitting large kmalloc() attempts.  Add
__GFP_NOWARN?

> +	if (!filter)
> +		return -ENOMEM;
> +	atomic_set(&filter->usage, 1);
> +	filter->len = fprog->len;
> +
> +	/* Copy the instructions from fprog. */
> +	ret = -EFAULT;
> +	if (copy_from_user(filter->insns, fprog->filter, fp_size))
> +		goto fail;
> +
> +	/* Check and rewrite the fprog via the skb checker */
> +	ret = sk_chk_filter(filter->insns, filter->len);
> +	if (ret)
> +		goto fail;
> +
> +	/* Check and rewrite the fprog for seccomp use */
> +	ret = seccomp_chk_filter(filter->insns, filter->len);

"check" is spelled "check"!

> +	if (ret)
> +		goto fail;
> +
> +	/*
> +	 * If there is an existing filter, make it the prev and don't drop its
> +	 * task reference.
> +	 */
> +	filter->prev = current->seccomp.filter;
> +	current->seccomp.filter = filter;
> +	return 0;
> +fail:
> +	kfree(filter);
> +	return ret;
> +}
> +
>
> ...
>
> +/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
> +void put_seccomp_filter(struct task_struct *tsk)
> +{
> +	struct seccomp_filter *orig = tsk->seccomp.filter;
> +	/* Clean up single-reference branches iteratively. */
> +	while (orig && atomic_dec_and_test(&orig->usage)) {
> +		struct seccomp_filter *freeme = orig;
> +		orig = orig->prev;
> +		kfree(freeme);
> +	}
> +}

So if one of the filters in the list has an elevated refcount, we bail
out on the remainder of the list.  Seems odd.

> +#endif	/* CONFIG_SECCOMP_FILTER */
>
> ...
>


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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-06 20:23     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 20:23 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:01:53 -0500
Will Drewry <wad@chromium.org> wrote:

> [This patch depends on luto@mit.edu's no_new_privs patch:
>    https://lkml.org/lkml/2012/1/30/264
>  included in this series for ease of consumption.
> ]
> 
> This patch adds support for seccomp mode 2.  Mode 2 introduces the
> ability for unprivileged processes to install system call filtering
> policy expressed in terms of a Berkeley Packet Filter (BPF) program.
> This program will be evaluated in the kernel for each system call
> the task makes and computes a result based on data in the format
> of struct seccomp_data.
> 
> A filter program may be installed by calling:
>   struct sock_fprog fprog = { ... };
>   ...
>   prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &fprog);
> 
> The return value of the filter program determines if the system call is
> allowed to proceed or denied.  If the first filter program installed
> allows prctl(2) calls, then the above call may be made repeatedly
> by a task to further reduce its access to the kernel.  All attached
> programs must be evaluated before a system call will be allowed to
> proceed.
> 
> Filter programs will be inherited across fork/clone and execve.
> However, if the task attaching the filter is unprivileged
> (!CAP_SYS_ADMIN) the no_new_privs bit will be set on the task.  This
> ensures that unprivileged tasks cannot attach filters that affect
> privileged tasks (e.g., setuid binary).
> 
> There are a number of benefits to this approach. A few of which are
> as follows:
> - BPF has been exposed to userland for a long time
> - BPF optimization (and JIT'ing) are well understood
> - Userland already knows its ABI: system call numbers and desired
>   arguments
> - No time-of-check-time-of-use vulnerable data accesses are possible.
> - system call arguments are loaded on access only to minimize copying
>   required for system call policy decisions.
> 
> Mode 2 support is restricted to architectures that enable
> HAVE_ARCH_SECCOMP_FILTER.  In this patch, the primary dependency is on
> syscall_get_arguments().  The full desired scope of this feature will
> add a few minor additional requirements expressed later in this series.
> Based on discussion, SECCOMP_RET_ERRNO and SECCOMP_RET_TRACE seem to be
> the desired additional functionality.
> 
> No architectures are enabled in this patch.
> 
>
> ...
>
> +/**
> + * struct seccomp_filter - container for seccomp BPF programs
> + *
> + * @usage: reference count to manage the object liftime.

i found a bug

> + *         get/put helpers should be used when accessing an instance
> + *         outside of a lifetime-guarded section.  In general, this
> + *         is only needed for handling filters shared across tasks.
> + * @prev: points to a previously installed, or inherited, filter
> + * @len: the number of instructions in the program
> + * @insns: the BPF program instructions to evaluate
> + *
> + * seccomp_filter objects are organized in a tree linked via the @prev
> + * pointer.  For any task, it appears to be a singly-linked list starting
> + * with current->seccomp.filter, the most recently attached or inherited filter.
> + * However, multiple filters may share a @prev node, by way of fork(), which
> + * results in a unidirectional tree existing in memory.  This is similar to
> + * how namespaces work.
> + *
> + * seccomp_filter objects should never be modified after being attached
> + * to a task_struct (other than @usage).
> + */
> +struct seccomp_filter {
> +	atomic_t usage;
> +	struct seccomp_filter *prev;
> +	unsigned short len;  /* Instruction count */
> +	struct sock_filter insns[];
> +};
> +
> +/* Limit any path through the tree to 256KB worth of instructions. */
> +#define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
> +
> +static void seccomp_filter_log_failure(int syscall)
> +{
> +	int compat = 0;
> +#ifdef CONFIG_COMPAT
> +	compat = is_compat_task();
> +#endif

hm, I'm surprised that we don't have a zero-returning implementation of
is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.

> +	pr_info("%s[%d]: %ssystem call %d blocked at 0x%lx\n",
> +		current->comm, task_pid_nr(current),
> +		(compat ? "compat " : ""),
> +		syscall, KSTK_EIP(current));
> +}
> +
> +/**
> + * get_u32 - returns a u32 offset into data
> + * @data: a unsigned 64 bit value
> + * @index: 0 or 1 to return the first or second 32-bits
> + *
> + * This inline exists to hide the length of unsigned long.
> + * If a 32-bit unsigned long is passed in, it will be extended
> + * and the top 32-bits will be 0. If it is a 64-bit unsigned
> + * long, then whatever data is resident will be properly returned.
> + */
> +static inline u32 get_u32(u64 data, int index)
> +{
> +	return ((u32 *)&data)[index];
> +}

This seems utterly broken on big-endian machines.  If so: fix.  If not:
add comment explaining why?

>
> ...
>
> +/**
> + *	seccomp_chk_filter - verify seccomp filter code
> + *	@filter: filter to verify
> + *	@flen: length of filter
> + *
> + * Takes a previously checked filter (by sk_chk_filter) and
> + * redirects all filter code that loads struct sk_buff data
> + * and related data through seccomp_bpf_load.  It also
> + * enforces length and alignment checking of those loads.
> + *
> + * Returns 0 if the rule set is legal or -EINVAL if not.
> + */
> +static int seccomp_chk_filter(struct sock_filter *filter, unsigned int flen)
> +{
> +	int pc;
> +	for (pc = 0; pc < flen; pc++) {
> +		struct sock_filter *ftest = &filter[pc];
> +		u16 code = ftest->code;
> +		u32 k = ftest->k;
> +		switch (code) {

It's conventional to have a blank line between end-of-locals and
start-of-code.


> +		case BPF_S_LD_W_ABS:
> +			ftest->code = BPF_S_ANC_SECCOMP_LD_W;
> +			/* 32-bit aligned and not out of bounds. */
> +			if (k >= sizeof(struct seccomp_data) || k & 3)
> +				return -EINVAL;
>
> ...
>
> +static u32 seccomp_run_filters(int syscall)
> +{
> +	struct seccomp_filter *f;
> +	u32 ret = SECCOMP_RET_KILL;
> +	/*
> +	 * All filters are evaluated in order of youngest to oldest. The lowest
> +	 * BPF return value always takes priority.
> +	 */

The youngest-first design surprised me.  It wasn't mentioned at all in
the changelog.  Thinking about it, I guess it just doesn't matter.  But
some description of the reasons for and implications of this decision
for the uninitiated would be welcome.

> +	for (f = current->seccomp.filter; f; f = f->prev) {
> +		ret = sk_run_filter(NULL, f->insns);
> +		if (ret != SECCOMP_RET_ALLOW)
> +			break;
> +	}
> +	return ret;
> +}
> +
> +/**
> + * seccomp_attach_filter: Attaches a seccomp filter to current.
> + * @fprog: BPF program to install
> + *
> + * Returns 0 on success or an errno on failure.
> + */
> +static long seccomp_attach_filter(struct sock_fprog *fprog)
> +{
> +	struct seccomp_filter *filter;
> +	unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
> +	unsigned long total_insns = fprog->len;
> +	long ret;
> +
> +	if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
> +		return -EINVAL;
> +
> +	for (filter = current->seccomp.filter; filter; filter = filter->prev)
> +		total_insns += filter->len + 4;  /* include a 4 instr penalty */

So tasks don't share filters?  We copy them by value at fork?  Do we do
this at vfork() too?

> +	if (total_insns > MAX_INSNS_PER_PATH)
> +		return -ENOMEM;
> +
> +	/*
> +	 * Installing a seccomp filter requires that the task have
> +	 * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
> +	 * This avoids scenarios where unprivileged tasks can affect the
> +	 * behavior of privileged children.
> +	 */
> +	if (!current->no_new_privs &&
> +	    security_capable_noaudit(current_cred(), current_user_ns(),
> +				     CAP_SYS_ADMIN) != 0)
> +		return -EACCES;
> +
> +	/* Allocate a new seccomp_filter */
> +	filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);

I think this gives userspace an easy way of causing page allocation
failure warnings, by permitting large kmalloc() attempts.  Add
__GFP_NOWARN?

> +	if (!filter)
> +		return -ENOMEM;
> +	atomic_set(&filter->usage, 1);
> +	filter->len = fprog->len;
> +
> +	/* Copy the instructions from fprog. */
> +	ret = -EFAULT;
> +	if (copy_from_user(filter->insns, fprog->filter, fp_size))
> +		goto fail;
> +
> +	/* Check and rewrite the fprog via the skb checker */
> +	ret = sk_chk_filter(filter->insns, filter->len);
> +	if (ret)
> +		goto fail;
> +
> +	/* Check and rewrite the fprog for seccomp use */
> +	ret = seccomp_chk_filter(filter->insns, filter->len);

"check" is spelled "check"!

> +	if (ret)
> +		goto fail;
> +
> +	/*
> +	 * If there is an existing filter, make it the prev and don't drop its
> +	 * task reference.
> +	 */
> +	filter->prev = current->seccomp.filter;
> +	current->seccomp.filter = filter;
> +	return 0;
> +fail:
> +	kfree(filter);
> +	return ret;
> +}
> +
>
> ...
>
> +/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
> +void put_seccomp_filter(struct task_struct *tsk)
> +{
> +	struct seccomp_filter *orig = tsk->seccomp.filter;
> +	/* Clean up single-reference branches iteratively. */
> +	while (orig && atomic_dec_and_test(&orig->usage)) {
> +		struct seccomp_filter *freeme = orig;
> +		orig = orig->prev;
> +		kfree(freeme);
> +	}
> +}

So if one of the filters in the list has an elevated refcount, we bail
out on the remainder of the list.  Seems odd.

> +#endif	/* CONFIG_SECCOMP_FILTER */
>
> ...
>

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 20:01       ` [kernel-hardening] " Andrew Lutomirski
@ 2012-04-06 20:28         ` Jonathan Corbet
  -1 siblings, 0 replies; 146+ messages in thread
From: Jonathan Corbet @ 2012-04-06 20:28 UTC (permalink / raw)
  To: Andrew Lutomirski
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, eric.dumazet,
	markus, coreyb, keescook, jmorris, Andy Lutomirski, linux-man

On Fri, 6 Apr 2012 13:01:17 -0700
Andrew Lutomirski <luto@mit.edu> wrote:

> This has been bugging me for awhile.  Is there any interest in moving
> the manpages into the kernel source tree?  Then there could be a
> general requirement that new APIs get documented when they're written.

Man page (or other documentation) requirements for patch acceptance are a
regular kernel summit feature.  People seem to think it's a good idea, but
actual enforcement of such requirements always seems to be lacking.  Lots
of people have kind of given up trying.  I don't really see that adding
the man pages to the tree would help, but I could be wrong...

jon

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 20:28         ` Jonathan Corbet
  0 siblings, 0 replies; 146+ messages in thread
From: Jonathan Corbet @ 2012-04-06 20:28 UTC (permalink / raw)
  To: Andrew Lutomirski
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, eric.dumazet,
	markus, coreyb, keescook, jmorris, Andy Lutomirski, linux-man

On Fri, 6 Apr 2012 13:01:17 -0700
Andrew Lutomirski <luto@mit.edu> wrote:

> This has been bugging me for awhile.  Is there any interest in moving
> the manpages into the kernel source tree?  Then there could be a
> general requirement that new APIs get documented when they're written.

Man page (or other documentation) requirements for patch acceptance are a
regular kernel summit feature.  People seem to think it's a good idea, but
actual enforcement of such requirements always seems to be lacking.  Lots
of people have kind of given up trying.  I don't really see that adding
the man pages to the tree would help, but I could be wrong...

jon

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 20:28         ` [kernel-hardening] " Jonathan Corbet
@ 2012-04-06 20:37           ` Andrew Lutomirski
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Lutomirski @ 2012-04-06 20:37 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, eric.dumazet,
	markus, coreyb, keescook, jmorris, Andy Lutomirski, linux-man

On Fri, Apr 6, 2012 at 1:28 PM, Jonathan Corbet <corbet@lwn.net> wrote:
> On Fri, 6 Apr 2012 13:01:17 -0700
> Andrew Lutomirski <luto@mit.edu> wrote:
>
>> This has been bugging me for awhile.  Is there any interest in moving
>> the manpages into the kernel source tree?  Then there could be a
>> general requirement that new APIs get documented when they're written.
>
> Man page (or other documentation) requirements for patch acceptance are a
> regular kernel summit feature.  People seem to think it's a good idea, but
> actual enforcement of such requirements always seems to be lacking.  Lots
> of people have kind of given up trying.  I don't really see that adding
> the man pages to the tree would help, but I could be wrong...
>

If it's in the source, then I can send it with git format-patch.  If
it's out of tree, I have to find the tree, clone the tree, figure out
how to submit, and send separate emails.  And then whoever checks that
I documented it has to figure out where I sent it and how to read it
and then try to decide which documentation submission matches which
patch submission.

(Also, if it's in-tree, then I can build the docs from a kernel tree
and have the latest ones.  That could be nice.)

--Andy

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 20:37           ` Andrew Lutomirski
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Lutomirski @ 2012-04-06 20:37 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, eric.dumazet,
	markus, coreyb, keescook, jmorris, Andy Lutomirski, linux-man

On Fri, Apr 6, 2012 at 1:28 PM, Jonathan Corbet <corbet@lwn.net> wrote:
> On Fri, 6 Apr 2012 13:01:17 -0700
> Andrew Lutomirski <luto@mit.edu> wrote:
>
>> This has been bugging me for awhile.  Is there any interest in moving
>> the manpages into the kernel source tree?  Then there could be a
>> general requirement that new APIs get documented when they're written.
>
> Man page (or other documentation) requirements for patch acceptance are a
> regular kernel summit feature.  People seem to think it's a good idea, but
> actual enforcement of such requirements always seems to be lacking.  Lots
> of people have kind of given up trying.  I don't really see that adding
> the man pages to the tree would help, but I could be wrong...
>

If it's in the source, then I can send it with git format-patch.  If
it's out of tree, I have to find the tree, clone the tree, figure out
how to submit, and send separate emails.  And then whoever checks that
I documented it has to figure out where I sent it and how to read it
and then try to decide which documentation submission matches which
patch submission.

(Also, if it's in-tree, then I can build the docs from a kernel tree
and have the latest ones.  That could be nice.)

--Andy

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-06 20:23     ` [kernel-hardening] " Andrew Morton
@ 2012-04-06 20:44       ` Kees Cook
  -1 siblings, 0 replies; 146+ messages in thread
From: Kees Cook @ 2012-04-06 20:44 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On Fri, Apr 6, 2012 at 1:23 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:53 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> [This patch depends on luto@mit.edu's no_new_privs patch:
>>    https://lkml.org/lkml/2012/1/30/264
>>  included in this series for ease of consumption.
>> ]
>>
>> This patch adds support for seccomp mode 2.  Mode 2 introduces the
>> ability for unprivileged processes to install system call filtering
>> policy expressed in terms of a Berkeley Packet Filter (BPF) program.
>> This program will be evaluated in the kernel for each system call
>> the task makes and computes a result based on data in the format
>> of struct seccomp_data.
>> ...
>> +static void seccomp_filter_log_failure(int syscall)
>> +{
>> +     int compat = 0;
>> +#ifdef CONFIG_COMPAT
>> +     compat = is_compat_task();
>> +#endif
>
> hm, I'm surprised that we don't have a zero-returning implementation of
> is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.

There is, but this chunk of the patch is removed later on in the
series. We could just drop seccomp_filter_log_failure and it's single
call entirely and depend on the later enhancement to add the logging
that is desired.

>> +static long seccomp_attach_filter(struct sock_fprog *fprog)
>> +{
>> +     struct seccomp_filter *filter;
>> +     unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
>> +     unsigned long total_insns = fprog->len;
>> +     long ret;
>> +
>> +     if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
>> +             return -EINVAL;
>> +
>> +     for (filter = current->seccomp.filter; filter; filter = filter->prev)
>> +             total_insns += filter->len + 4;  /* include a 4 instr penalty */
>
> So tasks don't share filters?  We copy them by value at fork?  Do we do
> this at vfork() too?

The filter chain is shared (and refcounted).

>> +     if (total_insns > MAX_INSNS_PER_PATH)
>> +             return -ENOMEM;
>> +
>> +     /*
>> +      * Installing a seccomp filter requires that the task have
>> +      * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
>> +      * This avoids scenarios where unprivileged tasks can affect the
>> +      * behavior of privileged children.
>> +      */
>> +     if (!current->no_new_privs &&
>> +         security_capable_noaudit(current_cred(), current_user_ns(),
>> +                                  CAP_SYS_ADMIN) != 0)
>> +             return -EACCES;
>> +
>> +     /* Allocate a new seccomp_filter */
>> +     filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
>
> I think this gives userspace an easy way of causing page allocation
> failure warnings, by permitting large kmalloc() attempts.  Add
> __GFP_NOWARN?

This is likely mitigated by the MAX_INSNS_PER_PATH check above, but,
yeah, there's no harm in adding __GFP_NOWARN.

>> +/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
>> +void put_seccomp_filter(struct task_struct *tsk)
>> +{
>> +     struct seccomp_filter *orig = tsk->seccomp.filter;
>> +     /* Clean up single-reference branches iteratively. */
>> +     while (orig && atomic_dec_and_test(&orig->usage)) {
>> +             struct seccomp_filter *freeme = orig;
>> +             orig = orig->prev;
>> +             kfree(freeme);
>> +     }
>> +}
>
> So if one of the filters in the list has an elevated refcount, we bail
> out on the remainder of the list.  Seems odd.

This so that every filter in the list doesn't need to have their
refcount raised. As long as the counting up matching the counting
down, it's fine. This allows for process trees branching the filter
list at different times still being safe. IIUC, this code was based on
how namespace refcounting is handled. I spent some time proving to
myself that it was correctly refcounted a while back. More eyes is
better, of course. :)

-Kees

-- 
Kees Cook
ChromeOS Security

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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-06 20:44       ` Kees Cook
  0 siblings, 0 replies; 146+ messages in thread
From: Kees Cook @ 2012-04-06 20:44 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On Fri, Apr 6, 2012 at 1:23 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:53 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> [This patch depends on luto@mit.edu's no_new_privs patch:
>>    https://lkml.org/lkml/2012/1/30/264
>>  included in this series for ease of consumption.
>> ]
>>
>> This patch adds support for seccomp mode 2.  Mode 2 introduces the
>> ability for unprivileged processes to install system call filtering
>> policy expressed in terms of a Berkeley Packet Filter (BPF) program.
>> This program will be evaluated in the kernel for each system call
>> the task makes and computes a result based on data in the format
>> of struct seccomp_data.
>> ...
>> +static void seccomp_filter_log_failure(int syscall)
>> +{
>> +     int compat = 0;
>> +#ifdef CONFIG_COMPAT
>> +     compat = is_compat_task();
>> +#endif
>
> hm, I'm surprised that we don't have a zero-returning implementation of
> is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.

There is, but this chunk of the patch is removed later on in the
series. We could just drop seccomp_filter_log_failure and it's single
call entirely and depend on the later enhancement to add the logging
that is desired.

>> +static long seccomp_attach_filter(struct sock_fprog *fprog)
>> +{
>> +     struct seccomp_filter *filter;
>> +     unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
>> +     unsigned long total_insns = fprog->len;
>> +     long ret;
>> +
>> +     if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
>> +             return -EINVAL;
>> +
>> +     for (filter = current->seccomp.filter; filter; filter = filter->prev)
>> +             total_insns += filter->len + 4;  /* include a 4 instr penalty */
>
> So tasks don't share filters?  We copy them by value at fork?  Do we do
> this at vfork() too?

The filter chain is shared (and refcounted).

>> +     if (total_insns > MAX_INSNS_PER_PATH)
>> +             return -ENOMEM;
>> +
>> +     /*
>> +      * Installing a seccomp filter requires that the task have
>> +      * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
>> +      * This avoids scenarios where unprivileged tasks can affect the
>> +      * behavior of privileged children.
>> +      */
>> +     if (!current->no_new_privs &&
>> +         security_capable_noaudit(current_cred(), current_user_ns(),
>> +                                  CAP_SYS_ADMIN) != 0)
>> +             return -EACCES;
>> +
>> +     /* Allocate a new seccomp_filter */
>> +     filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
>
> I think this gives userspace an easy way of causing page allocation
> failure warnings, by permitting large kmalloc() attempts.  Add
> __GFP_NOWARN?

This is likely mitigated by the MAX_INSNS_PER_PATH check above, but,
yeah, there's no harm in adding __GFP_NOWARN.

>> +/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
>> +void put_seccomp_filter(struct task_struct *tsk)
>> +{
>> +     struct seccomp_filter *orig = tsk->seccomp.filter;
>> +     /* Clean up single-reference branches iteratively. */
>> +     while (orig && atomic_dec_and_test(&orig->usage)) {
>> +             struct seccomp_filter *freeme = orig;
>> +             orig = orig->prev;
>> +             kfree(freeme);
>> +     }
>> +}
>
> So if one of the filters in the list has an elevated refcount, we bail
> out on the remainder of the list.  Seems odd.

This so that every filter in the list doesn't need to have their
refcount raised. As long as the counting up matching the counting
down, it's fine. This allows for process trees branching the filter
list at different times still being safe. IIUC, this code was based on
how namespace refcounting is handled. I spent some time proving to
myself that it was correctly refcounted a while back. More eyes is
better, of course. :)

-Kees

-- 
Kees Cook
ChromeOS Security

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 19:49     ` [kernel-hardening] " Andrew Morton
@ 2012-04-06 20:47       ` Markus Gutschke
  -1 siblings, 0 replies; 146+ messages in thread
From: Markus Gutschke @ 2012-04-06 20:47 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 12:49, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:46 -0500
> Will Drewry <wad@chromium.org> wrote:
>> From: Andy Lutomirski <luto@amacapital.net>
>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>> become a lot less dangerous because there is no possibility of
>> subverting privileged binaries.

I don't want to derail things. So, tell me to go away, if I can't have
what I want.

Having said that, it would be great if NO_NEW_PRIVS also gave access
to the restricted clone() flags. Such as CLONE_NEWIPC, CLONE_NEWNET
and CLONE_NEWPID.


Markus

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 20:47       ` Markus Gutschke
  0 siblings, 0 replies; 146+ messages in thread
From: Markus Gutschke @ 2012-04-06 20:47 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 12:49, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:46 -0500
> Will Drewry <wad@chromium.org> wrote:
>> From: Andy Lutomirski <luto@amacapital.net>
>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>> become a lot less dangerous because there is no possibility of
>> subverting privileged binaries.

I don't want to derail things. So, tell me to go away, if I can't have
what I want.

Having said that, it would be great if NO_NEW_PRIVS also gave access
to the restricted clone() flags. Such as CLONE_NEWIPC, CLONE_NEWNET
and CLONE_NEWPID.


Markus

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 20:47       ` [kernel-hardening] " Markus Gutschke
@ 2012-04-06 20:54         ` Andrew Lutomirski
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Lutomirski @ 2012-04-06 20:54 UTC (permalink / raw)
  To: Markus Gutschke
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 1:47 PM, Markus Gutschke <markus@chromium.org> wrote:
> On Fri, Apr 6, 2012 at 12:49, Andrew Morton <akpm@linux-foundation.org> wrote:
>> On Thu, 29 Mar 2012 15:01:46 -0500
>> Will Drewry <wad@chromium.org> wrote:
>>> From: Andy Lutomirski <luto@amacapital.net>
>>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>>> become a lot less dangerous because there is no possibility of
>>> subverting privileged binaries.
>
> I don't want to derail things. So, tell me to go away, if I can't have
> what I want.
>
> Having said that, it would be great if NO_NEW_PRIVS also gave access
> to the restricted clone() flags. Such as CLONE_NEWIPC, CLONE_NEWNET
> and CLONE_NEWPID.

I decided to hold off on extra controversy for awhile.  However:

https://git.kernel.org/?p=linux/kernel/git/luto/linux.git;a=commit;h=9a520b74ad5dc14a3d6950b6d63a64714adbdd7d
and
http://web.mit.edu/luto/www/linux/nnp/newns.c

I fully intend to resurrect both of those once nnp lands.

(FWIW, I think that CLONE_NEWPID interacts badly with unix socket
credentials and should be fixed as a prerequisite for making it easier
to access.)

--Andy

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 20:54         ` Andrew Lutomirski
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Lutomirski @ 2012-04-06 20:54 UTC (permalink / raw)
  To: Markus Gutschke
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 1:47 PM, Markus Gutschke <markus@chromium.org> wrote:
> On Fri, Apr 6, 2012 at 12:49, Andrew Morton <akpm@linux-foundation.org> wrote:
>> On Thu, 29 Mar 2012 15:01:46 -0500
>> Will Drewry <wad@chromium.org> wrote:
>>> From: Andy Lutomirski <luto@amacapital.net>
>>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>>> become a lot less dangerous because there is no possibility of
>>> subverting privileged binaries.
>
> I don't want to derail things. So, tell me to go away, if I can't have
> what I want.
>
> Having said that, it would be great if NO_NEW_PRIVS also gave access
> to the restricted clone() flags. Such as CLONE_NEWIPC, CLONE_NEWNET
> and CLONE_NEWPID.

I decided to hold off on extra controversy for awhile.  However:

https://git.kernel.org/?p=linux/kernel/git/luto/linux.git;a=commit;h=9a520b74ad5dc14a3d6950b6d63a64714adbdd7d
and
http://web.mit.edu/luto/www/linux/nnp/newns.c

I fully intend to resurrect both of those once nnp lands.

(FWIW, I think that CLONE_NEWPID interacts badly with unix socket
credentials and should be fixed as a prerequisite for making it easier
to access.)

--Andy

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 20:54         ` [kernel-hardening] " Andrew Lutomirski
@ 2012-04-06 21:04           ` Markus Gutschke
  -1 siblings, 0 replies; 146+ messages in thread
From: Markus Gutschke @ 2012-04-06 21:04 UTC (permalink / raw)
  To: Andrew Lutomirski
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 13:54, Andrew Lutomirski <luto@mit.edu> wrote:
> (FWIW, I think that CLONE_NEWPID interacts badly with unix socket
> credentials and should be fixed as a prerequisite for making it easier
> to access.)

sendmsg() is a big hair ball. And yes, I have all sorts of things on
my wish list that touch sendmsg(). I don't think, I'll get them
fullfilled anytime soon, though:

 - sendmsg() does lots of different things: sending on unconnected
sockets, sending file descriptors, sending unix decriptors, and
plain-old sending data. These operations have very different security
properties and implications. It would be awesome if BPF filters could
filter these different types of operations selectively.

 - ancillary data is a cool concept in general. We should use it more.
If I could send a memory mapping from one process to another, that
would solve so many problems. But I know, I am dreaming; I don't
expect to see this feature any time soon.


Markus

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 21:04           ` Markus Gutschke
  0 siblings, 0 replies; 146+ messages in thread
From: Markus Gutschke @ 2012-04-06 21:04 UTC (permalink / raw)
  To: Andrew Lutomirski
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 13:54, Andrew Lutomirski <luto@mit.edu> wrote:
> (FWIW, I think that CLONE_NEWPID interacts badly with unix socket
> credentials and should be fixed as a prerequisite for making it easier
> to access.)

sendmsg() is a big hair ball. And yes, I have all sorts of things on
my wish list that touch sendmsg(). I don't think, I'll get them
fullfilled anytime soon, though:

 - sendmsg() does lots of different things: sending on unconnected
sockets, sending file descriptors, sending unix decriptors, and
plain-old sending data. These operations have very different security
properties and implications. It would be awesome if BPF filters could
filter these different types of operations selectively.

 - ancillary data is a cool concept in general. We should use it more.
If I could send a memory mapping from one process to another, that
would solve so many problems. But I know, I am dreaming; I don't
expect to see this feature any time soon.


Markus

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-06 20:44       ` [kernel-hardening] " Kees Cook
@ 2012-04-06 21:05         ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:05 UTC (permalink / raw)
  To: Kees Cook
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On Fri, 6 Apr 2012 13:44:43 -0700
Kees Cook <keescook@chromium.org> wrote:

> On Fri, Apr 6, 2012 at 1:23 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> > On Thu, 29 Mar 2012 15:01:53 -0500
> > Will Drewry <wad@chromium.org> wrote:
> >
> >> [This patch depends on luto@mit.edu's no_new_privs patch:
> >>    https://lkml.org/lkml/2012/1/30/264
> >>  included in this series for ease of consumption.
> >> ]
> >>
> >> This patch adds support for seccomp mode 2.  Mode 2 introduces the
> >> ability for unprivileged processes to install system call filtering
> >> policy expressed in terms of a Berkeley Packet Filter (BPF) program.
> >> This program will be evaluated in the kernel for each system call
> >> the task makes and computes a result based on data in the format
> >> of struct seccomp_data.
> >> ...
> >> +static void seccomp_filter_log_failure(int syscall)
> >> +{
> >> +     int compat = 0;
> >> +#ifdef CONFIG_COMPAT
> >> +     compat = is_compat_task();
> >> +#endif
> >
> > hm, I'm surprised that we don't have a zero-returning implementation of
> > is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
> 
> There is

I can't find it.  The definition in include/linux/compat.h is inside
#ifdef CONFIG_COMPAT.

> >> +static long seccomp_attach_filter(struct sock_fprog *fprog)
> >> +{
> >> +     struct seccomp_filter *filter;
> >> +     unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
> >> +     unsigned long total_insns = fprog->len;
> >> +     long ret;
> >> +
> >> +     if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
> >> +             return -EINVAL;
> >> +
> >> +     for (filter = current->seccomp.filter; filter; filter = filter->prev)
> >> +             total_insns += filter->len + 4;  /* include a 4 instr penalty */
> >
> > So tasks don't share filters?  We copy them by value at fork?  Do we do
> > this at vfork() too?
> 
> The filter chain is shared (and refcounted).

So what's the locking rule for accessing and modifying that
singly-linked list?

> ...
> >> +/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
> >> +void put_seccomp_filter(struct task_struct *tsk)
> >> +{
> >> +     struct seccomp_filter *orig = tsk->seccomp.filter;
> >> +     /* Clean up single-reference branches iteratively. */
> >> +     while (orig && atomic_dec_and_test(&orig->usage)) {
> >> +             struct seccomp_filter *freeme = orig;
> >> +             orig = orig->prev;
> >> +             kfree(freeme);
> >> +     }
> >> +}
> >
> > So if one of the filters in the list has an elevated refcount, we bail
> > out on the remainder of the list.  Seems odd.
> 
> This so that every filter in the list doesn't need to have their
> refcount raised. As long as the counting up matching the counting
> down, it's fine. This allows for process trees branching the filter
> list at different times still being safe. IIUC, this code was based on
> how namespace refcounting is handled. I spent some time proving to
> myself that it was correctly refcounted a while back. More eyes is
> better, of course. :)

Please ensure that future readers of this code have a description of
how it is supposed to work.

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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-06 21:05         ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:05 UTC (permalink / raw)
  To: Kees Cook
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On Fri, 6 Apr 2012 13:44:43 -0700
Kees Cook <keescook@chromium.org> wrote:

> On Fri, Apr 6, 2012 at 1:23 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> > On Thu, 29 Mar 2012 15:01:53 -0500
> > Will Drewry <wad@chromium.org> wrote:
> >
> >> [This patch depends on luto@mit.edu's no_new_privs patch:
> >>    https://lkml.org/lkml/2012/1/30/264
> >>  included in this series for ease of consumption.
> >> ]
> >>
> >> This patch adds support for seccomp mode 2.  Mode 2 introduces the
> >> ability for unprivileged processes to install system call filtering
> >> policy expressed in terms of a Berkeley Packet Filter (BPF) program.
> >> This program will be evaluated in the kernel for each system call
> >> the task makes and computes a result based on data in the format
> >> of struct seccomp_data.
> >> ...
> >> +static void seccomp_filter_log_failure(int syscall)
> >> +{
> >> +     int compat = 0;
> >> +#ifdef CONFIG_COMPAT
> >> +     compat = is_compat_task();
> >> +#endif
> >
> > hm, I'm surprised that we don't have a zero-returning implementation of
> > is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
> 
> There is

I can't find it.  The definition in include/linux/compat.h is inside
#ifdef CONFIG_COMPAT.

> >> +static long seccomp_attach_filter(struct sock_fprog *fprog)
> >> +{
> >> +     struct seccomp_filter *filter;
> >> +     unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
> >> +     unsigned long total_insns = fprog->len;
> >> +     long ret;
> >> +
> >> +     if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
> >> +             return -EINVAL;
> >> +
> >> +     for (filter = current->seccomp.filter; filter; filter = filter->prev)
> >> +             total_insns += filter->len + 4;  /* include a 4 instr penalty */
> >
> > So tasks don't share filters?  We copy them by value at fork?  Do we do
> > this at vfork() too?
> 
> The filter chain is shared (and refcounted).

So what's the locking rule for accessing and modifying that
singly-linked list?

> ...
> >> +/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
> >> +void put_seccomp_filter(struct task_struct *tsk)
> >> +{
> >> +     struct seccomp_filter *orig = tsk->seccomp.filter;
> >> +     /* Clean up single-reference branches iteratively. */
> >> +     while (orig && atomic_dec_and_test(&orig->usage)) {
> >> +             struct seccomp_filter *freeme = orig;
> >> +             orig = orig->prev;
> >> +             kfree(freeme);
> >> +     }
> >> +}
> >
> > So if one of the filters in the list has an elevated refcount, we bail
> > out on the remainder of the list.  Seems odd.
> 
> This so that every filter in the list doesn't need to have their
> refcount raised. As long as the counting up matching the counting
> down, it's fine. This allows for process trees branching the filter
> list at different times still being safe. IIUC, this code was based on
> how namespace refcounting is handled. I spent some time proving to
> myself that it was correctly refcounted a while back. More eyes is
> better, of course. :)

Please ensure that future readers of this code have a description of
how it is supposed to work.

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-06 21:05         ` [kernel-hardening] " Andrew Morton
@ 2012-04-06 21:06           ` H. Peter Anvin
  -1 siblings, 0 replies; 146+ messages in thread
From: H. Peter Anvin @ 2012-04-06 21:06 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto,
	eparis, serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On 04/06/2012 02:05 PM, Andrew Morton wrote:
>>>
>>> hm, I'm surprised that we don't have a zero-returning implementation of
>>> is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
>>
>> There is
> 
> I can't find it.  The definition in include/linux/compat.h is inside
> #ifdef CONFIG_COMPAT.
> 

I thought Linus globalized it very recently...

	-hpa


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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-06 21:06           ` H. Peter Anvin
  0 siblings, 0 replies; 146+ messages in thread
From: H. Peter Anvin @ 2012-04-06 21:06 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto,
	eparis, serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On 04/06/2012 02:05 PM, Andrew Morton wrote:
>>>
>>> hm, I'm surprised that we don't have a zero-returning implementation of
>>> is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
>>
>> There is
> 
> I can't find it.  The definition in include/linux/compat.h is inside
> #ifdef CONFIG_COMPAT.
> 

I thought Linus globalized it very recently...

	-hpa

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-06 21:06           ` [kernel-hardening] " H. Peter Anvin
@ 2012-04-06 21:09             ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:09 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Kees Cook, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto,
	eparis, serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On Fri, 06 Apr 2012 14:06:01 -0700
"H. Peter Anvin" <hpa@zytor.com> wrote:

> On 04/06/2012 02:05 PM, Andrew Morton wrote:
> >>>
> >>> hm, I'm surprised that we don't have a zero-returning implementation of
> >>> is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
> >>
> >> There is
> > 
> > I can't find it.  The definition in include/linux/compat.h is inside
> > #ifdef CONFIG_COMPAT.
> > 
> 
> I thought Linus globalized it very recently...

Oh, yeah, I misread.

We should be able to remove quite a few open-coded ifdefs now.

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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-06 21:09             ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:09 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Kees Cook, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto,
	eparis, serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On Fri, 06 Apr 2012 14:06:01 -0700
"H. Peter Anvin" <hpa@zytor.com> wrote:

> On 04/06/2012 02:05 PM, Andrew Morton wrote:
> >>>
> >>> hm, I'm surprised that we don't have a zero-returning implementation of
> >>> is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
> >>
> >> There is
> > 
> > I can't find it.  The definition in include/linux/compat.h is inside
> > #ifdef CONFIG_COMPAT.
> > 
> 
> I thought Linus globalized it very recently...

Oh, yeah, I misread.

We should be able to remove quite a few open-coded ifdefs now.

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

* Re: [PATCH v17 09/15] seccomp: remove duplicated failure logging
  2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
@ 2012-04-06 21:14     ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:14 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:01:54 -0500
Will Drewry <wad@chromium.org> wrote:

> From: Kees Cook <keescook@chromium.org>
> 
> This consolidates the seccomp filter error logging path and adds more
> details to the audit log.
> 
> ...
>
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
>
> ...
>
>  #define audit_inode(n,d) do { (void)(d); } while (0)
>  #define audit_inode_child(i,p) do { ; } while (0)
>  #define audit_core_dumps(i) do { ; } while (0)
> -#define audit_seccomp(i) do { ; } while (0)
> +#define audit_seccomp(i,s,c) do { ; } while (0)

Sigh.  Someone please convert all these to C.  That way we get
typechecking and don't need dopey party tricks like that "(void)(d)" to
squish compilation warnings.

> ...
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -67,6 +67,7 @@
>  #include <linux/syscalls.h>
>  #include <linux/capability.h>
>  #include <linux/fs_struct.h>
> +#include <linux/compat.h>
>  
>  #include "audit.h"
>  
> @@ -2710,13 +2711,18 @@ void audit_core_dumps(long signr)
>  	audit_log_end(ab);
>  }
>  
> -void __audit_seccomp(unsigned long syscall)
> +void __audit_seccomp(unsigned long syscall, long signr, int code)
>  {
>  	struct audit_buffer *ab;
>  
>  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
> -	audit_log_abend(ab, "seccomp", SIGKILL);
> +	audit_log_abend(ab, "seccomp", signr);
>  	audit_log_format(ab, " syscall=%ld", syscall);
> +#ifdef CONFIG_COMPAT
> +	audit_log_format(ab, " compat=%d", is_compat_task());
> +#endif

We don't need the ifdef for compilation reasons now.

The question is: should we emit the compat= record on
non-compat-capable architectures?  Doing so would be safer - making it
conditional invites people to write x86-only usersapce.



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

* [kernel-hardening] Re: [PATCH v17 09/15] seccomp: remove duplicated failure logging
@ 2012-04-06 21:14     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:14 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:01:54 -0500
Will Drewry <wad@chromium.org> wrote:

> From: Kees Cook <keescook@chromium.org>
> 
> This consolidates the seccomp filter error logging path and adds more
> details to the audit log.
> 
> ...
>
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
>
> ...
>
>  #define audit_inode(n,d) do { (void)(d); } while (0)
>  #define audit_inode_child(i,p) do { ; } while (0)
>  #define audit_core_dumps(i) do { ; } while (0)
> -#define audit_seccomp(i) do { ; } while (0)
> +#define audit_seccomp(i,s,c) do { ; } while (0)

Sigh.  Someone please convert all these to C.  That way we get
typechecking and don't need dopey party tricks like that "(void)(d)" to
squish compilation warnings.

> ...
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -67,6 +67,7 @@
>  #include <linux/syscalls.h>
>  #include <linux/capability.h>
>  #include <linux/fs_struct.h>
> +#include <linux/compat.h>
>  
>  #include "audit.h"
>  
> @@ -2710,13 +2711,18 @@ void audit_core_dumps(long signr)
>  	audit_log_end(ab);
>  }
>  
> -void __audit_seccomp(unsigned long syscall)
> +void __audit_seccomp(unsigned long syscall, long signr, int code)
>  {
>  	struct audit_buffer *ab;
>  
>  	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
> -	audit_log_abend(ab, "seccomp", SIGKILL);
> +	audit_log_abend(ab, "seccomp", signr);
>  	audit_log_format(ab, " syscall=%ld", syscall);
> +#ifdef CONFIG_COMPAT
> +	audit_log_format(ab, " compat=%d", is_compat_task());
> +#endif

We don't need the ifdef for compilation reasons now.

The question is: should we emit the compat= record on
non-compat-capable architectures?  Doing so would be safer - making it
conditional invites people to write x86-only usersapce.

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 21:04           ` [kernel-hardening] " Markus Gutschke
@ 2012-04-06 21:15             ` Andrew Lutomirski
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Lutomirski @ 2012-04-06 21:15 UTC (permalink / raw)
  To: Markus Gutschke
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 2:04 PM, Markus Gutschke <markus@chromium.org> wrote:
> On Fri, Apr 6, 2012 at 13:54, Andrew Lutomirski <luto@mit.edu> wrote:
>> (FWIW, I think that CLONE_NEWPID interacts badly with unix socket
>> credentials and should be fixed as a prerequisite for making it easier
>> to access.)
>
> sendmsg() is a big hair ball. And yes, I have all sorts of things on
> my wish list that touch sendmsg(). I don't think, I'll get them
> fullfilled anytime soon, though:
>
>  - sendmsg() does lots of different things: sending on unconnected
> sockets, sending file descriptors, sending unix decriptors, and
> plain-old sending data. These operations have very different security
> properties and implications. It would be awesome if BPF filters could
> filter these different types of operations selectively.
>
>  - ancillary data is a cool concept in general. We should use it more.
> If I could send a memory mapping from one process to another, that
> would solve so many problems. But I know, I am dreaming; I don't
> expect to see this feature any time soon.
>

Agreed, but I'm talking about something totally different: if I can
use CLONE_NEWPID, then I can send an unexpected pid with SCM_CREDS.
The SCM_CREDS receive code should remap pids.

--Andy

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 21:15             ` Andrew Lutomirski
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Lutomirski @ 2012-04-06 21:15 UTC (permalink / raw)
  To: Markus Gutschke
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 2:04 PM, Markus Gutschke <markus@chromium.org> wrote:
> On Fri, Apr 6, 2012 at 13:54, Andrew Lutomirski <luto@mit.edu> wrote:
>> (FWIW, I think that CLONE_NEWPID interacts badly with unix socket
>> credentials and should be fixed as a prerequisite for making it easier
>> to access.)
>
> sendmsg() is a big hair ball. And yes, I have all sorts of things on
> my wish list that touch sendmsg(). I don't think, I'll get them
> fullfilled anytime soon, though:
>
>  - sendmsg() does lots of different things: sending on unconnected
> sockets, sending file descriptors, sending unix decriptors, and
> plain-old sending data. These operations have very different security
> properties and implications. It would be awesome if BPF filters could
> filter these different types of operations selectively.
>
>  - ancillary data is a cool concept in general. We should use it more.
> If I could send a memory mapping from one process to another, that
> would solve so many problems. But I know, I am dreaming; I don't
> expect to see this feature any time soon.
>

Agreed, but I'm talking about something totally different: if I can
use CLONE_NEWPID, then I can send an unexpected pid with SCM_CREDS.
The SCM_CREDS receive code should remap pids.

--Andy

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

* Re: [PATCH v17 10/15] seccomp: add SECCOMP_RET_ERRNO
  2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
@ 2012-04-06 21:19     ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:19 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:01:55 -0500
Will Drewry <wad@chromium.org> wrote:

> This change adds the SECCOMP_RET_ERRNO as a valid return value from a
> seccomp filter.  Additionally, it makes the first use of the lower
> 16-bits for storing a filter-supplied errno.  16-bits is more than
> enough for the errno-base.h calls.
> 
> Returning errors instead of immediately terminating processes that
> violate seccomp policy allow for broader use of this functionality
> for kernel attack surface reduction.  For example, a linux container
> could maintain a whitelist of pre-existing system calls but drop
> all new ones with errnos.  This would keep a logically static attack
> surface while providing errnos that may allow for graceful failure
> without the downside of do_exit() on a bad call.
> 
>
> ...
>
> @@ -64,11 +65,17 @@ struct seccomp {
>  	struct seccomp_filter *filter;
>  };
>  
> -extern void __secure_computing(int);
> -static inline void secure_computing(int this_syscall)
> +/*
> + * Direct callers to __secure_computing should be updated as
> + * CONFIG_HAVE_ARCH_SECCOMP_FILTER propagates.

Are there any such callers?  There's one I see in arm, but it's called
from assembly code.

> + */
> +extern void __secure_computing(int) __deprecated;
> +extern int __secure_computing_int(int);
> +static inline int secure_computing(int this_syscall)
>  {
>  	if (unlikely(test_thread_flag(TIF_SECCOMP)))
> -		__secure_computing(this_syscall);
> +		return  __secure_computing_int(this_syscall);
> +	return 0;
>  }
>  
> ...
>
>  void __secure_computing(int this_syscall)
>  {
> +	/* Filter calls should never use this function. */
> +	BUG_ON(current->seccomp.mode == SECCOMP_MODE_FILTER);
> +	__secure_computing_int(this_syscall);
> +}
> +
> +int __secure_computing_int(int this_syscall)

What the heck does "_int" mean here?  I read it as "integer" but
perhaps it's shorthand for "internal".  Give us a better name, please. 
Or a code comment.

> +{
>  	int mode = current->seccomp.mode;
>  	int exit_sig = 0;
>  	int *syscall;
> +	u32 ret = SECCOMP_RET_KILL;
> +	int data;
>  
>  	switch (mode) {
>  	case SECCOMP_MODE_STRICT:


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

* [kernel-hardening] Re: [PATCH v17 10/15] seccomp: add SECCOMP_RET_ERRNO
@ 2012-04-06 21:19     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:19 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:01:55 -0500
Will Drewry <wad@chromium.org> wrote:

> This change adds the SECCOMP_RET_ERRNO as a valid return value from a
> seccomp filter.  Additionally, it makes the first use of the lower
> 16-bits for storing a filter-supplied errno.  16-bits is more than
> enough for the errno-base.h calls.
> 
> Returning errors instead of immediately terminating processes that
> violate seccomp policy allow for broader use of this functionality
> for kernel attack surface reduction.  For example, a linux container
> could maintain a whitelist of pre-existing system calls but drop
> all new ones with errnos.  This would keep a logically static attack
> surface while providing errnos that may allow for graceful failure
> without the downside of do_exit() on a bad call.
> 
>
> ...
>
> @@ -64,11 +65,17 @@ struct seccomp {
>  	struct seccomp_filter *filter;
>  };
>  
> -extern void __secure_computing(int);
> -static inline void secure_computing(int this_syscall)
> +/*
> + * Direct callers to __secure_computing should be updated as
> + * CONFIG_HAVE_ARCH_SECCOMP_FILTER propagates.

Are there any such callers?  There's one I see in arm, but it's called
from assembly code.

> + */
> +extern void __secure_computing(int) __deprecated;
> +extern int __secure_computing_int(int);
> +static inline int secure_computing(int this_syscall)
>  {
>  	if (unlikely(test_thread_flag(TIF_SECCOMP)))
> -		__secure_computing(this_syscall);
> +		return  __secure_computing_int(this_syscall);
> +	return 0;
>  }
>  
> ...
>
>  void __secure_computing(int this_syscall)
>  {
> +	/* Filter calls should never use this function. */
> +	BUG_ON(current->seccomp.mode == SECCOMP_MODE_FILTER);
> +	__secure_computing_int(this_syscall);
> +}
> +
> +int __secure_computing_int(int this_syscall)

What the heck does "_int" mean here?  I read it as "integer" but
perhaps it's shorthand for "internal".  Give us a better name, please. 
Or a code comment.

> +{
>  	int mode = current->seccomp.mode;
>  	int exit_sig = 0;
>  	int *syscall;
> +	u32 ret = SECCOMP_RET_KILL;
> +	int data;
>  
>  	switch (mode) {
>  	case SECCOMP_MODE_STRICT:

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

* Re: [PATCH v17 13/15] ptrace,seccomp: Add PTRACE_SECCOMP support
  2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
@ 2012-04-06 21:24     ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:24 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:01:58 -0500
Will Drewry <wad@chromium.org> wrote:

> This change adds support for a new ptrace option, PTRACE_O_TRACESECCOMP,
> and a new return value for seccomp BPF programs, SECCOMP_RET_TRACE.
> 
> When a tracer specifies the PTRACE_O_TRACESECCOMP ptrace option, the
> tracer will be notified, via PTRACE_EVENT_SECCOMP, for any syscall that
> results in a BPF program returning SECCOMP_RET_TRACE.  The 16-bit
> SECCOMP_RET_DATA mask of the BPF program return value will be passed as
> the ptrace_message and may be retrieved using PTRACE_GETEVENTMSG.
> 
> If the subordinate process is not using seccomp filter, then no
> system call notifications will occur even if the option is specified.
> 
> If there is no tracer with PTRACE_O_TRACESECCOMP when SECCOMP_RET_TRACE
> is returned, the system call will not be executed and an -ENOSYS errno
> will be returned to userspace.
> 
> This change adds a dependency on the system call slow path.  Any future
> efforts to use the system call fast path for seccomp filter will need to
> address this restriction.
> 
>
> ...
>
> @@ -410,6 +411,15 @@ int __secure_computing_int(int this_syscall)
>  			/* Let the filter pass back 16 bits of data. */
>  			seccomp_send_sigsys(this_syscall, data);
>  			goto skip;
> +		case SECCOMP_RET_TRACE:
> +			/* Skip these calls if there is no tracer. */
> +			if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP))
> +				goto skip;
> +			/* Allow the BPF to provide the event message */
> +			ptrace_event(PTRACE_EVENT_SECCOMP, data);
> +			if (fatal_signal_pending(current))
> +				break;

I don't have all the patches applied here so the context is missing. 
Perhaps tht would help me understand what this fatal_signal_pending()
test is doing here.  But an explanatory comment wouldn't hurt.

What *is* it here for, anyway?

> +			return 0;
>  		case SECCOMP_RET_ALLOW:
>  			return 0;
>  		case SECCOMP_RET_KILL:


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

* [kernel-hardening] Re: [PATCH v17 13/15] ptrace,seccomp: Add PTRACE_SECCOMP support
@ 2012-04-06 21:24     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:24 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:01:58 -0500
Will Drewry <wad@chromium.org> wrote:

> This change adds support for a new ptrace option, PTRACE_O_TRACESECCOMP,
> and a new return value for seccomp BPF programs, SECCOMP_RET_TRACE.
> 
> When a tracer specifies the PTRACE_O_TRACESECCOMP ptrace option, the
> tracer will be notified, via PTRACE_EVENT_SECCOMP, for any syscall that
> results in a BPF program returning SECCOMP_RET_TRACE.  The 16-bit
> SECCOMP_RET_DATA mask of the BPF program return value will be passed as
> the ptrace_message and may be retrieved using PTRACE_GETEVENTMSG.
> 
> If the subordinate process is not using seccomp filter, then no
> system call notifications will occur even if the option is specified.
> 
> If there is no tracer with PTRACE_O_TRACESECCOMP when SECCOMP_RET_TRACE
> is returned, the system call will not be executed and an -ENOSYS errno
> will be returned to userspace.
> 
> This change adds a dependency on the system call slow path.  Any future
> efforts to use the system call fast path for seccomp filter will need to
> address this restriction.
> 
>
> ...
>
> @@ -410,6 +411,15 @@ int __secure_computing_int(int this_syscall)
>  			/* Let the filter pass back 16 bits of data. */
>  			seccomp_send_sigsys(this_syscall, data);
>  			goto skip;
> +		case SECCOMP_RET_TRACE:
> +			/* Skip these calls if there is no tracer. */
> +			if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP))
> +				goto skip;
> +			/* Allow the BPF to provide the event message */
> +			ptrace_event(PTRACE_EVENT_SECCOMP, data);
> +			if (fatal_signal_pending(current))
> +				break;

I don't have all the patches applied here so the context is missing. 
Perhaps tht would help me understand what this fatal_signal_pending()
test is doing here.  But an explanatory comment wouldn't hurt.

What *is* it here for, anyway?

> +			return 0;
>  		case SECCOMP_RET_ALLOW:
>  			return 0;
>  		case SECCOMP_RET_KILL:

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

* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
  2012-03-29 20:02   ` [kernel-hardening] " Will Drewry
@ 2012-04-06 21:26     ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:26 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:02:00 -0500
Will Drewry <wad@chromium.org> wrote:

> Documents how system call filtering using Berkeley Packet
> Filter programs works and how it may be used.
> Includes an example for x86 and a semi-generic
> example using a macro-based code generator.
> 
>
> ...
>
> +Adding architecture support
> +-----------------------
> +
> +See arch/Kconfig for the authoritative requirements.  In general, if an
> +architecture supports both ptrace_event and seccomp, it will be able to
> +support seccomp filter with minor fixup: SIGSYS support and seccomp return
> +value checking.  Then it must just add CONFIG_HAVE_ARCH_SECCOMP_FILTER
> +to its arch-specific Kconfig.
> diff --git a/samples/Makefile b/samples/Makefile
> index 2f75851..5ef08bb 100644
> --- a/samples/Makefile
> +++ b/samples/Makefile

Oh good, I was going to ask about that.

Can we get this code into tools/testing/selftests?  That way people
will run it more often and it's more likely to be maintained as the
code evolves.


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

* [kernel-hardening] Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
@ 2012-04-06 21:26     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:26 UTC (permalink / raw)
  To: Will Drewry
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Thu, 29 Mar 2012 15:02:00 -0500
Will Drewry <wad@chromium.org> wrote:

> Documents how system call filtering using Berkeley Packet
> Filter programs works and how it may be used.
> Includes an example for x86 and a semi-generic
> example using a macro-based code generator.
> 
>
> ...
>
> +Adding architecture support
> +-----------------------
> +
> +See arch/Kconfig for the authoritative requirements.  In general, if an
> +architecture supports both ptrace_event and seccomp, it will be able to
> +support seccomp filter with minor fixup: SIGSYS support and seccomp return
> +value checking.  Then it must just add CONFIG_HAVE_ARCH_SECCOMP_FILTER
> +to its arch-specific Kconfig.
> diff --git a/samples/Makefile b/samples/Makefile
> index 2f75851..5ef08bb 100644
> --- a/samples/Makefile
> +++ b/samples/Makefile

Oh good, I was going to ask about that.

Can we get this code into tools/testing/selftests?  That way people
will run it more often and it's more likely to be maintained as the
code evolves.

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

* Re: [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering
  2012-03-29 23:11   ` [kernel-hardening] " James Morris
  (?)
@ 2012-04-06 21:28     ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:28 UTC (permalink / raw)
  To: James Morris
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook, Oleg Nesterov

On Fri, 30 Mar 2012 10:11:32 +1100 (EST)
James Morris <jmorris@namei.org> wrote:

> On Thu, 29 Mar 2012, Will Drewry wrote:
> 
> > Please see prior revisions for a detailed discussion of this patch
> > series.
> > 
> > This series is a rebase on to:
> >   b5174fa3a7f4f8f150bfa3b917c92608953dfa0f
> > with very minor changes due to rebasing and tweaks noticed by a few
> > initial users.  (I will rebase again for v3.4-rc1 when that time comes.)
> 
> I've offered to take this via my tree -- if anyone else wants to merge it 
> via theirs instead, holler.

OK by me, especially if it means that you'll carefully (re)review it!  I
had some minor quibbles with v17.

It would be good if Oleg could take a look at the signal changes, if he
has not yet done so?

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

* Re: [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering
@ 2012-04-06 21:28     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:28 UTC (permalink / raw)
  To: James Morris
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook

On Fri, 30 Mar 2012 10:11:32 +1100 (EST)
James Morris <jmorris@namei.org> wrote:

> On Thu, 29 Mar 2012, Will Drewry wrote:
> 
> > Please see prior revisions for a detailed discussion of this patch
> > series.
> > 
> > This series is a rebase on to:
> >   b5174fa3a7f4f8f150bfa3b917c92608953dfa0f
> > with very minor changes due to rebasing and tweaks noticed by a few
> > initial users.  (I will rebase again for v3.4-rc1 when that time comes.)
> 
> I've offered to take this via my tree -- if anyone else wants to merge it 
> via theirs instead, holler.

OK by me, especially if it means that you'll carefully (re)review it!  I
had some minor quibbles with v17.

It would be good if Oleg could take a look at the signal changes, if he
has not yet done so?

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

* [kernel-hardening] Re: [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering
@ 2012-04-06 21:28     ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-06 21:28 UTC (permalink / raw)
  To: James Morris
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook

On Fri, 30 Mar 2012 10:11:32 +1100 (EST)
James Morris <jmorris@namei.org> wrote:

> On Thu, 29 Mar 2012, Will Drewry wrote:
> 
> > Please see prior revisions for a detailed discussion of this patch
> > series.
> > 
> > This series is a rebase on to:
> >   b5174fa3a7f4f8f150bfa3b917c92608953dfa0f
> > with very minor changes due to rebasing and tweaks noticed by a few
> > initial users.  (I will rebase again for v3.4-rc1 when that time comes.)
> 
> I've offered to take this via my tree -- if anyone else wants to merge it 
> via theirs instead, holler.

OK by me, especially if it means that you'll carefully (re)review it!  I
had some minor quibbles with v17.

It would be good if Oleg could take a look at the signal changes, if he
has not yet done so?

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 21:15             ` [kernel-hardening] " Andrew Lutomirski
@ 2012-04-06 21:32               ` Markus Gutschke
  -1 siblings, 0 replies; 146+ messages in thread
From: Markus Gutschke @ 2012-04-06 21:32 UTC (permalink / raw)
  To: Andrew Lutomirski
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 14:15, Andrew Lutomirski <luto@mit.edu> wrote:
> Agreed, but I'm talking about something totally different: if I can
> use CLONE_NEWPID, then I can send an unexpected pid with SCM_CREDS.
> The SCM_CREDS receive code should remap pids.

Yes, I know. It's broken. And so is the view of the /proc filesystem
when inside a pid namespace. And things behave funny if you don't set
up a new "init" process inside of the pid namespace. And I am sure, a
few other things are broken that we just haven't run into.

CLONE_NEWPID is tricky. I can understand, if you want to fix it first.
Looking forward to seeing some patches in the future; please cc me, if
you want feedback from an actual user of this code.

The SCM_CREDS issue is the most serious one of the above, but it
doesn't bother me personally, as I would just set up my sandbox policy
to disallow all of SCM_CREDS (*). But that obviously not a good excuse
for leaving a kernel bug around.

Overall, I like both NO_NEW_PRIVS and BPF filters for seccomp though;
they are a great way to reduce the attack surface of the kernel.
Kernel bugs become a lot less of a headache, if I have a way to filter
out the buggy parts of the kernel. It isn't a panacea, but it's a
great new tool to harden applications.


Markus


*) this is currently difficult to filter SCM_CREDS, if we still want
to allow SCM_RIGHTS. See my earlier complaint about sendmsg().
Currently, filtering of sendmsg() probably requires the use of a
helper process.

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-06 21:32               ` Markus Gutschke
  0 siblings, 0 replies; 146+ messages in thread
From: Markus Gutschke @ 2012-04-06 21:32 UTC (permalink / raw)
  To: Andrew Lutomirski
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 14:15, Andrew Lutomirski <luto@mit.edu> wrote:
> Agreed, but I'm talking about something totally different: if I can
> use CLONE_NEWPID, then I can send an unexpected pid with SCM_CREDS.
> The SCM_CREDS receive code should remap pids.

Yes, I know. It's broken. And so is the view of the /proc filesystem
when inside a pid namespace. And things behave funny if you don't set
up a new "init" process inside of the pid namespace. And I am sure, a
few other things are broken that we just haven't run into.

CLONE_NEWPID is tricky. I can understand, if you want to fix it first.
Looking forward to seeing some patches in the future; please cc me, if
you want feedback from an actual user of this code.

The SCM_CREDS issue is the most serious one of the above, but it
doesn't bother me personally, as I would just set up my sandbox policy
to disallow all of SCM_CREDS (*). But that obviously not a good excuse
for leaving a kernel bug around.

Overall, I like both NO_NEW_PRIVS and BPF filters for seccomp though;
they are a great way to reduce the attack surface of the kernel.
Kernel bugs become a lot less of a headache, if I have a way to filter
out the buggy parts of the kernel. It isn't a panacea, but it's a
great new tool to harden applications.


Markus


*) this is currently difficult to filter SCM_CREDS, if we still want
to allow SCM_RIGHTS. See my earlier complaint about sendmsg().
Currently, filtering of sendmsg() probably requires the use of a
helper process.

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-06 20:23     ` [kernel-hardening] " Andrew Morton
@ 2012-04-08 18:22       ` Indan Zupancic
  -1 siblings, 0 replies; 146+ messages in thread
From: Indan Zupancic @ 2012-04-08 18:22 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Sat, April 7, 2012 06:23, Andrew Morton wrote:
> hm, I'm surprised that we don't have a zero-returning implementation of
> is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.

It's sneakily hidden at the end of compat.h.

>> +/**
>> + * get_u32 - returns a u32 offset into data
>> + * @data: a unsigned 64 bit value
>> + * @index: 0 or 1 to return the first or second 32-bits
>> + *
>> + * This inline exists to hide the length of unsigned long.
>> + * If a 32-bit unsigned long is passed in, it will be extended
>> + * and the top 32-bits will be 0. If it is a 64-bit unsigned
>> + * long, then whatever data is resident will be properly returned.
>> + */
>> +static inline u32 get_u32(u64 data, int index)
>> +{
>> +	return ((u32 *)&data)[index];
>> +}
>
> This seems utterly broken on big-endian machines.  If so: fix.  If not:
> add comment explaining why?

It's not a bug, it's intentional.

I tried to convince them to have a stable ABI for all archs, but they
didn't want to make the ABI endianness independent, because it looks
uglier. The argument being that system call numbers are arch dependent
anyway.

So a filter for a little endian arch needs to check a different offset
than one for a big endian archs.

>> +static u32 seccomp_run_filters(int syscall)
>> +{
>> +	struct seccomp_filter *f;
>> +	u32 ret = SECCOMP_RET_KILL;
>> +	/*
>> +	 * All filters are evaluated in order of youngest to oldest. The lowest
>> +	 * BPF return value always takes priority.
>> +	 */
>
> The youngest-first design surprised me.  It wasn't mentioned at all in
> the changelog.  Thinking about it, I guess it just doesn't matter.  But
> some description of the reasons for and implications of this decision
> for the uninitiated would be welcome.

I think it's less confusing to not mention the order at all, exactly
because it doesn't matter. It has been like this from the start, so
that's why it's not mentioned in the changelog I guess.

The reason to check the youngest first is because the filters are shared
between processes: childs inherit it. If later on additional filters are
added, the only way of adding them without modifying an older filter is
by adding them to the head of the list. This way no locking is needed,
because filters are only added and removed single-threadedly, and never
modified when being shared.

>> +/**
>> + * seccomp_attach_filter: Attaches a seccomp filter to current.
>> + * @fprog: BPF program to install
>> + *
>> + * Returns 0 on success or an errno on failure.
>> + */
>> +static long seccomp_attach_filter(struct sock_fprog *fprog)
>> +{
>> +	struct seccomp_filter *filter;
>> +	unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
>> +	unsigned long total_insns = fprog->len;
>> +	long ret;
>> +
>> +	if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
>> +		return -EINVAL;
>> +
>> +	for (filter = current->seccomp.filter; filter; filter = filter->prev)
>> +		total_insns += filter->len + 4;  /* include a 4 instr penalty */
>
> So tasks don't share filters?  We copy them by value at fork?  Do we do
> this at vfork() too?

Yes they do. But shared filters are never modified, except for the refcount.

>
>> +	if (total_insns > MAX_INSNS_PER_PATH)
>> +		return -ENOMEM;
>> +
>> +	/*
>> +	 * Installing a seccomp filter requires that the task have
>> +	 * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
>> +	 * This avoids scenarios where unprivileged tasks can affect the
>> +	 * behavior of privileged children.
>> +	 */
>> +	if (!current->no_new_privs &&
>> +	    security_capable_noaudit(current_cred(), current_user_ns(),
>> +				     CAP_SYS_ADMIN) != 0)
>> +		return -EACCES;
>> +
>> +	/* Allocate a new seccomp_filter */
>> +	filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
>
> I think this gives userspace an easy way of causing page allocation
> failure warnings, by permitting large kmalloc() attempts.  Add
> __GFP_NOWARN?

Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
it allocates up to 512kb before even checking the length.

What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?

>> +	/* Check and rewrite the fprog via the skb checker */
>> +	ret = sk_chk_filter(filter->insns, filter->len);
>> +	if (ret)
>> +		goto fail;
>> +
>> +	/* Check and rewrite the fprog for seccomp use */
>> +	ret = seccomp_chk_filter(filter->insns, filter->len);
>
> "check" is spelled "check"!

Yes, it is and he did spell "check" as "Check".

seccomp_chk_filter() mirrors sk_chk_filter(). So it refers to
"chk", not "check".

>
>> +	if (ret)
>> +		goto fail;
>> +
>> +	/*
>> +	 * If there is an existing filter, make it the prev and don't drop its
>> +	 * task reference.
>> +	 */
>> +	filter->prev = current->seccomp.filter;
>> +	current->seccomp.filter = filter;
>> +	return 0;
>> +fail:
>> +	kfree(filter);
>> +	return ret;
>> +}
>> +
>>
>> ...
>>
>> +/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
>> +void put_seccomp_filter(struct task_struct *tsk)
>> +{
>> +	struct seccomp_filter *orig = tsk->seccomp.filter;
>> +	/* Clean up single-reference branches iteratively. */
>> +	while (orig && atomic_dec_and_test(&orig->usage)) {
>> +		struct seccomp_filter *freeme = orig;
>> +		orig = orig->prev;
>> +		kfree(freeme);
>> +	}
>> +}
>
> So if one of the filters in the list has an elevated refcount, we bail
> out on the remainder of the list.  Seems odd.

A bit odd yes, but fiddling with the other refcounts makes no functional
difference. You can see it as a tree of filters, with a fork at each
point any process forked, and the filters between forks having the same
life-time (added by the same process). Every process's filter list is
a path from a leaf filter to the root.

Only leaf filters get their refcount incremented at fork time, so their
refcount is always the same or higher than the refcount of the filters
before them, up to the previous fork. The intermediate filters always
have a refcount of 1, real refcounting only happens on the fork filters.
A refcount of 1 means it's an intermediate or a leaf filter, a higher
refcount means it's a fork filter.

With "proper" refcounting all the filters from the new leaf up to the
root would get their refcount incremented at fork time, but that is
wasted work, because they can be guarded by the last filter instead.

So the code bails when reaching a fork point, as it means that filter
and hence the rest of the list is shared and used by other processes.

Greetings,

Indan



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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-08 18:22       ` Indan Zupancic
  0 siblings, 0 replies; 146+ messages in thread
From: Indan Zupancic @ 2012-04-08 18:22 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Sat, April 7, 2012 06:23, Andrew Morton wrote:
> hm, I'm surprised that we don't have a zero-returning implementation of
> is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.

It's sneakily hidden at the end of compat.h.

>> +/**
>> + * get_u32 - returns a u32 offset into data
>> + * @data: a unsigned 64 bit value
>> + * @index: 0 or 1 to return the first or second 32-bits
>> + *
>> + * This inline exists to hide the length of unsigned long.
>> + * If a 32-bit unsigned long is passed in, it will be extended
>> + * and the top 32-bits will be 0. If it is a 64-bit unsigned
>> + * long, then whatever data is resident will be properly returned.
>> + */
>> +static inline u32 get_u32(u64 data, int index)
>> +{
>> +	return ((u32 *)&data)[index];
>> +}
>
> This seems utterly broken on big-endian machines.  If so: fix.  If not:
> add comment explaining why?

It's not a bug, it's intentional.

I tried to convince them to have a stable ABI for all archs, but they
didn't want to make the ABI endianness independent, because it looks
uglier. The argument being that system call numbers are arch dependent
anyway.

So a filter for a little endian arch needs to check a different offset
than one for a big endian archs.

>> +static u32 seccomp_run_filters(int syscall)
>> +{
>> +	struct seccomp_filter *f;
>> +	u32 ret = SECCOMP_RET_KILL;
>> +	/*
>> +	 * All filters are evaluated in order of youngest to oldest. The lowest
>> +	 * BPF return value always takes priority.
>> +	 */
>
> The youngest-first design surprised me.  It wasn't mentioned at all in
> the changelog.  Thinking about it, I guess it just doesn't matter.  But
> some description of the reasons for and implications of this decision
> for the uninitiated would be welcome.

I think it's less confusing to not mention the order at all, exactly
because it doesn't matter. It has been like this from the start, so
that's why it's not mentioned in the changelog I guess.

The reason to check the youngest first is because the filters are shared
between processes: childs inherit it. If later on additional filters are
added, the only way of adding them without modifying an older filter is
by adding them to the head of the list. This way no locking is needed,
because filters are only added and removed single-threadedly, and never
modified when being shared.

>> +/**
>> + * seccomp_attach_filter: Attaches a seccomp filter to current.
>> + * @fprog: BPF program to install
>> + *
>> + * Returns 0 on success or an errno on failure.
>> + */
>> +static long seccomp_attach_filter(struct sock_fprog *fprog)
>> +{
>> +	struct seccomp_filter *filter;
>> +	unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
>> +	unsigned long total_insns = fprog->len;
>> +	long ret;
>> +
>> +	if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
>> +		return -EINVAL;
>> +
>> +	for (filter = current->seccomp.filter; filter; filter = filter->prev)
>> +		total_insns += filter->len + 4;  /* include a 4 instr penalty */
>
> So tasks don't share filters?  We copy them by value at fork?  Do we do
> this at vfork() too?

Yes they do. But shared filters are never modified, except for the refcount.

>
>> +	if (total_insns > MAX_INSNS_PER_PATH)
>> +		return -ENOMEM;
>> +
>> +	/*
>> +	 * Installing a seccomp filter requires that the task have
>> +	 * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
>> +	 * This avoids scenarios where unprivileged tasks can affect the
>> +	 * behavior of privileged children.
>> +	 */
>> +	if (!current->no_new_privs &&
>> +	    security_capable_noaudit(current_cred(), current_user_ns(),
>> +				     CAP_SYS_ADMIN) != 0)
>> +		return -EACCES;
>> +
>> +	/* Allocate a new seccomp_filter */
>> +	filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
>
> I think this gives userspace an easy way of causing page allocation
> failure warnings, by permitting large kmalloc() attempts.  Add
> __GFP_NOWARN?

Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
it allocates up to 512kb before even checking the length.

What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?

>> +	/* Check and rewrite the fprog via the skb checker */
>> +	ret = sk_chk_filter(filter->insns, filter->len);
>> +	if (ret)
>> +		goto fail;
>> +
>> +	/* Check and rewrite the fprog for seccomp use */
>> +	ret = seccomp_chk_filter(filter->insns, filter->len);
>
> "check" is spelled "check"!

Yes, it is and he did spell "check" as "Check".

seccomp_chk_filter() mirrors sk_chk_filter(). So it refers to
"chk", not "check".

>
>> +	if (ret)
>> +		goto fail;
>> +
>> +	/*
>> +	 * If there is an existing filter, make it the prev and don't drop its
>> +	 * task reference.
>> +	 */
>> +	filter->prev = current->seccomp.filter;
>> +	current->seccomp.filter = filter;
>> +	return 0;
>> +fail:
>> +	kfree(filter);
>> +	return ret;
>> +}
>> +
>>
>> ...
>>
>> +/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */
>> +void put_seccomp_filter(struct task_struct *tsk)
>> +{
>> +	struct seccomp_filter *orig = tsk->seccomp.filter;
>> +	/* Clean up single-reference branches iteratively. */
>> +	while (orig && atomic_dec_and_test(&orig->usage)) {
>> +		struct seccomp_filter *freeme = orig;
>> +		orig = orig->prev;
>> +		kfree(freeme);
>> +	}
>> +}
>
> So if one of the filters in the list has an elevated refcount, we bail
> out on the remainder of the list.  Seems odd.

A bit odd yes, but fiddling with the other refcounts makes no functional
difference. You can see it as a tree of filters, with a fork at each
point any process forked, and the filters between forks having the same
life-time (added by the same process). Every process's filter list is
a path from a leaf filter to the root.

Only leaf filters get their refcount incremented at fork time, so their
refcount is always the same or higher than the refcount of the filters
before them, up to the previous fork. The intermediate filters always
have a refcount of 1, real refcounting only happens on the fork filters.
A refcount of 1 means it's an intermediate or a leaf filter, a higher
refcount means it's a fork filter.

With "proper" refcounting all the filters from the new leaf up to the
root would get their refcount incremented at fork time, but that is
wasted work, because they can be guarded by the last filter instead.

So the code bails when reaching a fork point, as it means that filter
and hence the rest of the list is shared and used by other processes.

Greetings,

Indan

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

* Re: [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering
  2012-04-06 21:28     ` Andrew Morton
  (?)
@ 2012-04-09  3:48       ` James Morris
  -1 siblings, 0 replies; 146+ messages in thread
From: James Morris @ 2012-04-09  3:48 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, Oleg Nesterov, peterz, rdunlap, mcgrathr, tglx, luto,
	eparis, serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook, Oleg Nesterov

On Fri, 6 Apr 2012, Andrew Morton wrote:

> > I've offered to take this via my tree -- if anyone else wants to merge it 
> > via theirs instead, holler.
> 
> OK by me, especially if it means that you'll carefully (re)review it!  I
> had some minor quibbles with v17.

Sure.

> 
> It would be good if Oleg could take a look at the signal changes, if he
> has not yet done so?
> 

-- 
James Morris
<jmorris@namei.org>

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

* Re: [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering
@ 2012-04-09  3:48       ` James Morris
  0 siblings, 0 replies; 146+ messages in thread
From: James Morris @ 2012-04-09  3:48 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, Oleg Nesterov, peterz, rdunlap, mcgrathr, tglx, luto,
	eparis, serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook

On Fri, 6 Apr 2012, Andrew Morton wrote:

> > I've offered to take this via my tree -- if anyone else wants to merge it 
> > via theirs instead, holler.
> 
> OK by me, especially if it means that you'll carefully (re)review it!  I
> had some minor quibbles with v17.

Sure.

> 
> It would be good if Oleg could take a look at the signal changes, if he
> has not yet done so?
> 

-- 
James Morris
<jmorris@namei.org>

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

* [kernel-hardening] Re: [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering
@ 2012-04-09  3:48       ` James Morris
  0 siblings, 0 replies; 146+ messages in thread
From: James Morris @ 2012-04-09  3:48 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, Oleg Nesterov, peterz, rdunlap, mcgrathr, tglx, luto,
	eparis, serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook

On Fri, 6 Apr 2012, Andrew Morton wrote:

> > I've offered to take this via my tree -- if anyone else wants to merge it 
> > via theirs instead, holler.
> 
> OK by me, especially if it means that you'll carefully (re)review it!  I
> had some minor quibbles with v17.

Sure.

> 
> It would be good if Oleg could take a look at the signal changes, if he
> has not yet done so?
> 

-- 
James Morris
<jmorris@namei.org>

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

* Re: [PATCH v17 10/15] seccomp: add SECCOMP_RET_ERRNO
  2012-04-06 21:19     ` [kernel-hardening] " Andrew Morton
@ 2012-04-09 19:19       ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:19 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Fri, Apr 6, 2012 at 4:19 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:55 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> This change adds the SECCOMP_RET_ERRNO as a valid return value from a
>> seccomp filter.  Additionally, it makes the first use of the lower
>> 16-bits for storing a filter-supplied errno.  16-bits is more than
>> enough for the errno-base.h calls.
>>
>> Returning errors instead of immediately terminating processes that
>> violate seccomp policy allow for broader use of this functionality
>> for kernel attack surface reduction.  For example, a linux container
>> could maintain a whitelist of pre-existing system calls but drop
>> all new ones with errnos.  This would keep a logically static attack
>> surface while providing errnos that may allow for graceful failure
>> without the downside of do_exit() on a bad call.
>>
>>
>> ...
>>
>> @@ -64,11 +65,17 @@ struct seccomp {
>>       struct seccomp_filter *filter;
>>  };
>>
>> -extern void __secure_computing(int);
>> -static inline void secure_computing(int this_syscall)
>> +/*
>> + * Direct callers to __secure_computing should be updated as
>> + * CONFIG_HAVE_ARCH_SECCOMP_FILTER propagates.
>
> Are there any such callers?  There's one I see in arm, but it's called
> from assembly code.

I think just arm, but I was trying to limit the patch growth as much
as I could, practically.  ARM support is relevant to my interests, and
I need to have patches out for review quite soon (once this series
settles :).

I hesitate to ask, but should I add a patch to this series for arm?

>> + */
>> +extern void __secure_computing(int) __deprecated;
>> +extern int __secure_computing_int(int);
>> +static inline int secure_computing(int this_syscall)
>>  {
>>       if (unlikely(test_thread_flag(TIF_SECCOMP)))
>> -             __secure_computing(this_syscall);
>> +             return  __secure_computing_int(this_syscall);
>> +     return 0;
>>  }
>>
>> ...
>>
>>  void __secure_computing(int this_syscall)
>>  {
>> +     /* Filter calls should never use this function. */
>> +     BUG_ON(current->seccomp.mode == SECCOMP_MODE_FILTER);
>> +     __secure_computing_int(this_syscall);
>> +}
>> +
>> +int __secure_computing_int(int this_syscall)
>
> What the heck does "_int" mean here?  I read it as "integer" but
> perhaps it's shorthand for "internal".  Give us a better name, please.
> Or a code comment.

It meant "returns an int", but its unclear.  I definitely will add a
comment, but I'm open to better naming.  Perhaps it'd make sense to
bring it inline with the other hook call styles:
  /* <proper comment here> */
  __secure_computing_enter(int this_syscall)

I can keep the other call as 'deprecated', and then remove it once all
the callers are updated.

I'll reply to the rest of the mails shortly - thanks!
will

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

* [kernel-hardening] Re: [PATCH v17 10/15] seccomp: add SECCOMP_RET_ERRNO
@ 2012-04-09 19:19       ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:19 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Fri, Apr 6, 2012 at 4:19 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:55 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> This change adds the SECCOMP_RET_ERRNO as a valid return value from a
>> seccomp filter.  Additionally, it makes the first use of the lower
>> 16-bits for storing a filter-supplied errno.  16-bits is more than
>> enough for the errno-base.h calls.
>>
>> Returning errors instead of immediately terminating processes that
>> violate seccomp policy allow for broader use of this functionality
>> for kernel attack surface reduction.  For example, a linux container
>> could maintain a whitelist of pre-existing system calls but drop
>> all new ones with errnos.  This would keep a logically static attack
>> surface while providing errnos that may allow for graceful failure
>> without the downside of do_exit() on a bad call.
>>
>>
>> ...
>>
>> @@ -64,11 +65,17 @@ struct seccomp {
>>       struct seccomp_filter *filter;
>>  };
>>
>> -extern void __secure_computing(int);
>> -static inline void secure_computing(int this_syscall)
>> +/*
>> + * Direct callers to __secure_computing should be updated as
>> + * CONFIG_HAVE_ARCH_SECCOMP_FILTER propagates.
>
> Are there any such callers?  There's one I see in arm, but it's called
> from assembly code.

I think just arm, but I was trying to limit the patch growth as much
as I could, practically.  ARM support is relevant to my interests, and
I need to have patches out for review quite soon (once this series
settles :).

I hesitate to ask, but should I add a patch to this series for arm?

>> + */
>> +extern void __secure_computing(int) __deprecated;
>> +extern int __secure_computing_int(int);
>> +static inline int secure_computing(int this_syscall)
>>  {
>>       if (unlikely(test_thread_flag(TIF_SECCOMP)))
>> -             __secure_computing(this_syscall);
>> +             return  __secure_computing_int(this_syscall);
>> +     return 0;
>>  }
>>
>> ...
>>
>>  void __secure_computing(int this_syscall)
>>  {
>> +     /* Filter calls should never use this function. */
>> +     BUG_ON(current->seccomp.mode == SECCOMP_MODE_FILTER);
>> +     __secure_computing_int(this_syscall);
>> +}
>> +
>> +int __secure_computing_int(int this_syscall)
>
> What the heck does "_int" mean here?  I read it as "integer" but
> perhaps it's shorthand for "internal".  Give us a better name, please.
> Or a code comment.

It meant "returns an int", but its unclear.  I definitely will add a
comment, but I'm open to better naming.  Perhaps it'd make sense to
bring it inline with the other hook call styles:
  /* <proper comment here> */
  __secure_computing_enter(int this_syscall)

I can keep the other call as 'deprecated', and then remove it once all
the callers are updated.

I'll reply to the rest of the mails shortly - thanks!
will

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

* Re: [PATCH v17 07/15] asm/syscall.h: add syscall_get_arch
  2012-04-06 20:05     ` [kernel-hardening] " Andrew Morton
@ 2012-04-09 19:24       ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:24 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Fri, Apr 6, 2012 at 3:05 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:52 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> Adds a stub for a function that will return the AUDIT_ARCH_*
>> value appropriate to the supplied task based on the system
>> call convention.
>>
>> For audit's use, the value can generally be hard-coded at the
>> audit-site.  However, for other functionality not inlined into
>> syscall entry/exit, this makes that information available.
>> seccomp_filter is the first planned consumer and, as such,
>> the comment indicates a tie to HAVE_ARCH_SECCOMP_FILTER.  That
>
> Should be "CONFIG_HAVE_ARCH_SECCOMP_FILTER", I hope.

yes!

>
>> is probably an unneeded detail.
>>
>> ...
>>
>> --- a/include/asm-generic/syscall.h
>> +++ b/include/asm-generic/syscall.h
>> @@ -142,4 +142,18 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
>>                          unsigned int i, unsigned int n,
>>                          const unsigned long *args);
>>
>> +/**
>> + * syscall_get_arch - return the AUDIT_ARCH for the current system call
>> + * @task:    task of interest, must be in system call entry tracing
>> + * @regs:    task_pt_regs() of @task
>> + *
>> + * Returns the AUDIT_ARCH_* based on the system call convention in use.
>> + *
>> + * It's only valid to call this when @task is stopped on entry to a system
>> + * call, due to %TIF_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or %TIF_SECCOMP.
>> + *
>> + * Note, at present this function is only required with
>> + * CONFIG_HAVE_ARCH_SECCOMP_FILTER.
>> + */
>> +int syscall_get_arch(struct task_struct *task, struct pt_regs *regs);
>>  #endif       /* _ASM_SYSCALL_H */
>
> So architectures which permit CONFIG_HAVE_ARCH_SECCOMP_FILTER must
> provide an implementation of this.

Much better wording.

In practice, many of the existing places that audit arch is needed
already know the calling convention because they happen in asm or have
hardcoded values.  It may be that other consumers may want this
information later, like ftrace, but I'm not sure of any that will
immediately benefit from it right now.

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

* [kernel-hardening] Re: [PATCH v17 07/15] asm/syscall.h: add syscall_get_arch
@ 2012-04-09 19:24       ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:24 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Fri, Apr 6, 2012 at 3:05 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:52 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> Adds a stub for a function that will return the AUDIT_ARCH_*
>> value appropriate to the supplied task based on the system
>> call convention.
>>
>> For audit's use, the value can generally be hard-coded at the
>> audit-site.  However, for other functionality not inlined into
>> syscall entry/exit, this makes that information available.
>> seccomp_filter is the first planned consumer and, as such,
>> the comment indicates a tie to HAVE_ARCH_SECCOMP_FILTER.  That
>
> Should be "CONFIG_HAVE_ARCH_SECCOMP_FILTER", I hope.

yes!

>
>> is probably an unneeded detail.
>>
>> ...
>>
>> --- a/include/asm-generic/syscall.h
>> +++ b/include/asm-generic/syscall.h
>> @@ -142,4 +142,18 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
>>                          unsigned int i, unsigned int n,
>>                          const unsigned long *args);
>>
>> +/**
>> + * syscall_get_arch - return the AUDIT_ARCH for the current system call
>> + * @task:    task of interest, must be in system call entry tracing
>> + * @regs:    task_pt_regs() of @task
>> + *
>> + * Returns the AUDIT_ARCH_* based on the system call convention in use.
>> + *
>> + * It's only valid to call this when @task is stopped on entry to a system
>> + * call, due to %TIF_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or %TIF_SECCOMP.
>> + *
>> + * Note, at present this function is only required with
>> + * CONFIG_HAVE_ARCH_SECCOMP_FILTER.
>> + */
>> +int syscall_get_arch(struct task_struct *task, struct pt_regs *regs);
>>  #endif       /* _ASM_SYSCALL_H */
>
> So architectures which permit CONFIG_HAVE_ARCH_SECCOMP_FILTER must
> provide an implementation of this.

Much better wording.

In practice, many of the existing places that audit arch is needed
already know the calling convention because they happen in asm or have
hardcoded values.  It may be that other consumers may want this
information later, like ftrace, but I'm not sure of any that will
immediately benefit from it right now.

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

* Re: [PATCH v17 09/15] seccomp: remove duplicated failure logging
  2012-04-06 21:14     ` [kernel-hardening] " Andrew Morton
  (?)
@ 2012-04-09 19:26       ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:26 UTC (permalink / raw)
  To: Andrew Morton, Kees Cook, Eric Paris
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	jmorris

On Fri, Apr 6, 2012 at 4:14 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:54 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Kees Cook <keescook@chromium.org>
>>
>> This consolidates the seccomp filter error logging path and adds more
>> details to the audit log.
>>
>> ...
>>
>> --- a/include/linux/audit.h
>> +++ b/include/linux/audit.h
>>
>> ...
>>
>>  #define audit_inode(n,d) do { (void)(d); } while (0)
>>  #define audit_inode_child(i,p) do { ; } while (0)
>>  #define audit_core_dumps(i) do { ; } while (0)
>> -#define audit_seccomp(i) do { ; } while (0)
>> +#define audit_seccomp(i,s,c) do { ; } while (0)
>
> Sigh.  Someone please convert all these to C.  That way we get
> typechecking and don't need dopey party tricks like that "(void)(d)" to
> squish compilation warnings.
>
>> ...
>> --- a/kernel/auditsc.c
>> +++ b/kernel/auditsc.c
>> @@ -67,6 +67,7 @@
>>  #include <linux/syscalls.h>
>>  #include <linux/capability.h>
>>  #include <linux/fs_struct.h>
>> +#include <linux/compat.h>
>>
>>  #include "audit.h"
>>
>> @@ -2710,13 +2711,18 @@ void audit_core_dumps(long signr)
>>       audit_log_end(ab);
>>  }
>>
>> -void __audit_seccomp(unsigned long syscall)
>> +void __audit_seccomp(unsigned long syscall, long signr, int code)
>>  {
>>       struct audit_buffer *ab;
>>
>>       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
>> -     audit_log_abend(ab, "seccomp", SIGKILL);
>> +     audit_log_abend(ab, "seccomp", signr);
>>       audit_log_format(ab, " syscall=%ld", syscall);
>> +#ifdef CONFIG_COMPAT
>> +     audit_log_format(ab, " compat=%d", is_compat_task());
>> +#endif
>
> We don't need the ifdef for compilation reasons now.
>
> The question is: should we emit the compat= record on
> non-compat-capable architectures?  Doing so would be safer - making it
> conditional invites people to write x86-only usersapce.

I'd certainly prefer it always being there for exactly that reason.

Kees, Eric, any preferences?  Unless I hear one, I'll just drop the
ifdefs in the next revision.

thanks!

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

* Re: [PATCH v17 09/15] seccomp: remove duplicated failure logging
@ 2012-04-09 19:26       ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:26 UTC (permalink / raw)
  To: Andrew Morton, Kees Cook, Eric Paris
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	jmorris

On Fri, Apr 6, 2012 at 4:14 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:54 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Kees Cook <keescook@chromium.org>
>>
>> This consolidates the seccomp filter error logging path and adds more
>> details to the audit log.
>>
>> ...
>>
>> --- a/include/linux/audit.h
>> +++ b/include/linux/audit.h
>>
>> ...
>>
>>  #define audit_inode(n,d) do { (void)(d); } while (0)
>>  #define audit_inode_child(i,p) do { ; } while (0)
>>  #define audit_core_dumps(i) do { ; } while (0)
>> -#define audit_seccomp(i) do { ; } while (0)
>> +#define audit_seccomp(i,s,c) do { ; } while (0)
>
> Sigh.  Someone please convert all these to C.  That way we get
> typechecking and don't need dopey party tricks like that "(void)(d)" to
> squish compilation warnings.
>
>> ...
>> --- a/kernel/auditsc.c
>> +++ b/kernel/auditsc.c
>> @@ -67,6 +67,7 @@
>>  #include <linux/syscalls.h>
>>  #include <linux/capability.h>
>>  #include <linux/fs_struct.h>
>> +#include <linux/compat.h>
>>
>>  #include "audit.h"
>>
>> @@ -2710,13 +2711,18 @@ void audit_core_dumps(long signr)
>>       audit_log_end(ab);
>>  }
>>
>> -void __audit_seccomp(unsigned long syscall)
>> +void __audit_seccomp(unsigned long syscall, long signr, int code)
>>  {
>>       struct audit_buffer *ab;
>>
>>       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
>> -     audit_log_abend(ab, "seccomp", SIGKILL);
>> +     audit_log_abend(ab, "seccomp", signr);
>>       audit_log_format(ab, " syscall=%ld", syscall);
>> +#ifdef CONFIG_COMPAT
>> +     audit_log_format(ab, " compat=%d", is_compat_task());
>> +#endif
>
> We don't need the ifdef for compilation reasons now.
>
> The question is: should we emit the compat= record on
> non-compat-capable architectures?  Doing so would be safer - making it
> conditional invites people to write x86-only usersapce.

I'd certainly prefer it always being there for exactly that reason.

Kees, Eric, any preferences?  Unless I hear one, I'll just drop the
ifdefs in the next revision.

thanks!
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [kernel-hardening] Re: [PATCH v17 09/15] seccomp: remove duplicated failure logging
@ 2012-04-09 19:26       ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:26 UTC (permalink / raw)
  To: Andrew Morton, Kees Cook, Eric Paris
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	jmorris

On Fri, Apr 6, 2012 at 4:14 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:54 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Kees Cook <keescook@chromium.org>
>>
>> This consolidates the seccomp filter error logging path and adds more
>> details to the audit log.
>>
>> ...
>>
>> --- a/include/linux/audit.h
>> +++ b/include/linux/audit.h
>>
>> ...
>>
>>  #define audit_inode(n,d) do { (void)(d); } while (0)
>>  #define audit_inode_child(i,p) do { ; } while (0)
>>  #define audit_core_dumps(i) do { ; } while (0)
>> -#define audit_seccomp(i) do { ; } while (0)
>> +#define audit_seccomp(i,s,c) do { ; } while (0)
>
> Sigh.  Someone please convert all these to C.  That way we get
> typechecking and don't need dopey party tricks like that "(void)(d)" to
> squish compilation warnings.
>
>> ...
>> --- a/kernel/auditsc.c
>> +++ b/kernel/auditsc.c
>> @@ -67,6 +67,7 @@
>>  #include <linux/syscalls.h>
>>  #include <linux/capability.h>
>>  #include <linux/fs_struct.h>
>> +#include <linux/compat.h>
>>
>>  #include "audit.h"
>>
>> @@ -2710,13 +2711,18 @@ void audit_core_dumps(long signr)
>>       audit_log_end(ab);
>>  }
>>
>> -void __audit_seccomp(unsigned long syscall)
>> +void __audit_seccomp(unsigned long syscall, long signr, int code)
>>  {
>>       struct audit_buffer *ab;
>>
>>       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
>> -     audit_log_abend(ab, "seccomp", SIGKILL);
>> +     audit_log_abend(ab, "seccomp", signr);
>>       audit_log_format(ab, " syscall=%ld", syscall);
>> +#ifdef CONFIG_COMPAT
>> +     audit_log_format(ab, " compat=%d", is_compat_task());
>> +#endif
>
> We don't need the ifdef for compilation reasons now.
>
> The question is: should we emit the compat= record on
> non-compat-capable architectures?  Doing so would be safer - making it
> conditional invites people to write x86-only usersapce.

I'd certainly prefer it always being there for exactly that reason.

Kees, Eric, any preferences?  Unless I hear one, I'll just drop the
ifdefs in the next revision.

thanks!

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

* Re: [PATCH v17 09/15] seccomp: remove duplicated failure logging
  2012-04-09 19:26       ` Will Drewry
@ 2012-04-09 19:32         ` Kees Cook
  -1 siblings, 0 replies; 146+ messages in thread
From: Kees Cook @ 2012-04-09 19:32 UTC (permalink / raw)
  To: Will Drewry
  Cc: Andrew Morton, Eric Paris, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On Mon, Apr 9, 2012 at 12:26 PM, Will Drewry <wad@chromium.org> wrote:
> On Fri, Apr 6, 2012 at 4:14 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
>> On Thu, 29 Mar 2012 15:01:54 -0500
>> Will Drewry <wad@chromium.org> wrote:
>>
>>> From: Kees Cook <keescook@chromium.org>
>>>
>>> This consolidates the seccomp filter error logging path and adds more
>>> details to the audit log.
>>>
>>> ...
>>>
>>> -void __audit_seccomp(unsigned long syscall)
>>> +void __audit_seccomp(unsigned long syscall, long signr, int code)
>>>  {
>>>       struct audit_buffer *ab;
>>>
>>>       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
>>> -     audit_log_abend(ab, "seccomp", SIGKILL);
>>> +     audit_log_abend(ab, "seccomp", signr);
>>>       audit_log_format(ab, " syscall=%ld", syscall);
>>> +#ifdef CONFIG_COMPAT
>>> +     audit_log_format(ab, " compat=%d", is_compat_task());
>>> +#endif
>>
>> We don't need the ifdef for compilation reasons now.
>>
>> The question is: should we emit the compat= record on
>> non-compat-capable architectures?  Doing so would be safer - making it
>> conditional invites people to write x86-only usersapce.
>
> I'd certainly prefer it always being there for exactly that reason.
>
> Kees, Eric, any preferences?  Unless I hear one, I'll just drop the
> ifdefs in the next revision.

Yeah, I'd prefer the ifdefs dropped too.

-Kees

-- 
Kees Cook
ChromeOS Security

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

* [kernel-hardening] Re: [PATCH v17 09/15] seccomp: remove duplicated failure logging
@ 2012-04-09 19:32         ` Kees Cook
  0 siblings, 0 replies; 146+ messages in thread
From: Kees Cook @ 2012-04-09 19:32 UTC (permalink / raw)
  To: Will Drewry
  Cc: Andrew Morton, Eric Paris, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On Mon, Apr 9, 2012 at 12:26 PM, Will Drewry <wad@chromium.org> wrote:
> On Fri, Apr 6, 2012 at 4:14 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
>> On Thu, 29 Mar 2012 15:01:54 -0500
>> Will Drewry <wad@chromium.org> wrote:
>>
>>> From: Kees Cook <keescook@chromium.org>
>>>
>>> This consolidates the seccomp filter error logging path and adds more
>>> details to the audit log.
>>>
>>> ...
>>>
>>> -void __audit_seccomp(unsigned long syscall)
>>> +void __audit_seccomp(unsigned long syscall, long signr, int code)
>>>  {
>>>       struct audit_buffer *ab;
>>>
>>>       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
>>> -     audit_log_abend(ab, "seccomp", SIGKILL);
>>> +     audit_log_abend(ab, "seccomp", signr);
>>>       audit_log_format(ab, " syscall=%ld", syscall);
>>> +#ifdef CONFIG_COMPAT
>>> +     audit_log_format(ab, " compat=%d", is_compat_task());
>>> +#endif
>>
>> We don't need the ifdef for compilation reasons now.
>>
>> The question is: should we emit the compat= record on
>> non-compat-capable architectures?  Doing so would be safer - making it
>> conditional invites people to write x86-only usersapce.
>
> I'd certainly prefer it always being there for exactly that reason.
>
> Kees, Eric, any preferences?  Unless I hear one, I'll just drop the
> ifdefs in the next revision.

Yeah, I'd prefer the ifdefs dropped too.

-Kees

-- 
Kees Cook
ChromeOS Security

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

* Re: [kernel-hardening] Re: [PATCH v17 09/15] seccomp: remove duplicated failure logging
  2012-04-09 19:26       ` Will Drewry
@ 2012-04-09 19:33         ` Eric Paris
  -1 siblings, 0 replies; 146+ messages in thread
From: Eric Paris @ 2012-04-09 19:33 UTC (permalink / raw)
  To: kernel-hardening
  Cc: Andrew Morton, Kees Cook, linux-kernel, linux-security-module,
	linux-arch, linux-doc, netdev, x86, arnd, davem, hpa, mingo,
	oleg, peterz, rdunlap, mcgrathr, tglx, luto, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	jmorris

On Mon, 2012-04-09 at 14:26 -0500, Will Drewry wrote:
> On Fri, Apr 6, 2012 at 4:14 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> > On Thu, 29 Mar 2012 15:01:54 -0500
> > Will Drewry <wad@chromium.org> wrote:

> >> -void __audit_seccomp(unsigned long syscall)
> >> +void __audit_seccomp(unsigned long syscall, long signr, int code)
> >>  {
> >>       struct audit_buffer *ab;
> >>
> >>       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
> >> -     audit_log_abend(ab, "seccomp", SIGKILL);
> >> +     audit_log_abend(ab, "seccomp", signr);
> >>       audit_log_format(ab, " syscall=%ld", syscall);
> >> +#ifdef CONFIG_COMPAT
> >> +     audit_log_format(ab, " compat=%d", is_compat_task());
> >> +#endif
> >
> > We don't need the ifdef for compilation reasons now.
> >
> > The question is: should we emit the compat= record on
> > non-compat-capable architectures?  Doing so would be safer - making it
> > conditional invites people to write x86-only usersapce.
> 
> I'd certainly prefer it always being there for exactly that reason.
> 
> Kees, Eric, any preferences?  Unless I hear one, I'll just drop the
> ifdefs in the next revision.

I'd just leave it in unconditionally.  The audit parse libraries would
handle it just fine, but that doesn't mean everyone uses that tool to
parse the text.

-Eric


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

* Re: Re: [PATCH v17 09/15] seccomp: remove duplicated failure logging
@ 2012-04-09 19:33         ` Eric Paris
  0 siblings, 0 replies; 146+ messages in thread
From: Eric Paris @ 2012-04-09 19:33 UTC (permalink / raw)
  To: kernel-hardening
  Cc: Andrew Morton, Kees Cook, linux-kernel, linux-security-module,
	linux-arch, linux-doc, netdev, x86, arnd, davem, hpa, mingo,
	oleg, peterz, rdunlap, mcgrathr, tglx, luto, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	jmorris

On Mon, 2012-04-09 at 14:26 -0500, Will Drewry wrote:
> On Fri, Apr 6, 2012 at 4:14 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> > On Thu, 29 Mar 2012 15:01:54 -0500
> > Will Drewry <wad@chromium.org> wrote:

> >> -void __audit_seccomp(unsigned long syscall)
> >> +void __audit_seccomp(unsigned long syscall, long signr, int code)
> >>  {
> >>       struct audit_buffer *ab;
> >>
> >>       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
> >> -     audit_log_abend(ab, "seccomp", SIGKILL);
> >> +     audit_log_abend(ab, "seccomp", signr);
> >>       audit_log_format(ab, " syscall=%ld", syscall);
> >> +#ifdef CONFIG_COMPAT
> >> +     audit_log_format(ab, " compat=%d", is_compat_task());
> >> +#endif
> >
> > We don't need the ifdef for compilation reasons now.
> >
> > The question is: should we emit the compat= record on
> > non-compat-capable architectures?  Doing so would be safer - making it
> > conditional invites people to write x86-only usersapce.
> 
> I'd certainly prefer it always being there for exactly that reason.
> 
> Kees, Eric, any preferences?  Unless I hear one, I'll just drop the
> ifdefs in the next revision.

I'd just leave it in unconditionally.  The audit parse libraries would
handle it just fine, but that doesn't mean everyone uses that tool to
parse the text.

-Eric

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

* Re: [PATCH v17 13/15] ptrace,seccomp: Add PTRACE_SECCOMP support
  2012-04-06 21:24     ` [kernel-hardening] " Andrew Morton
@ 2012-04-09 19:38       ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:38 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Fri, Apr 6, 2012 at 4:24 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:58 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> This change adds support for a new ptrace option, PTRACE_O_TRACESECCOMP,
>> and a new return value for seccomp BPF programs, SECCOMP_RET_TRACE.
>>
>> When a tracer specifies the PTRACE_O_TRACESECCOMP ptrace option, the
>> tracer will be notified, via PTRACE_EVENT_SECCOMP, for any syscall that
>> results in a BPF program returning SECCOMP_RET_TRACE.  The 16-bit
>> SECCOMP_RET_DATA mask of the BPF program return value will be passed as
>> the ptrace_message and may be retrieved using PTRACE_GETEVENTMSG.
>>
>> If the subordinate process is not using seccomp filter, then no
>> system call notifications will occur even if the option is specified.
>>
>> If there is no tracer with PTRACE_O_TRACESECCOMP when SECCOMP_RET_TRACE
>> is returned, the system call will not be executed and an -ENOSYS errno
>> will be returned to userspace.
>>
>> This change adds a dependency on the system call slow path.  Any future
>> efforts to use the system call fast path for seccomp filter will need to
>> address this restriction.
>>
>>
>> ...
>>
>> @@ -410,6 +411,15 @@ int __secure_computing_int(int this_syscall)
>>                       /* Let the filter pass back 16 bits of data. */
>>                       seccomp_send_sigsys(this_syscall, data);
>>                       goto skip;
>> +             case SECCOMP_RET_TRACE:
>> +                     /* Skip these calls if there is no tracer. */
>> +                     if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP))
>> +                             goto skip;
>> +                     /* Allow the BPF to provide the event message */
>> +                     ptrace_event(PTRACE_EVENT_SECCOMP, data);
>> +                     if (fatal_signal_pending(current))
>> +                             break;
>
> I don't have all the patches applied here so the context is missing.
> Perhaps tht would help me understand what this fatal_signal_pending()
> test is doing here.  But an explanatory comment wouldn't hurt.

I'll add a comment along the lines of my answer below!

> What *is* it here for, anyway?

The timely delivery of a fatal signal will silently block tracer event
notification.  By immediately terminating if a fatal signal is
pending, we avoid accidentally executing a system call that the tracer
did not approve of.

http://lxr.linux.no/linux+v3.3.1/kernel/signal.c#L1839

I can be more verbose, but hopefully that covers it well enough - thanks!

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

* [kernel-hardening] Re: [PATCH v17 13/15] ptrace,seccomp: Add PTRACE_SECCOMP support
@ 2012-04-09 19:38       ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:38 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Fri, Apr 6, 2012 at 4:24 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:58 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> This change adds support for a new ptrace option, PTRACE_O_TRACESECCOMP,
>> and a new return value for seccomp BPF programs, SECCOMP_RET_TRACE.
>>
>> When a tracer specifies the PTRACE_O_TRACESECCOMP ptrace option, the
>> tracer will be notified, via PTRACE_EVENT_SECCOMP, for any syscall that
>> results in a BPF program returning SECCOMP_RET_TRACE.  The 16-bit
>> SECCOMP_RET_DATA mask of the BPF program return value will be passed as
>> the ptrace_message and may be retrieved using PTRACE_GETEVENTMSG.
>>
>> If the subordinate process is not using seccomp filter, then no
>> system call notifications will occur even if the option is specified.
>>
>> If there is no tracer with PTRACE_O_TRACESECCOMP when SECCOMP_RET_TRACE
>> is returned, the system call will not be executed and an -ENOSYS errno
>> will be returned to userspace.
>>
>> This change adds a dependency on the system call slow path.  Any future
>> efforts to use the system call fast path for seccomp filter will need to
>> address this restriction.
>>
>>
>> ...
>>
>> @@ -410,6 +411,15 @@ int __secure_computing_int(int this_syscall)
>>                       /* Let the filter pass back 16 bits of data. */
>>                       seccomp_send_sigsys(this_syscall, data);
>>                       goto skip;
>> +             case SECCOMP_RET_TRACE:
>> +                     /* Skip these calls if there is no tracer. */
>> +                     if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP))
>> +                             goto skip;
>> +                     /* Allow the BPF to provide the event message */
>> +                     ptrace_event(PTRACE_EVENT_SECCOMP, data);
>> +                     if (fatal_signal_pending(current))
>> +                             break;
>
> I don't have all the patches applied here so the context is missing.
> Perhaps tht would help me understand what this fatal_signal_pending()
> test is doing here.  But an explanatory comment wouldn't hurt.

I'll add a comment along the lines of my answer below!

> What *is* it here for, anyway?

The timely delivery of a fatal signal will silently block tracer event
notification.  By immediately terminating if a fatal signal is
pending, we avoid accidentally executing a system call that the tracer
did not approve of.

http://lxr.linux.no/linux+v3.3.1/kernel/signal.c#L1839

I can be more verbose, but hopefully that covers it well enough - thanks!

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

* Re: [kernel-hardening] Re: [PATCH v17 09/15] seccomp: remove duplicated failure logging
  2012-04-09 19:33         ` Eric Paris
@ 2012-04-09 19:39           ` Kees Cook
  -1 siblings, 0 replies; 146+ messages in thread
From: Kees Cook @ 2012-04-09 19:39 UTC (permalink / raw)
  To: Eric Paris
  Cc: kernel-hardening, Andrew Morton, linux-kernel,
	linux-security-module, linux-arch, linux-doc, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On Mon, Apr 9, 2012 at 12:33 PM, Eric Paris <eparis@redhat.com> wrote:
> On Mon, 2012-04-09 at 14:26 -0500, Will Drewry wrote:
>> On Fri, Apr 6, 2012 at 4:14 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
>> > On Thu, 29 Mar 2012 15:01:54 -0500
>> > Will Drewry <wad@chromium.org> wrote:
>
>> >> -void __audit_seccomp(unsigned long syscall)
>> >> +void __audit_seccomp(unsigned long syscall, long signr, int code)
>> >>  {
>> >>       struct audit_buffer *ab;
>> >>
>> >>       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
>> >> -     audit_log_abend(ab, "seccomp", SIGKILL);
>> >> +     audit_log_abend(ab, "seccomp", signr);
>> >>       audit_log_format(ab, " syscall=%ld", syscall);
>> >> +#ifdef CONFIG_COMPAT
>> >> +     audit_log_format(ab, " compat=%d", is_compat_task());
>> >> +#endif
>> >
>> > We don't need the ifdef for compilation reasons now.
>> >
>> > The question is: should we emit the compat= record on
>> > non-compat-capable architectures?  Doing so would be safer - making it
>> > conditional invites people to write x86-only usersapce.
>>
>> I'd certainly prefer it always being there for exactly that reason.
>>
>> Kees, Eric, any preferences?  Unless I hear one, I'll just drop the
>> ifdefs in the next revision.
>
> I'd just leave it in unconditionally.  The audit parse libraries would
> handle it just fine, but that doesn't mean everyone uses that tool to
> parse the text.

Related to this, can we get this patch into a tree as well?
https://lkml.org/lkml/2012/3/23/332

Thanks,

-Kees

-- 
Kees Cook
ChromeOS Security

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

* Re: [kernel-hardening] Re: [PATCH v17 09/15] seccomp: remove duplicated failure logging
@ 2012-04-09 19:39           ` Kees Cook
  0 siblings, 0 replies; 146+ messages in thread
From: Kees Cook @ 2012-04-09 19:39 UTC (permalink / raw)
  To: Eric Paris
  Cc: kernel-hardening, Andrew Morton, linux-kernel,
	linux-security-module, linux-arch, linux-doc, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, jmorris

On Mon, Apr 9, 2012 at 12:33 PM, Eric Paris <eparis@redhat.com> wrote:
> On Mon, 2012-04-09 at 14:26 -0500, Will Drewry wrote:
>> On Fri, Apr 6, 2012 at 4:14 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
>> > On Thu, 29 Mar 2012 15:01:54 -0500
>> > Will Drewry <wad@chromium.org> wrote:
>
>> >> -void __audit_seccomp(unsigned long syscall)
>> >> +void __audit_seccomp(unsigned long syscall, long signr, int code)
>> >>  {
>> >>       struct audit_buffer *ab;
>> >>
>> >>       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
>> >> -     audit_log_abend(ab, "seccomp", SIGKILL);
>> >> +     audit_log_abend(ab, "seccomp", signr);
>> >>       audit_log_format(ab, " syscall=%ld", syscall);
>> >> +#ifdef CONFIG_COMPAT
>> >> +     audit_log_format(ab, " compat=%d", is_compat_task());
>> >> +#endif
>> >
>> > We don't need the ifdef for compilation reasons now.
>> >
>> > The question is: should we emit the compat= record on
>> > non-compat-capable architectures?  Doing so would be safer - making it
>> > conditional invites people to write x86-only usersapce.
>>
>> I'd certainly prefer it always being there for exactly that reason.
>>
>> Kees, Eric, any preferences?  Unless I hear one, I'll just drop the
>> ifdefs in the next revision.
>
> I'd just leave it in unconditionally.  The audit parse libraries would
> handle it just fine, but that doesn't mean everyone uses that tool to
> parse the text.

Related to this, can we get this patch into a tree as well?
https://lkml.org/lkml/2012/3/23/332

Thanks,

-Kees

-- 
Kees Cook
ChromeOS Security
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
  2012-04-06 21:26     ` [kernel-hardening] " Andrew Morton
@ 2012-04-09 19:46       ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:46 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Fri, Apr 6, 2012 at 4:26 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:02:00 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> Documents how system call filtering using Berkeley Packet
>> Filter programs works and how it may be used.
>> Includes an example for x86 and a semi-generic
>> example using a macro-based code generator.
>>
>>
>> ...
>>
>> +Adding architecture support
>> +-----------------------
>> +
>> +See arch/Kconfig for the authoritative requirements.  In general, if an
>> +architecture supports both ptrace_event and seccomp, it will be able to
>> +support seccomp filter with minor fixup: SIGSYS support and seccomp return
>> +value checking.  Then it must just add CONFIG_HAVE_ARCH_SECCOMP_FILTER
>> +to its arch-specific Kconfig.
>> diff --git a/samples/Makefile b/samples/Makefile
>> index 2f75851..5ef08bb 100644
>> --- a/samples/Makefile
>> +++ b/samples/Makefile
>
> Oh good, I was going to ask about that.
>
> Can we get this code into tools/testing/selftests?  That way people
> will run it more often and it's more likely to be maintained as the
> code evolves.

I'm currently using a lightweight testsuite in addition to the
samples.  It's a little more oriented at pass/fail behavior.  Would it
be more appropriate to post those in addition to, or instead of,
samples?

thanks!

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

* [kernel-hardening] Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
@ 2012-04-09 19:46       ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:46 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris

On Fri, Apr 6, 2012 at 4:26 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:02:00 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> Documents how system call filtering using Berkeley Packet
>> Filter programs works and how it may be used.
>> Includes an example for x86 and a semi-generic
>> example using a macro-based code generator.
>>
>>
>> ...
>>
>> +Adding architecture support
>> +-----------------------
>> +
>> +See arch/Kconfig for the authoritative requirements.  In general, if an
>> +architecture supports both ptrace_event and seccomp, it will be able to
>> +support seccomp filter with minor fixup: SIGSYS support and seccomp return
>> +value checking.  Then it must just add CONFIG_HAVE_ARCH_SECCOMP_FILTER
>> +to its arch-specific Kconfig.
>> diff --git a/samples/Makefile b/samples/Makefile
>> index 2f75851..5ef08bb 100644
>> --- a/samples/Makefile
>> +++ b/samples/Makefile
>
> Oh good, I was going to ask about that.
>
> Can we get this code into tools/testing/selftests?  That way people
> will run it more often and it's more likely to be maintained as the
> code evolves.

I'm currently using a lightweight testsuite in addition to the
samples.  It's a little more oriented at pass/fail behavior.  Would it
be more appropriate to post those in addition to, or instead of,
samples?

thanks!

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-08 18:22       ` [kernel-hardening] " Indan Zupancic
@ 2012-04-09 19:59         ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:59 UTC (permalink / raw)
  To: Indan Zupancic
  Cc: Andrew Morton, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Sun, Apr 8, 2012 at 1:22 PM, Indan Zupancic <indan@nul.nu> wrote:
> On Sat, April 7, 2012 06:23, Andrew Morton wrote:
>> hm, I'm surprised that we don't have a zero-returning implementation of
>> is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
>
> It's sneakily hidden at the end of compat.h.
>
>>> +/**
>>> + * get_u32 - returns a u32 offset into data
>>> + * @data: a unsigned 64 bit value
>>> + * @index: 0 or 1 to return the first or second 32-bits
>>> + *
>>> + * This inline exists to hide the length of unsigned long.
>>> + * If a 32-bit unsigned long is passed in, it will be extended
>>> + * and the top 32-bits will be 0. If it is a 64-bit unsigned
>>> + * long, then whatever data is resident will be properly returned.
>>> + */
>>> +static inline u32 get_u32(u64 data, int index)
>>> +{
>>> +    return ((u32 *)&data)[index];
>>> +}
>>
>> This seems utterly broken on big-endian machines.  If so: fix.  If not:
>> add comment explaining why?
>
> It's not a bug, it's intentional.
>
> I tried to convince them to have a stable ABI for all archs, but they
> didn't want to make the ABI endianness independent, because it looks
> uglier. The argument being that system call numbers are arch dependent
> anyway.
>
> So a filter for a little endian arch needs to check a different offset
> than one for a big endian archs.

Awkward, but in practice it doesn't seem to matter either way --
especially since properly written filters should check the @arch which
indicates the calling convention, endianness, etc.

>>> +static u32 seccomp_run_filters(int syscall)
>>> +{
>>> +    struct seccomp_filter *f;
>>> +    u32 ret = SECCOMP_RET_KILL;
>>> +    /*
>>> +     * All filters are evaluated in order of youngest to oldest. The lowest
>>> +     * BPF return value always takes priority.
>>> +     */
>>
>> The youngest-first design surprised me.  It wasn't mentioned at all in
>> the changelog.  Thinking about it, I guess it just doesn't matter.  But
>> some description of the reasons for and implications of this decision
>> for the uninitiated would be welcome.
>
> I think it's less confusing to not mention the order at all, exactly
> because it doesn't matter. It has been like this from the start, so
> that's why it's not mentioned in the changelog I guess.

Good call - I will remove that comment.  The only relevant information
is that the lowest return value wins.  I did add a comment up near
struct seccomp_filter with my attempt at explaining the tree
structure, but I didn't detail evaluation order.  In this case, it
only is relevant because our only link to the tree is via our local
pointer which happens to be the "youngest".

> The reason to check the youngest first is because the filters are shared
> between processes: childs inherit it. If later on additional filters are
> added, the only way of adding them without modifying an older filter is
> by adding them to the head of the list. This way no locking is needed,
> because filters are only added and removed single-threadedly, and never
> modified when being shared.

I tried a handful of other strategies, but in practice this seemed to
meet the needs with the least complexity/overhead.

>>> +/**
>>> + * seccomp_attach_filter: Attaches a seccomp filter to current.
>>> + * @fprog: BPF program to install
>>> + *
>>> + * Returns 0 on success or an errno on failure.
>>> + */
>>> +static long seccomp_attach_filter(struct sock_fprog *fprog)
>>> +{
>>> +    struct seccomp_filter *filter;
>>> +    unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
>>> +    unsigned long total_insns = fprog->len;
>>> +    long ret;
>>> +
>>> +    if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
>>> +            return -EINVAL;
>>> +
>>> +    for (filter = current->seccomp.filter; filter; filter = filter->prev)
>>> +            total_insns += filter->len + 4;  /* include a 4 instr penalty */
>>
>> So tasks don't share filters?  We copy them by value at fork?  Do we do
>> this at vfork() too?
>
> Yes they do. But shared filters are never modified, except for the refcount.
>
>>
>>> +    if (total_insns > MAX_INSNS_PER_PATH)
>>> +            return -ENOMEM;
>>> +
>>> +    /*
>>> +     * Installing a seccomp filter requires that the task have
>>> +     * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
>>> +     * This avoids scenarios where unprivileged tasks can affect the
>>> +     * behavior of privileged children.
>>> +     */
>>> +    if (!current->no_new_privs &&
>>> +        security_capable_noaudit(current_cred(), current_user_ns(),
>>> +                                 CAP_SYS_ADMIN) != 0)
>>> +            return -EACCES;
>>> +
>>> +    /* Allocate a new seccomp_filter */
>>> +    filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
>>
>> I think this gives userspace an easy way of causing page allocation
>> failure warnings, by permitting large kmalloc() attempts.  Add
>> __GFP_NOWARN?
>
> Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
> it allocates up to 512kb before even checking the length.
>
> What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?

It looks like GFP_USER|__GFP_NOWARN would make sense here.  I'll change it.

>>> +    /* Check and rewrite the fprog via the skb checker */
>>> +    ret = sk_chk_filter(filter->insns, filter->len);
>>> +    if (ret)
>>> +            goto fail;
>>> +
>>> +    /* Check and rewrite the fprog for seccomp use */
>>> +    ret = seccomp_chk_filter(filter->insns, filter->len);
>>
>> "check" is spelled "check"!
>
> Yes, it is and he did spell "check" as "Check".
>
> seccomp_chk_filter() mirrors sk_chk_filter(). So it refers to
> "chk", not "check".

I can change it to be written out or leave it matching the networking
code.  Any preferences?

Thanks!
will

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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-09 19:59         ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 19:59 UTC (permalink / raw)
  To: Indan Zupancic
  Cc: Andrew Morton, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Sun, Apr 8, 2012 at 1:22 PM, Indan Zupancic <indan@nul.nu> wrote:
> On Sat, April 7, 2012 06:23, Andrew Morton wrote:
>> hm, I'm surprised that we don't have a zero-returning implementation of
>> is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
>
> It's sneakily hidden at the end of compat.h.
>
>>> +/**
>>> + * get_u32 - returns a u32 offset into data
>>> + * @data: a unsigned 64 bit value
>>> + * @index: 0 or 1 to return the first or second 32-bits
>>> + *
>>> + * This inline exists to hide the length of unsigned long.
>>> + * If a 32-bit unsigned long is passed in, it will be extended
>>> + * and the top 32-bits will be 0. If it is a 64-bit unsigned
>>> + * long, then whatever data is resident will be properly returned.
>>> + */
>>> +static inline u32 get_u32(u64 data, int index)
>>> +{
>>> +    return ((u32 *)&data)[index];
>>> +}
>>
>> This seems utterly broken on big-endian machines.  If so: fix.  If not:
>> add comment explaining why?
>
> It's not a bug, it's intentional.
>
> I tried to convince them to have a stable ABI for all archs, but they
> didn't want to make the ABI endianness independent, because it looks
> uglier. The argument being that system call numbers are arch dependent
> anyway.
>
> So a filter for a little endian arch needs to check a different offset
> than one for a big endian archs.

Awkward, but in practice it doesn't seem to matter either way --
especially since properly written filters should check the @arch which
indicates the calling convention, endianness, etc.

>>> +static u32 seccomp_run_filters(int syscall)
>>> +{
>>> +    struct seccomp_filter *f;
>>> +    u32 ret = SECCOMP_RET_KILL;
>>> +    /*
>>> +     * All filters are evaluated in order of youngest to oldest. The lowest
>>> +     * BPF return value always takes priority.
>>> +     */
>>
>> The youngest-first design surprised me.  It wasn't mentioned at all in
>> the changelog.  Thinking about it, I guess it just doesn't matter.  But
>> some description of the reasons for and implications of this decision
>> for the uninitiated would be welcome.
>
> I think it's less confusing to not mention the order at all, exactly
> because it doesn't matter. It has been like this from the start, so
> that's why it's not mentioned in the changelog I guess.

Good call - I will remove that comment.  The only relevant information
is that the lowest return value wins.  I did add a comment up near
struct seccomp_filter with my attempt at explaining the tree
structure, but I didn't detail evaluation order.  In this case, it
only is relevant because our only link to the tree is via our local
pointer which happens to be the "youngest".

> The reason to check the youngest first is because the filters are shared
> between processes: childs inherit it. If later on additional filters are
> added, the only way of adding them without modifying an older filter is
> by adding them to the head of the list. This way no locking is needed,
> because filters are only added and removed single-threadedly, and never
> modified when being shared.

I tried a handful of other strategies, but in practice this seemed to
meet the needs with the least complexity/overhead.

>>> +/**
>>> + * seccomp_attach_filter: Attaches a seccomp filter to current.
>>> + * @fprog: BPF program to install
>>> + *
>>> + * Returns 0 on success or an errno on failure.
>>> + */
>>> +static long seccomp_attach_filter(struct sock_fprog *fprog)
>>> +{
>>> +    struct seccomp_filter *filter;
>>> +    unsigned long fp_size = fprog->len * sizeof(struct sock_filter);
>>> +    unsigned long total_insns = fprog->len;
>>> +    long ret;
>>> +
>>> +    if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
>>> +            return -EINVAL;
>>> +
>>> +    for (filter = current->seccomp.filter; filter; filter = filter->prev)
>>> +            total_insns += filter->len + 4;  /* include a 4 instr penalty */
>>
>> So tasks don't share filters?  We copy them by value at fork?  Do we do
>> this at vfork() too?
>
> Yes they do. But shared filters are never modified, except for the refcount.
>
>>
>>> +    if (total_insns > MAX_INSNS_PER_PATH)
>>> +            return -ENOMEM;
>>> +
>>> +    /*
>>> +     * Installing a seccomp filter requires that the task have
>>> +     * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
>>> +     * This avoids scenarios where unprivileged tasks can affect the
>>> +     * behavior of privileged children.
>>> +     */
>>> +    if (!current->no_new_privs &&
>>> +        security_capable_noaudit(current_cred(), current_user_ns(),
>>> +                                 CAP_SYS_ADMIN) != 0)
>>> +            return -EACCES;
>>> +
>>> +    /* Allocate a new seccomp_filter */
>>> +    filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
>>
>> I think this gives userspace an easy way of causing page allocation
>> failure warnings, by permitting large kmalloc() attempts.  Add
>> __GFP_NOWARN?
>
> Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
> it allocates up to 512kb before even checking the length.
>
> What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?

It looks like GFP_USER|__GFP_NOWARN would make sense here.  I'll change it.

>>> +    /* Check and rewrite the fprog via the skb checker */
>>> +    ret = sk_chk_filter(filter->insns, filter->len);
>>> +    if (ret)
>>> +            goto fail;
>>> +
>>> +    /* Check and rewrite the fprog for seccomp use */
>>> +    ret = seccomp_chk_filter(filter->insns, filter->len);
>>
>> "check" is spelled "check"!
>
> Yes, it is and he did spell "check" as "Check".
>
> seccomp_chk_filter() mirrors sk_chk_filter(). So it refers to
> "chk", not "check".

I can change it to be written out or leave it matching the networking
code.  Any preferences?

Thanks!
will

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

* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
  2012-04-09 19:46       ` [kernel-hardening] " Will Drewry
@ 2012-04-09 20:47         ` Markus Gutschke
  -1 siblings, 0 replies; 146+ messages in thread
From: Markus Gutschke @ 2012-04-09 20:47 UTC (permalink / raw)
  To: Will Drewry
  Cc: Andrew Morton, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris

No matter what you do, please leave the samples accessible somewhere.
They proved incredibly useful in figuring out how the API works. I am
sure, other developers are going to appreciate them as well.

Alternatively, if you don't want to include the samples with the
kernel sources, figure out how you can include a sample in the
official manual page for prctl().


Markus

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

* [kernel-hardening] Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
@ 2012-04-09 20:47         ` Markus Gutschke
  0 siblings, 0 replies; 146+ messages in thread
From: Markus Gutschke @ 2012-04-09 20:47 UTC (permalink / raw)
  To: Will Drewry
  Cc: Andrew Morton, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris

No matter what you do, please leave the samples accessible somewhere.
They proved incredibly useful in figuring out how the API works. I am
sure, other developers are going to appreciate them as well.

Alternatively, if you don't want to include the samples with the
kernel sources, figure out how you can include a sample in the
official manual page for prctl().


Markus

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

* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
  2012-04-09 20:47         ` [kernel-hardening] " Markus Gutschke
  (?)
@ 2012-04-09 20:58           ` Ryan Ware
  -1 siblings, 0 replies; 146+ messages in thread
From: Ryan Ware @ 2012-04-09 20:58 UTC (permalink / raw)
  To: Markus Gutschke, Will Drewry
  Cc: Andrew Morton, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris

I second this!  They are extremely useful.

Ryan

On 4/9/12 1:47 PM, "Markus Gutschke" <markus@chromium.org> wrote:

>No matter what you do, please leave the samples accessible somewhere.
>They proved incredibly useful in figuring out how the API works. I am
>sure, other developers are going to appreciate them as well.
>
>Alternatively, if you don't want to include the samples with the
>kernel sources, figure out how you can include a sample in the
>official manual page for prctl().
>
>
>Markus
>--
>To unsubscribe from this list: send the line "unsubscribe
>linux-security-module" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html



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

* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
@ 2012-04-09 20:58           ` Ryan Ware
  0 siblings, 0 replies; 146+ messages in thread
From: Ryan Ware @ 2012-04-09 20:58 UTC (permalink / raw)
  To: Markus Gutschke, Will Drewry
  Cc: Andrew Morton, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris

I second this!  They are extremely useful.

Ryan

On 4/9/12 1:47 PM, "Markus Gutschke" <markus@chromium.org> wrote:

>No matter what you do, please leave the samples accessible somewhere.
>They proved incredibly useful in figuring out how the API works. I am
>sure, other developers are going to appreciate them as well.
>
>Alternatively, if you don't want to include the samples with the
>kernel sources, figure out how you can include a sample in the
>official manual page for prctl().
>
>
>Markus
>--
>To unsubscribe from this list: send the line "unsubscribe
>linux-security-module" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html



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

* [kernel-hardening] Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
@ 2012-04-09 20:58           ` Ryan Ware
  0 siblings, 0 replies; 146+ messages in thread
From: Ryan Ware @ 2012-04-09 20:58 UTC (permalink / raw)
  To: Markus Gutschke, Will Drewry
  Cc: Andrew Morton, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, coreyb, keescook, jmorris

I second this!  They are extremely useful.

Ryan

On 4/9/12 1:47 PM, "Markus Gutschke" <markus@chromium.org> wrote:

>No matter what you do, please leave the samples accessible somewhere.
>They proved incredibly useful in figuring out how the API works. I am
>sure, other developers are going to appreciate them as well.
>
>Alternatively, if you don't want to include the samples with the
>kernel sources, figure out how you can include a sample in the
>official manual page for prctl().
>
>
>Markus
>--
>To unsubscribe from this list: send the line "unsubscribe
>linux-security-module" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
  2012-04-09 20:58           ` Ryan Ware
@ 2012-04-09 22:47             ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 22:47 UTC (permalink / raw)
  To: Ryan Ware, Markus Gutschke, Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, coreyb,
	keescook, jmorris

On Mon, Apr 9, 2012 at 3:58 PM, Ryan Ware <ware@linux.intel.com> wrote:
>
> On 4/9/12 1:47 PM, "Markus Gutschke" <markus@chromium.org> wrote:
>
>>No matter what you do, please leave the samples accessible somewhere.
>>They proved incredibly useful in figuring out how the API works. I am
>>sure, other developers are going to appreciate them as well.
>>
>>Alternatively, if you don't want to include the samples with the
>>kernel sources, figure out how you can include a sample in the
>>official manual page for prctl().
>>
>
> I second this!  They are extremely useful.
>
> Ryan

In that case, would it make sense to put up a separate tools/testing
patch and leave samples where they lie? (I'd _love_ to keep this patch
series from acquiring another 1000 lines, but either way works :)

My current tester and harness lives here:
  https://github.com/redpig/seccomp/blob/master/tests/
and the licensing can be sorted out prior to a patch mail.

thanks!
will

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

* [kernel-hardening] Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
@ 2012-04-09 22:47             ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-09 22:47 UTC (permalink / raw)
  To: Ryan Ware, Markus Gutschke, Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, coreyb,
	keescook, jmorris

On Mon, Apr 9, 2012 at 3:58 PM, Ryan Ware <ware@linux.intel.com> wrote:
>
> On 4/9/12 1:47 PM, "Markus Gutschke" <markus@chromium.org> wrote:
>
>>No matter what you do, please leave the samples accessible somewhere.
>>They proved incredibly useful in figuring out how the API works. I am
>>sure, other developers are going to appreciate them as well.
>>
>>Alternatively, if you don't want to include the samples with the
>>kernel sources, figure out how you can include a sample in the
>>official manual page for prctl().
>>
>
> I second this!  They are extremely useful.
>
> Ryan

In that case, would it make sense to put up a separate tools/testing
patch and leave samples where they lie? (I'd _love_ to keep this patch
series from acquiring another 1000 lines, but either way works :)

My current tester and harness lives here:
  https://github.com/redpig/seccomp/blob/master/tests/
and the licensing can be sorted out prior to a patch mail.

thanks!
will

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-09 19:59         ` [kernel-hardening] " Will Drewry
@ 2012-04-10  9:48           ` James Morris
  -1 siblings, 0 replies; 146+ messages in thread
From: James Morris @ 2012-04-10  9:48 UTC (permalink / raw)
  To: Will Drewry
  Cc: Indan Zupancic, Andrew Morton, linux-kernel,
	linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	pmoore, corbet, eric.dumazet, markus, coreyb, keescook

On Mon, 9 Apr 2012, Will Drewry wrote:

> > seccomp_chk_filter() mirrors sk_chk_filter(). So it refers to
> > "chk", not "check".
> 
> I can change it to be written out or leave it matching the networking
> code.  Any preferences?

check :-)


-- 
James Morris
<jmorris@namei.org>

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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-10  9:48           ` James Morris
  0 siblings, 0 replies; 146+ messages in thread
From: James Morris @ 2012-04-10  9:48 UTC (permalink / raw)
  To: Will Drewry
  Cc: Indan Zupancic, Andrew Morton, linux-kernel,
	linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, luto, eparis, serge.hallyn, djm, scarybeasts,
	pmoore, corbet, eric.dumazet, markus, coreyb, keescook

On Mon, 9 Apr 2012, Will Drewry wrote:

> > seccomp_chk_filter() mirrors sk_chk_filter(). So it refers to
> > "chk", not "check".
> 
> I can change it to be written out or leave it matching the networking
> code.  Any preferences?

check :-)


-- 
James Morris
<jmorris@namei.org>

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-08 18:22       ` [kernel-hardening] " Indan Zupancic
@ 2012-04-10 10:34         ` Eric Dumazet
  -1 siblings, 0 replies; 146+ messages in thread
From: Eric Dumazet @ 2012-04-10 10:34 UTC (permalink / raw)
  To: Indan Zupancic
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto,
	eparis, serge.hallyn, djm, scarybeasts, pmoore, corbet, markus,
	coreyb, keescook, jmorris

On Mon, 2012-04-09 at 04:22 +1000, Indan Zupancic wrote:
> On Sat, April 7, 2012 06:23, Andrew Morton wrote:
> >
> > I think this gives userspace an easy way of causing page allocation
> > failure warnings, by permitting large kmalloc() attempts.  Add
> > __GFP_NOWARN?
> 
> Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
> it allocates up to 512kb before even checking the length.
> 

I dont think so.

sk_attach_filter() uses sk_malloc() and it does a check.

# cat /proc/sys/net/core/optmem_max 
20480

Of course you can change the limit on your machine.




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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-10 10:34         ` Eric Dumazet
  0 siblings, 0 replies; 146+ messages in thread
From: Eric Dumazet @ 2012-04-10 10:34 UTC (permalink / raw)
  To: Indan Zupancic
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto,
	eparis, serge.hallyn, djm, scarybeasts, pmoore, corbet, markus,
	coreyb, keescook, jmorris

On Mon, 2012-04-09 at 04:22 +1000, Indan Zupancic wrote:
> On Sat, April 7, 2012 06:23, Andrew Morton wrote:
> >
> > I think this gives userspace an easy way of causing page allocation
> > failure warnings, by permitting large kmalloc() attempts.  Add
> > __GFP_NOWARN?
> 
> Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
> it allocates up to 512kb before even checking the length.
> 

I dont think so.

sk_attach_filter() uses sk_malloc() and it does a check.

# cat /proc/sys/net/core/optmem_max 
20480

Of course you can change the limit on your machine.

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

* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
  2012-04-09 22:47             ` [kernel-hardening] " Will Drewry
  (?)
@ 2012-04-10 17:49               ` Ryan Ware
  -1 siblings, 0 replies; 146+ messages in thread
From: Ryan Ware @ 2012-04-10 17:49 UTC (permalink / raw)
  To: Will Drewry, Markus Gutschke, Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, coreyb,
	keescook, jmorris



On 4/9/12 3:47 PM, "Will Drewry" <wad@chromium.org> wrote:

>On Mon, Apr 9, 2012 at 3:58 PM, Ryan Ware <ware@linux.intel.com> wrote:
>>
>> On 4/9/12 1:47 PM, "Markus Gutschke" <markus@chromium.org> wrote:
>>
>>>No matter what you do, please leave the samples accessible somewhere.
>>>They proved incredibly useful in figuring out how the API works. I am
>>>sure, other developers are going to appreciate them as well.
>>>
>>>Alternatively, if you don't want to include the samples with the
>>>kernel sources, figure out how you can include a sample in the
>>>official manual page for prctl().
>>>
>>
>> I second this!  They are extremely useful.
>>
>> Ryan
>
>In that case, would it make sense to put up a separate tools/testing
>patch and leave samples where they lie? (I'd _love_ to keep this patch
>series from acquiring another 1000 lines, but either way works :)
>
>My current tester and harness lives here:
>  https://github.com/redpig/seccomp/blob/master/tests/
>and the licensing can be sorted out prior to a patch mail.

I have absolutely no problems with that solution.  Availability is the
important thing.

Ryan



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

* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
@ 2012-04-10 17:49               ` Ryan Ware
  0 siblings, 0 replies; 146+ messages in thread
From: Ryan Ware @ 2012-04-10 17:49 UTC (permalink / raw)
  To: Will Drewry, Markus Gutschke, Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, coreyb,
	keescook, jmorris



On 4/9/12 3:47 PM, "Will Drewry" <wad@chromium.org> wrote:

>On Mon, Apr 9, 2012 at 3:58 PM, Ryan Ware <ware@linux.intel.com> wrote:
>>
>> On 4/9/12 1:47 PM, "Markus Gutschke" <markus@chromium.org> wrote:
>>
>>>No matter what you do, please leave the samples accessible somewhere.
>>>They proved incredibly useful in figuring out how the API works. I am
>>>sure, other developers are going to appreciate them as well.
>>>
>>>Alternatively, if you don't want to include the samples with the
>>>kernel sources, figure out how you can include a sample in the
>>>official manual page for prctl().
>>>
>>
>> I second this!  They are extremely useful.
>>
>> Ryan
>
>In that case, would it make sense to put up a separate tools/testing
>patch and leave samples where they lie? (I'd _love_ to keep this patch
>series from acquiring another 1000 lines, but either way works :)
>
>My current tester and harness lives here:
>  https://github.com/redpig/seccomp/blob/master/tests/
>and the licensing can be sorted out prior to a patch mail.

I have absolutely no problems with that solution.  Availability is the
important thing.

Ryan



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

* [kernel-hardening] Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
@ 2012-04-10 17:49               ` Ryan Ware
  0 siblings, 0 replies; 146+ messages in thread
From: Ryan Ware @ 2012-04-10 17:49 UTC (permalink / raw)
  To: Will Drewry, Markus Gutschke, Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, coreyb,
	keescook, jmorris



On 4/9/12 3:47 PM, "Will Drewry" <wad@chromium.org> wrote:

>On Mon, Apr 9, 2012 at 3:58 PM, Ryan Ware <ware@linux.intel.com> wrote:
>>
>> On 4/9/12 1:47 PM, "Markus Gutschke" <markus@chromium.org> wrote:
>>
>>>No matter what you do, please leave the samples accessible somewhere.
>>>They proved incredibly useful in figuring out how the API works. I am
>>>sure, other developers are going to appreciate them as well.
>>>
>>>Alternatively, if you don't want to include the samples with the
>>>kernel sources, figure out how you can include a sample in the
>>>official manual page for prctl().
>>>
>>
>> I second this!  They are extremely useful.
>>
>> Ryan
>
>In that case, would it make sense to put up a separate tools/testing
>patch and leave samples where they lie? (I'd _love_ to keep this patch
>series from acquiring another 1000 lines, but either way works :)
>
>My current tester and harness lives here:
>  https://github.com/redpig/seccomp/blob/master/tests/
>and the licensing can be sorted out prior to a patch mail.

I have absolutely no problems with that solution.  Availability is the
important thing.

Ryan

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 19:55     ` Andrew Morton
@ 2012-04-10 19:03       ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-10 19:03 UTC (permalink / raw)
  To: Andrew Morton, Andrew Lutomirski
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski, linux-man

On Fri, Apr 6, 2012 at 2:55 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:46 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Andy Lutomirski <luto@amacapital.net>
>>
>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>> become a lot less dangerous because there is no possibility of
>> subverting privileged binaries.
>
> The changelog doesn't explain the semantics of the new syscall.
> There's a comment way-down-there which I guess suffices, if you hunt
> for it.

I'll bubble up luto's comment into the changelog when I resend the
grand-unified-patchset.

> And the changelog doesn't explain why this is being added.  Presumably
> seccomp_filter wants/needs this feature but whowhatwherewhenwhy?  Spell
> it all out, please.

I'll try my hand at that and luto@ can yell at me if I misrepresent.
Seem reasonable?

> The new syscall mode will be documented in the prctl manpage.  Please
> cc linux-man@vger.kernel.org and work with Michael on getting this
> done?

I'll add linux-man to the patch series since this applies to both
no_new_privs and seccomp filter.

Thanks!

>>
>> ...
>>

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-10 19:03       ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-10 19:03 UTC (permalink / raw)
  To: Andrew Morton, Andrew Lutomirski
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski, linux-man

On Fri, Apr 6, 2012 at 2:55 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:46 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Andy Lutomirski <luto@amacapital.net>
>>
>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>> become a lot less dangerous because there is no possibility of
>> subverting privileged binaries.
>
> The changelog doesn't explain the semantics of the new syscall.
> There's a comment way-down-there which I guess suffices, if you hunt
> for it.

I'll bubble up luto's comment into the changelog when I resend the
grand-unified-patchset.

> And the changelog doesn't explain why this is being added.  Presumably
> seccomp_filter wants/needs this feature but whowhatwherewhenwhy?  Spell
> it all out, please.

I'll try my hand at that and luto@ can yell at me if I misrepresent.
Seem reasonable?

> The new syscall mode will be documented in the prctl manpage.  Please
> cc linux-man@vger.kernel.org and work with Michael on getting this
> done?

I'll add linux-man to the patch series since this applies to both
no_new_privs and seccomp filter.

Thanks!

>>
>> ...
>>

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 19:49     ` [kernel-hardening] " Andrew Morton
@ 2012-04-10 19:12       ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-10 19:12 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 2:49 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:46 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Andy Lutomirski <luto@amacapital.net>
>>
>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>> become a lot less dangerous because there is no possibility of
>> subverting privileged binaries.
>>
>> This patch completely breaks apparmor.  Someone who understands (and
>> uses) apparmor should fix it or at least give me a hint.
>
> So [patch 2/15] fixes all this up?
>
> I guess we should join the two patches into one, to avoid a silly
> breakage window.  That means that John loses a brownie point, but we
> can mention him in the changelog, include his signed-off-by:
>
>> Signed-off-by: Andy Lutomirski <luto@amacapital.net>
>
> Several of these patches are missing your signed-off-by:.  They should
> all have your SOB, because you sent them.
> Documentation/SubmittingPatches explains this.

Oops - I'll add them!

> I'm trying to find a way to merge all this code without reviewing it ;)
> Alas, this is against my rules.  Given the length of time for which
> this patchset has been floating around, I'm a little surprised by the
> lack of acked-by's and reviewed-by's.  Have you been gathering them all
> up?  Are the networking guys all happy about this patchset?

eric.dumazet@gmail.com acked the networking ones, and I have a
smattering of others for the other patches. Given the review and
feedback, I don't have a huge number of acked/reviewed-bys. I tried
not to lose any after the first couple of revs, but I know I did some
things wrong early on.

I can prod some others who've contributed to add their tags, unless
there is a good reason for them not too.  I suspect it was just
because of partial/drive-by reviewing, but I don't know.

thanks!
will

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-10 19:12       ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-10 19:12 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, corbet, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski

On Fri, Apr 6, 2012 at 2:49 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 29 Mar 2012 15:01:46 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> From: Andy Lutomirski <luto@amacapital.net>
>>
>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>> become a lot less dangerous because there is no possibility of
>> subverting privileged binaries.
>>
>> This patch completely breaks apparmor.  Someone who understands (and
>> uses) apparmor should fix it or at least give me a hint.
>
> So [patch 2/15] fixes all this up?
>
> I guess we should join the two patches into one, to avoid a silly
> breakage window.  That means that John loses a brownie point, but we
> can mention him in the changelog, include his signed-off-by:
>
>> Signed-off-by: Andy Lutomirski <luto@amacapital.net>
>
> Several of these patches are missing your signed-off-by:.  They should
> all have your SOB, because you sent them.
> Documentation/SubmittingPatches explains this.

Oops - I'll add them!

> I'm trying to find a way to merge all this code without reviewing it ;)
> Alas, this is against my rules.  Given the length of time for which
> this patchset has been floating around, I'm a little surprised by the
> lack of acked-by's and reviewed-by's.  Have you been gathering them all
> up?  Are the networking guys all happy about this patchset?

eric.dumazet@gmail.com acked the networking ones, and I have a
smattering of others for the other patches. Given the review and
feedback, I don't have a huge number of acked/reviewed-bys. I tried
not to lose any after the first couple of revs, but I know I did some
things wrong early on.

I can prod some others who've contributed to add their tags, unless
there is a good reason for them not too.  I suspect it was just
because of partial/drive-by reviewing, but I don't know.

thanks!
will

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-08 18:22       ` [kernel-hardening] " Indan Zupancic
@ 2012-04-10 19:54         ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-10 19:54 UTC (permalink / raw)
  To: Indan Zupancic
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Mon, 9 Apr 2012 04:22:40 +1000
"Indan Zupancic" <indan@nul.nu> wrote:

> On Sat, April 7, 2012 06:23, Andrew Morton wrote:
> > hm, I'm surprised that we don't have a zero-returning implementation of
> > is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
> 
> It's sneakily hidden at the end of compat.h.
> 
> >> +/**
> >> + * get_u32 - returns a u32 offset into data
> >> + * @data: a unsigned 64 bit value
> >> + * @index: 0 or 1 to return the first or second 32-bits
> >> + *
> >> + * This inline exists to hide the length of unsigned long.
> >> + * If a 32-bit unsigned long is passed in, it will be extended
> >> + * and the top 32-bits will be 0. If it is a 64-bit unsigned
> >> + * long, then whatever data is resident will be properly returned.
> >> + */
> >> +static inline u32 get_u32(u64 data, int index)
> >> +{
> >> +	return ((u32 *)&data)[index];
> >> +}
> >
> > This seems utterly broken on big-endian machines.  If so: fix.  If not:
> > add comment explaining why?
> 
> It's not a bug, it's intentional.

Well it looks like a bug, which is why I suggest that it be clearly
commented.

> >
> >> +	if (total_insns > MAX_INSNS_PER_PATH)
> >> +		return -ENOMEM;
> >> +
> >> +	/*
> >> +	 * Installing a seccomp filter requires that the task have
> >> +	 * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
> >> +	 * This avoids scenarios where unprivileged tasks can affect the
> >> +	 * behavior of privileged children.
> >> +	 */
> >> +	if (!current->no_new_privs &&
> >> +	    security_capable_noaudit(current_cred(), current_user_ns(),
> >> +				     CAP_SYS_ADMIN) != 0)
> >> +		return -EACCES;
> >> +
> >> +	/* Allocate a new seccomp_filter */
> >> +	filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
> >
> > I think this gives userspace an easy way of causing page allocation
> > failure warnings, by permitting large kmalloc() attempts.  Add
> > __GFP_NOWARN?
> 
> Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
> it allocates up to 512kb before even checking the length.

An order-3 allocation attempt is pretty fragile.  This will sometimes
fail.

> What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?

Let's be conventional and use the open-coded __GFP_NOWARN. 
__GFP_NOWARN says "this is a big allocation which will sometimes fail
and I have carefully reviewed the failure paths and runtime tested
them".

Please carefully review the failure paths and runtime test them ;)

> >> +	/* Check and rewrite the fprog via the skb checker */
> >> +	ret = sk_chk_filter(filter->insns, filter->len);
> >> +	if (ret)
> >> +		goto fail;
> >> +
> >> +	/* Check and rewrite the fprog for seccomp use */
> >> +	ret = seccomp_chk_filter(filter->insns, filter->len);
> >
> > "check" is spelled "check"!
> 
> Yes, it is and he did spell "check" as "Check".
> 
> seccomp_chk_filter() mirrors sk_chk_filter(). So it refers to
> "chk", not "check".

bah.  Two poor identifiers isn't better than one.  Whatever.



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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-10 19:54         ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-10 19:54 UTC (permalink / raw)
  To: Indan Zupancic
  Cc: Will Drewry, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Mon, 9 Apr 2012 04:22:40 +1000
"Indan Zupancic" <indan@nul.nu> wrote:

> On Sat, April 7, 2012 06:23, Andrew Morton wrote:
> > hm, I'm surprised that we don't have a zero-returning implementation of
> > is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
> 
> It's sneakily hidden at the end of compat.h.
> 
> >> +/**
> >> + * get_u32 - returns a u32 offset into data
> >> + * @data: a unsigned 64 bit value
> >> + * @index: 0 or 1 to return the first or second 32-bits
> >> + *
> >> + * This inline exists to hide the length of unsigned long.
> >> + * If a 32-bit unsigned long is passed in, it will be extended
> >> + * and the top 32-bits will be 0. If it is a 64-bit unsigned
> >> + * long, then whatever data is resident will be properly returned.
> >> + */
> >> +static inline u32 get_u32(u64 data, int index)
> >> +{
> >> +	return ((u32 *)&data)[index];
> >> +}
> >
> > This seems utterly broken on big-endian machines.  If so: fix.  If not:
> > add comment explaining why?
> 
> It's not a bug, it's intentional.

Well it looks like a bug, which is why I suggest that it be clearly
commented.

> >
> >> +	if (total_insns > MAX_INSNS_PER_PATH)
> >> +		return -ENOMEM;
> >> +
> >> +	/*
> >> +	 * Installing a seccomp filter requires that the task have
> >> +	 * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
> >> +	 * This avoids scenarios where unprivileged tasks can affect the
> >> +	 * behavior of privileged children.
> >> +	 */
> >> +	if (!current->no_new_privs &&
> >> +	    security_capable_noaudit(current_cred(), current_user_ns(),
> >> +				     CAP_SYS_ADMIN) != 0)
> >> +		return -EACCES;
> >> +
> >> +	/* Allocate a new seccomp_filter */
> >> +	filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
> >
> > I think this gives userspace an easy way of causing page allocation
> > failure warnings, by permitting large kmalloc() attempts.  Add
> > __GFP_NOWARN?
> 
> Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
> it allocates up to 512kb before even checking the length.

An order-3 allocation attempt is pretty fragile.  This will sometimes
fail.

> What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?

Let's be conventional and use the open-coded __GFP_NOWARN. 
__GFP_NOWARN says "this is a big allocation which will sometimes fail
and I have carefully reviewed the failure paths and runtime tested
them".

Please carefully review the failure paths and runtime test them ;)

> >> +	/* Check and rewrite the fprog via the skb checker */
> >> +	ret = sk_chk_filter(filter->insns, filter->len);
> >> +	if (ret)
> >> +		goto fail;
> >> +
> >> +	/* Check and rewrite the fprog for seccomp use */
> >> +	ret = seccomp_chk_filter(filter->insns, filter->len);
> >
> > "check" is spelled "check"!
> 
> Yes, it is and he did spell "check" as "Check".
> 
> seccomp_chk_filter() mirrors sk_chk_filter(). So it refers to
> "chk", not "check".

bah.  Two poor identifiers isn't better than one.  Whatever.

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-09 19:59         ` [kernel-hardening] " Will Drewry
@ 2012-04-10 20:00           ` Andrew Morton
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-10 20:00 UTC (permalink / raw)
  To: Will Drewry
  Cc: Indan Zupancic, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Mon, 9 Apr 2012 14:59:00 -0500
Will Drewry <wad@chromium.org> wrote:

> >> I think this gives userspace an easy way of causing page allocation
> >> failure warnings, by permitting large kmalloc() attempts. __Add
> >> __GFP_NOWARN?
> >
> > Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
> > it allocates up to 512kb before even checking the length.
> >
> > What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?
> 
> It looks like GFP_USER|__GFP_NOWARN would make sense here.  I'll change it.

I'm not really sure why GFP_USER exists.  It's very rarely used, and
most usages are probably inappropriate.  To me it means "same as
GFP_HIGHUSER, only don't use highmem".  That's relevant to blockdev
pagecache and nothing else as far as I can tell.  And good luck working
out what the __GFP_HARDWALL does ;)

This is a regular old allocation of kernel memory - the thing to use
here is GFP_KERNEL|__GFP_NOWARN.

(I'm surprised that we didn't remove __GFP_NOWARN ages ago - warning by
default is pretty obnoxious.  But the warning continues to be
occasionally useful and false positives are rare).


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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-10 20:00           ` Andrew Morton
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Morton @ 2012-04-10 20:00 UTC (permalink / raw)
  To: Will Drewry
  Cc: Indan Zupancic, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Mon, 9 Apr 2012 14:59:00 -0500
Will Drewry <wad@chromium.org> wrote:

> >> I think this gives userspace an easy way of causing page allocation
> >> failure warnings, by permitting large kmalloc() attempts. __Add
> >> __GFP_NOWARN?
> >
> > Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
> > it allocates up to 512kb before even checking the length.
> >
> > What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?
> 
> It looks like GFP_USER|__GFP_NOWARN would make sense here.  I'll change it.

I'm not really sure why GFP_USER exists.  It's very rarely used, and
most usages are probably inappropriate.  To me it means "same as
GFP_HIGHUSER, only don't use highmem".  That's relevant to blockdev
pagecache and nothing else as far as I can tell.  And good luck working
out what the __GFP_HARDWALL does ;)

This is a regular old allocation of kernel memory - the thing to use
here is GFP_KERNEL|__GFP_NOWARN.

(I'm surprised that we didn't remove __GFP_NOWARN ages ago - warning by
default is pretty obnoxious.  But the warning continues to be
occasionally useful and false positives are rare).

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-10 19:54         ` [kernel-hardening] " Andrew Morton
@ 2012-04-10 20:15           ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-10 20:15 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Indan Zupancic, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Tue, Apr 10, 2012 at 2:54 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Mon, 9 Apr 2012 04:22:40 +1000
> "Indan Zupancic" <indan@nul.nu> wrote:
>
>> On Sat, April 7, 2012 06:23, Andrew Morton wrote:
>> > hm, I'm surprised that we don't have a zero-returning implementation of
>> > is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
>>
>> It's sneakily hidden at the end of compat.h.
>>
>> >> +/**
>> >> + * get_u32 - returns a u32 offset into data
>> >> + * @data: a unsigned 64 bit value
>> >> + * @index: 0 or 1 to return the first or second 32-bits
>> >> + *
>> >> + * This inline exists to hide the length of unsigned long.
>> >> + * If a 32-bit unsigned long is passed in, it will be extended
>> >> + * and the top 32-bits will be 0. If it is a 64-bit unsigned
>> >> + * long, then whatever data is resident will be properly returned.
>> >> + */
>> >> +static inline u32 get_u32(u64 data, int index)
>> >> +{
>> >> +  return ((u32 *)&data)[index];
>> >> +}
>> >
>> > This seems utterly broken on big-endian machines.  If so: fix.  If not:
>> > add comment explaining why?
>>
>> It's not a bug, it's intentional.
>
> Well it looks like a bug, which is why I suggest that it be clearly
> commented.

I've added a comment indicating it is intentionally ugly.

>> >
>> >> +  if (total_insns > MAX_INSNS_PER_PATH)
>> >> +          return -ENOMEM;
>> >> +
>> >> +  /*
>> >> +   * Installing a seccomp filter requires that the task have
>> >> +   * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
>> >> +   * This avoids scenarios where unprivileged tasks can affect the
>> >> +   * behavior of privileged children.
>> >> +   */
>> >> +  if (!current->no_new_privs &&
>> >> +      security_capable_noaudit(current_cred(), current_user_ns(),
>> >> +                               CAP_SYS_ADMIN) != 0)
>> >> +          return -EACCES;
>> >> +
>> >> +  /* Allocate a new seccomp_filter */
>> >> +  filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
>> >
>> > I think this gives userspace an easy way of causing page allocation
>> > failure warnings, by permitting large kmalloc() attempts.  Add
>> > __GFP_NOWARN?
>>
>> Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
>> it allocates up to 512kb before even checking the length.
>
> An order-3 allocation attempt is pretty fragile.  This will sometimes
> fail.
>
>> What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?
>
> Let's be conventional and use the open-coded __GFP_NOWARN.
> __GFP_NOWARN says "this is a big allocation which will sometimes fail
> and I have carefully reviewed the failure paths and runtime tested
> them".
>
> Please carefully review the failure paths and runtime test them ;)

Thankfully the failure path is simple in this case.  Additional
runtime testing in progress :)

>> >> +  /* Check and rewrite the fprog via the skb checker */
>> >> +  ret = sk_chk_filter(filter->insns, filter->len);
>> >> +  if (ret)
>> >> +          goto fail;
>> >> +
>> >> +  /* Check and rewrite the fprog for seccomp use */
>> >> +  ret = seccomp_chk_filter(filter->insns, filter->len);
>> >
>> > "check" is spelled "check"!
>>
>> Yes, it is and he did spell "check" as "Check".
>>
>> seccomp_chk_filter() mirrors sk_chk_filter(). So it refers to
>> "chk", not "check".
>
> bah.  Two poor identifiers isn't better than one.  Whatever.

As per James's comment, reducing it to one poor identifier.

thanks!

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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-10 20:15           ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-10 20:15 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Indan Zupancic, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Tue, Apr 10, 2012 at 2:54 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Mon, 9 Apr 2012 04:22:40 +1000
> "Indan Zupancic" <indan@nul.nu> wrote:
>
>> On Sat, April 7, 2012 06:23, Andrew Morton wrote:
>> > hm, I'm surprised that we don't have a zero-returning implementation of
>> > is_compat_task() when CONFIG_COMPAT=n.  Seems silly.  Blames Arnd.
>>
>> It's sneakily hidden at the end of compat.h.
>>
>> >> +/**
>> >> + * get_u32 - returns a u32 offset into data
>> >> + * @data: a unsigned 64 bit value
>> >> + * @index: 0 or 1 to return the first or second 32-bits
>> >> + *
>> >> + * This inline exists to hide the length of unsigned long.
>> >> + * If a 32-bit unsigned long is passed in, it will be extended
>> >> + * and the top 32-bits will be 0. If it is a 64-bit unsigned
>> >> + * long, then whatever data is resident will be properly returned.
>> >> + */
>> >> +static inline u32 get_u32(u64 data, int index)
>> >> +{
>> >> +  return ((u32 *)&data)[index];
>> >> +}
>> >
>> > This seems utterly broken on big-endian machines.  If so: fix.  If not:
>> > add comment explaining why?
>>
>> It's not a bug, it's intentional.
>
> Well it looks like a bug, which is why I suggest that it be clearly
> commented.

I've added a comment indicating it is intentionally ugly.

>> >
>> >> +  if (total_insns > MAX_INSNS_PER_PATH)
>> >> +          return -ENOMEM;
>> >> +
>> >> +  /*
>> >> +   * Installing a seccomp filter requires that the task have
>> >> +   * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
>> >> +   * This avoids scenarios where unprivileged tasks can affect the
>> >> +   * behavior of privileged children.
>> >> +   */
>> >> +  if (!current->no_new_privs &&
>> >> +      security_capable_noaudit(current_cred(), current_user_ns(),
>> >> +                               CAP_SYS_ADMIN) != 0)
>> >> +          return -EACCES;
>> >> +
>> >> +  /* Allocate a new seccomp_filter */
>> >> +  filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);
>> >
>> > I think this gives userspace an easy way of causing page allocation
>> > failure warnings, by permitting large kmalloc() attempts.  Add
>> > __GFP_NOWARN?
>>
>> Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
>> it allocates up to 512kb before even checking the length.
>
> An order-3 allocation attempt is pretty fragile.  This will sometimes
> fail.
>
>> What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?
>
> Let's be conventional and use the open-coded __GFP_NOWARN.
> __GFP_NOWARN says "this is a big allocation which will sometimes fail
> and I have carefully reviewed the failure paths and runtime tested
> them".
>
> Please carefully review the failure paths and runtime test them ;)

Thankfully the failure path is simple in this case.  Additional
runtime testing in progress :)

>> >> +  /* Check and rewrite the fprog via the skb checker */
>> >> +  ret = sk_chk_filter(filter->insns, filter->len);
>> >> +  if (ret)
>> >> +          goto fail;
>> >> +
>> >> +  /* Check and rewrite the fprog for seccomp use */
>> >> +  ret = seccomp_chk_filter(filter->insns, filter->len);
>> >
>> > "check" is spelled "check"!
>>
>> Yes, it is and he did spell "check" as "Check".
>>
>> seccomp_chk_filter() mirrors sk_chk_filter(). So it refers to
>> "chk", not "check".
>
> bah.  Two poor identifiers isn't better than one.  Whatever.

As per James's comment, reducing it to one poor identifier.

thanks!

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
  2012-04-10 20:00           ` [kernel-hardening] " Andrew Morton
  (?)
@ 2012-04-10 20:16             ` Will Drewry
  -1 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-10 20:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Indan Zupancic, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Tue, Apr 10, 2012 at 3:00 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Mon, 9 Apr 2012 14:59:00 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> >> I think this gives userspace an easy way of causing page allocation
>> >> failure warnings, by permitting large kmalloc() attempts. __Add
>> >> __GFP_NOWARN?
>> >
>> > Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
>> > it allocates up to 512kb before even checking the length.
>> >
>> > What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?
>>
>> It looks like GFP_USER|__GFP_NOWARN would make sense here.  I'll change it.
>
> I'm not really sure why GFP_USER exists.  It's very rarely used, and
> most usages are probably inappropriate.  To me it means "same as
> GFP_HIGHUSER, only don't use highmem".  That's relevant to blockdev
> pagecache and nothing else as far as I can tell.  And good luck working
> out what the __GFP_HARDWALL does ;)

I was wildly speculating about it, but maybe I should stop doing that.

> This is a regular old allocation of kernel memory - the thing to use
> here is GFP_KERNEL|__GFP_NOWARN.

Sounds good - I've just changed the patchset to that effect.

> (I'm surprised that we didn't remove __GFP_NOWARN ages ago - warning by
> default is pretty obnoxious.  But the warning continues to be
> occasionally useful and false positives are rare).
>

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

* Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-10 20:16             ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-10 20:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Indan Zupancic, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Tue, Apr 10, 2012 at 3:00 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Mon, 9 Apr 2012 14:59:00 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> >> I think this gives userspace an easy way of causing page allocation
>> >> failure warnings, by permitting large kmalloc() attempts. __Add
>> >> __GFP_NOWARN?
>> >
>> > Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
>> > it allocates up to 512kb before even checking the length.
>> >
>> > What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?
>>
>> It looks like GFP_USER|__GFP_NOWARN would make sense here.  I'll change it.
>
> I'm not really sure why GFP_USER exists.  It's very rarely used, and
> most usages are probably inappropriate.  To me it means "same as
> GFP_HIGHUSER, only don't use highmem".  That's relevant to blockdev
> pagecache and nothing else as far as I can tell.  And good luck working
> out what the __GFP_HARDWALL does ;)

I was wildly speculating about it, but maybe I should stop doing that.

> This is a regular old allocation of kernel memory - the thing to use
> here is GFP_KERNEL|__GFP_NOWARN.

Sounds good - I've just changed the patchset to that effect.

> (I'm surprised that we didn't remove __GFP_NOWARN ages ago - warning by
> default is pretty obnoxious.  But the warning continues to be
> occasionally useful and false positives are rare).
>
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [kernel-hardening] Re: [PATCH v17 08/15] seccomp: add system call filtering using BPF
@ 2012-04-10 20:16             ` Will Drewry
  0 siblings, 0 replies; 146+ messages in thread
From: Will Drewry @ 2012-04-10 20:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Indan Zupancic, linux-kernel, linux-security-module, linux-arch,
	linux-doc, kernel-hardening, netdev, x86, arnd, davem, hpa,
	mingo, oleg, peterz, rdunlap, mcgrathr, tglx, luto, eparis,
	serge.hallyn, djm, scarybeasts, pmoore, corbet, eric.dumazet,
	markus, coreyb, keescook, jmorris

On Tue, Apr 10, 2012 at 3:00 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Mon, 9 Apr 2012 14:59:00 -0500
> Will Drewry <wad@chromium.org> wrote:
>
>> >> I think this gives userspace an easy way of causing page allocation
>> >> failure warnings, by permitting large kmalloc() attempts. __Add
>> >> __GFP_NOWARN?
>> >
>> > Max is 32kb. sk_attach_filter() in net/core/filter.c is worse,
>> > it allocates up to 512kb before even checking the length.
>> >
>> > What about using GFP_USER (and adding __GFP_NOWARN to GFP_USER) instead?
>>
>> It looks like GFP_USER|__GFP_NOWARN would make sense here.  I'll change it.
>
> I'm not really sure why GFP_USER exists.  It's very rarely used, and
> most usages are probably inappropriate.  To me it means "same as
> GFP_HIGHUSER, only don't use highmem".  That's relevant to blockdev
> pagecache and nothing else as far as I can tell.  And good luck working
> out what the __GFP_HARDWALL does ;)

I was wildly speculating about it, but maybe I should stop doing that.

> This is a regular old allocation of kernel memory - the thing to use
> here is GFP_KERNEL|__GFP_NOWARN.

Sounds good - I've just changed the patchset to that effect.

> (I'm surprised that we didn't remove __GFP_NOWARN ages ago - warning by
> default is pretty obnoxious.  But the warning continues to be
> occasionally useful and false positives are rare).
>

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 20:01       ` [kernel-hardening] " Andrew Lutomirski
@ 2012-04-10 20:37         ` Rob Landley
  -1 siblings, 0 replies; 146+ messages in thread
From: Rob Landley @ 2012-04-10 20:37 UTC (permalink / raw)
  To: Andrew Lutomirski
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook, jmorris, Andy Lutomirski,
	linux-man

On 04/06/2012 03:01 PM, Andrew Lutomirski wrote:
> On Fri, Apr 6, 2012 at 12:55 PM, Andrew Morton
> <akpm@linux-foundation.org> wrote:
>> On Thu, 29 Mar 2012 15:01:46 -0500
>> Will Drewry <wad@chromium.org> wrote:
>>
>>> From: Andy Lutomirski <luto@amacapital.net>
>>>
>>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>>> become a lot less dangerous because there is no possibility of
>>> subverting privileged binaries.
>>
>> The changelog doesn't explain the semantics of the new syscall.
>> There's a comment way-down-there which I guess suffices, if you hunt
>> for it.
>>
>> And the changelog doesn't explain why this is being added.  Presumably
>> seccomp_filter wants/needs this feature but whowhatwherewhenwhy?  Spell
>> it all out, please.
>>
>> The new syscall mode will be documented in the prctl manpage.  Please
>> cc linux-man@vger.kernel.org and work with Michael on getting this
>> done?
> 
> This has been bugging me for awhile.  Is there any interest in moving
> the manpages into the kernel source tree?

Not that I know of. I'm pretty sure if the guy maintaining it (Michael
Kerrisk) wanted to do that, he could have raised the issue at any time
over the past several years.

> Then there could be a
> general requirement that new APIs get documented when they're written.

Because having a Documentation directory, javadoc in the source itself
(some of which is combined with the Documentation/DocBook xml files to
form the make htmldocs output), menuconfig help text, and a whole buch
of scattered readmes does _not_ get new APIs documented as they're written.

That isn't even counting git commit comments and mailing list messages
in various web archives. Are you going to suck the linux weekly news
kernel articles into the tree (http://lwn.net/Kernel/Index)? How about
Linux Journal's complete archives going back to 2004
(http://www.linuxjournal.com/magazine)? Or the h-online and
kernelnewbies writeups? How about wikipedia pages on interesting kernel
topics? The sourceforge pages for userspace projects like lxc.sf.net or
i2c-utils? How about that device driver writing tutorial Greg KH
recorded in 2008, that's only a 2.8 gigabyte video file.  Rusty's
Unreliable Guides?  Greg KH's blog? (Heck, http://kernelplanet.org).

Speaking of videos, here's the 2011 LinuxCon Japan talks:

  http://video.linux.com/categories/2011-linuxcon-japan

And here are videos for the Consumer Electronic Linux Forum:

  http://free-electrons.com/blog/elc-2012-videos/

(and you can get 2011, 2010, 2006...)

Here are Ottawa Linux Symposium papers:

  http://kernel.org/doc/ols

Don't forget IBM Developerworks' library:

http://www.ibm.com/developerworks/linux/library/l-linux-kernel/

Have some standards documents:

http://www.opengroup.org/onlinepubs/9699919799/
http://busybox.net/~landley/c99-draft.html
http://www.unix.org/whitepapers/64bit.html
http://refspecs.linuxfoundation.org
http://t10.org/scsi-3.htm

Here's a random blog post about booting a bare metal "hello world"
program on qemu for ARM:

http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/

Let's pick a topic, like the ELF loader. Here's the best introduction of
how ELF files _really_ work I've seen:

http://muppetlabs.com/~breadbox/software/tiny/teensy.html

Although http://linuxjournal.com/article/1059 is pretty good too, as
were http://linuxjournal.com/article/1060 and
http://linuxjournal.com/article/80 as well.  And if you want the
_details_, here's an extremely dry online book:

http;//www.iecc.com/linker/

And here's the first entry in the blog series the guy who wrote "gold"
did about writing his new linker:

http://www.airs.com/blog/archives/38

And so on, and so forth...

> (There are plenty of barely- or incompletely-documented syscalls.
> futex and relatives come to mind.)

Your proposal does not address this problem.

speaking of syscalls, I do note that ever since I tried to add Hexagon
support to strace (less fun than it sounds), I've wanted a way to beat
proper syscall information out of the kernel headers so I could get not
just syscall numbers but how many arguments and a brief stab at the type
of each argument.

Of course you _can_ get argument type and count, but not from the
headers: you have to use moderately horrible sed on the kernel's source
code, ala:

find . -name "*.c" -print0 | \
xargs -n1 -0 sed -n -e 's/.*\(SYSCALL_DEFINE[0-9](\)/\1/' \
  -e 't got;d;:got;s/).*/)/p;t;N;b got'

> --Andy

Rob
-- 
GNU/Linux isn't: Linux=GPLv2, GNU=GPLv3+, they can't share code.
Either it's "mere aggregation", or a license violation.  Pick one.

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-10 20:37         ` Rob Landley
  0 siblings, 0 replies; 146+ messages in thread
From: Rob Landley @ 2012-04-10 20:37 UTC (permalink / raw)
  To: Andrew Lutomirski
  Cc: Andrew Morton, Will Drewry, linux-kernel, linux-security-module,
	linux-arch, linux-doc, kernel-hardening, netdev, x86, arnd,
	davem, hpa, mingo, oleg, peterz, rdunlap, mcgrathr, tglx, eparis,
	serge.hallyn, djm, scarybeasts, indan, pmoore, corbet,
	eric.dumazet, markus, coreyb, keescook, jmorris, Andy Lutomirski,
	linux-man

On 04/06/2012 03:01 PM, Andrew Lutomirski wrote:
> On Fri, Apr 6, 2012 at 12:55 PM, Andrew Morton
> <akpm@linux-foundation.org> wrote:
>> On Thu, 29 Mar 2012 15:01:46 -0500
>> Will Drewry <wad@chromium.org> wrote:
>>
>>> From: Andy Lutomirski <luto@amacapital.net>
>>>
>>> With this set, a lot of dangerous operations (chroot, unshare, etc)
>>> become a lot less dangerous because there is no possibility of
>>> subverting privileged binaries.
>>
>> The changelog doesn't explain the semantics of the new syscall.
>> There's a comment way-down-there which I guess suffices, if you hunt
>> for it.
>>
>> And the changelog doesn't explain why this is being added.  Presumably
>> seccomp_filter wants/needs this feature but whowhatwherewhenwhy?  Spell
>> it all out, please.
>>
>> The new syscall mode will be documented in the prctl manpage.  Please
>> cc linux-man@vger.kernel.org and work with Michael on getting this
>> done?
> 
> This has been bugging me for awhile.  Is there any interest in moving
> the manpages into the kernel source tree?

Not that I know of. I'm pretty sure if the guy maintaining it (Michael
Kerrisk) wanted to do that, he could have raised the issue at any time
over the past several years.

> Then there could be a
> general requirement that new APIs get documented when they're written.

Because having a Documentation directory, javadoc in the source itself
(some of which is combined with the Documentation/DocBook xml files to
form the make htmldocs output), menuconfig help text, and a whole buch
of scattered readmes does _not_ get new APIs documented as they're written.

That isn't even counting git commit comments and mailing list messages
in various web archives. Are you going to suck the linux weekly news
kernel articles into the tree (http://lwn.net/Kernel/Index)? How about
Linux Journal's complete archives going back to 2004
(http://www.linuxjournal.com/magazine)? Or the h-online and
kernelnewbies writeups? How about wikipedia pages on interesting kernel
topics? The sourceforge pages for userspace projects like lxc.sf.net or
i2c-utils? How about that device driver writing tutorial Greg KH
recorded in 2008, that's only a 2.8 gigabyte video file.  Rusty's
Unreliable Guides?  Greg KH's blog? (Heck, http://kernelplanet.org).

Speaking of videos, here's the 2011 LinuxCon Japan talks:

  http://video.linux.com/categories/2011-linuxcon-japan

And here are videos for the Consumer Electronic Linux Forum:

  http://free-electrons.com/blog/elc-2012-videos/

(and you can get 2011, 2010, 2006...)

Here are Ottawa Linux Symposium papers:

  http://kernel.org/doc/ols

Don't forget IBM Developerworks' library:

http://www.ibm.com/developerworks/linux/library/l-linux-kernel/

Have some standards documents:

http://www.opengroup.org/onlinepubs/9699919799/
http://busybox.net/~landley/c99-draft.html
http://www.unix.org/whitepapers/64bit.html
http://refspecs.linuxfoundation.org
http://t10.org/scsi-3.htm

Here's a random blog post about booting a bare metal "hello world"
program on qemu for ARM:

http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/

Let's pick a topic, like the ELF loader. Here's the best introduction of
how ELF files _really_ work I've seen:

http://muppetlabs.com/~breadbox/software/tiny/teensy.html

Although http://linuxjournal.com/article/1059 is pretty good too, as
were http://linuxjournal.com/article/1060 and
http://linuxjournal.com/article/80 as well.  And if you want the
_details_, here's an extremely dry online book:

http;//www.iecc.com/linker/

And here's the first entry in the blog series the guy who wrote "gold"
did about writing his new linker:

http://www.airs.com/blog/archives/38

And so on, and so forth...

> (There are plenty of barely- or incompletely-documented syscalls.
> futex and relatives come to mind.)

Your proposal does not address this problem.

speaking of syscalls, I do note that ever since I tried to add Hexagon
support to strace (less fun than it sounds), I've wanted a way to beat
proper syscall information out of the kernel headers so I could get not
just syscall numbers but how many arguments and a brief stab at the type
of each argument.

Of course you _can_ get argument type and count, but not from the
headers: you have to use moderately horrible sed on the kernel's source
code, ala:

find . -name "*.c" -print0 | \
xargs -n1 -0 sed -n -e 's/.*\(SYSCALL_DEFINE[0-9](\)/\1/' \
  -e 't got;d;:got;s/).*/)/p;t;N;b got'

> --Andy

Rob
-- 
GNU/Linux isn't: Linux=GPLv2, GNU=GPLv3+, they can't share code.
Either it's "mere aggregation", or a license violation.  Pick one.

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-06 20:28         ` [kernel-hardening] " Jonathan Corbet
@ 2012-04-11 19:31           ` Michael Kerrisk (man-pages)
  -1 siblings, 0 replies; 146+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-11 19:31 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: Andrew Lutomirski, Andrew Morton, Will Drewry, linux-kernel,
	linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, eparis, serge.hallyn, djm, scarybeasts, indan,
	pmoore, eric.dumazet, markus, coreyb, keescook, jmorris,
	Andy Lutomirski, linux-man

On Sat, Apr 7, 2012 at 8:28 AM, Jonathan Corbet <corbet@lwn.net> wrote:
> On Fri, 6 Apr 2012 13:01:17 -0700
> Andrew Lutomirski <luto@mit.edu> wrote:
>
>> This has been bugging me for awhile.  Is there any interest in moving
>> the manpages into the kernel source tree?  Then there could be a
>> general requirement that new APIs get documented when they're written.
>
> Man page (or other documentation) requirements for patch acceptance are a
> regular kernel summit feature.  People seem to think it's a good idea, but
> actual enforcement of such requirements always seems to be lacking.  Lots
> of people have kind of given up trying.  I don't really see that adding
> the man pages to the tree would help, but I could be wrong...

I largely consider this (moving man pages to kernel.org) a technical
solution to what is fundamentally a social problem (developers
reluctant to write documentation), and doubt that the technical
solution would make much difference. I'd love to be proved wrong, but
the experiment would require significant start-up effort. (My
collected thoughts on this can be found here:
http://www.kernel.org/doc/man-pages/todo.html#migrate_to_kernel_source.
Note the alternative idea of patch tags mentioned at the end of that
text.)

Unless, or until there's a paid maintainer, I don't expect things to
get significantly better than what they currently are. The quite
significant improvements in man-pages since 2004, when I became
maintainer were in small part due to the fact that I was for a short
period paid to do the work, but in much larger part due to a huge
private effort over those years which over the last couple of years is
no longer unsustainable for me (man-pages is in competition with
requirements for my attention from family, working life, and
(seriously!) seismic events),

Cheers,

Michael


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-11 19:31           ` Michael Kerrisk (man-pages)
  0 siblings, 0 replies; 146+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-11 19:31 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: Andrew Lutomirski, Andrew Morton, Will Drewry, linux-kernel,
	linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, eparis, serge.hallyn, djm, scarybeasts, indan,
	pmoore, eric.dumazet, markus, coreyb, keescook, jmorris,
	Andy Lutomirski, linux-man

On Sat, Apr 7, 2012 at 8:28 AM, Jonathan Corbet <corbet@lwn.net> wrote:
> On Fri, 6 Apr 2012 13:01:17 -0700
> Andrew Lutomirski <luto@mit.edu> wrote:
>
>> This has been bugging me for awhile.  Is there any interest in moving
>> the manpages into the kernel source tree?  Then there could be a
>> general requirement that new APIs get documented when they're written.
>
> Man page (or other documentation) requirements for patch acceptance are a
> regular kernel summit feature.  People seem to think it's a good idea, but
> actual enforcement of such requirements always seems to be lacking.  Lots
> of people have kind of given up trying.  I don't really see that adding
> the man pages to the tree would help, but I could be wrong...

I largely consider this (moving man pages to kernel.org) a technical
solution to what is fundamentally a social problem (developers
reluctant to write documentation), and doubt that the technical
solution would make much difference. I'd love to be proved wrong, but
the experiment would require significant start-up effort. (My
collected thoughts on this can be found here:
http://www.kernel.org/doc/man-pages/todo.html#migrate_to_kernel_source.
Note the alternative idea of patch tags mentioned at the end of that
text.)

Unless, or until there's a paid maintainer, I don't expect things to
get significantly better than what they currently are. The quite
significant improvements in man-pages since 2004, when I became
maintainer were in small part due to the fact that I was for a short
period paid to do the work, but in much larger part due to a huge
private effort over those years which over the last couple of years is
no longer unsustainable for me (man-pages is in competition with
requirements for my attention from family, working life, and
(seriously!) seismic events),

Cheers,

Michael


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-11 19:31           ` [kernel-hardening] " Michael Kerrisk (man-pages)
@ 2012-04-12  0:15             ` Michael Kerrisk (man-pages)
  -1 siblings, 0 replies; 146+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-12  0:15 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: Andrew Lutomirski, Andrew Morton, Will Drewry, linux-kernel,
	linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, eparis, serge.hallyn, djm, scarybeasts, indan,
	pmoore, eric.dumazet, markus, coreyb, keescook, jmorris,
	Andy Lutomirski, linux-man

> no longer unsustainable for me (man-pages is in competition with

^no longer unsustainable^no longer sustainable

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-12  0:15             ` Michael Kerrisk (man-pages)
  0 siblings, 0 replies; 146+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-12  0:15 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: Andrew Lutomirski, Andrew Morton, Will Drewry, linux-kernel,
	linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, eparis, serge.hallyn, djm, scarybeasts, indan,
	pmoore, eric.dumazet, markus, coreyb, keescook, jmorris,
	Andy Lutomirski, linux-man

> no longer unsustainable for me (man-pages is in competition with

^no longer unsustainable^no longer sustainable

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-11 19:31           ` [kernel-hardening] " Michael Kerrisk (man-pages)
@ 2012-04-12  0:50             ` Andrew Lutomirski
  -1 siblings, 0 replies; 146+ messages in thread
From: Andrew Lutomirski @ 2012-04-12  0:50 UTC (permalink / raw)
  To: mtk.manpages
  Cc: Jonathan Corbet, Andrew Morton, Will Drewry, linux-kernel,
	linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, eparis, serge.hallyn, djm, scarybeasts, indan,
	pmoore, eric.dumazet, markus, coreyb, keescook, jmorris,
	Andy Lutomirski, linux-man

On Wed, Apr 11, 2012 at 12:31 PM, Michael Kerrisk (man-pages)
<mtk.manpages@gmail.com> wrote:
> On Sat, Apr 7, 2012 at 8:28 AM, Jonathan Corbet <corbet@lwn.net> wrote:
>> On Fri, 6 Apr 2012 13:01:17 -0700
>> Andrew Lutomirski <luto@mit.edu> wrote:
>>
>>> This has been bugging me for awhile.  Is there any interest in moving
>>> the manpages into the kernel source tree?  Then there could be a
>>> general requirement that new APIs get documented when they're written.
>>
>> Man page (or other documentation) requirements for patch acceptance are a
>> regular kernel summit feature.  People seem to think it's a good idea, but
>> actual enforcement of such requirements always seems to be lacking.  Lots
>> of people have kind of given up trying.  I don't really see that adding
>> the man pages to the tree would help, but I could be wrong...
>
> I largely consider this (moving man pages to kernel.org) a technical
> solution to what is fundamentally a social problem (developers
> reluctant to write documentation), and doubt that the technical
> solution would make much difference. I'd love to be proved wrong, but
> the experiment would require significant start-up effort. (My
> collected thoughts on this can be found here:
> http://www.kernel.org/doc/man-pages/todo.html#migrate_to_kernel_source.
> Note the alternative idea of patch tags mentioned at the end of that
> text.)
>
> Unless, or until there's a paid maintainer, I don't expect things to
> get significantly better than what they currently are. The quite
> significant improvements in man-pages since 2004, when I became
> maintainer were in small part due to the fact that I was for a short
> period paid to do the work, but in much larger part due to a huge
> private effort over those years which over the last couple of years is
> no longer unsustainable for me (man-pages is in competition with
> requirements for my attention from family, working life, and
> (seriously!) seismic events),

Hrm.  Maybe someone could convince Andrew and Linus not to pull new
syscalls or major ABI features unless the patchset includes full docs.

Anyway, I'll write up a detailed description of PR_SET_NO_NEW_PRIVS,
stick it in the changelog, and cc linux-doc.

--Andy

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-12  0:50             ` Andrew Lutomirski
  0 siblings, 0 replies; 146+ messages in thread
From: Andrew Lutomirski @ 2012-04-12  0:50 UTC (permalink / raw)
  To: mtk.manpages
  Cc: Jonathan Corbet, Andrew Morton, Will Drewry, linux-kernel,
	linux-security-module, linux-arch, linux-doc, kernel-hardening,
	netdev, x86, arnd, davem, hpa, mingo, oleg, peterz, rdunlap,
	mcgrathr, tglx, eparis, serge.hallyn, djm, scarybeasts, indan,
	pmoore, eric.dumazet, markus, coreyb, keescook, jmorris,
	Andy Lutomirski, linux-man

On Wed, Apr 11, 2012 at 12:31 PM, Michael Kerrisk (man-pages)
<mtk.manpages@gmail.com> wrote:
> On Sat, Apr 7, 2012 at 8:28 AM, Jonathan Corbet <corbet@lwn.net> wrote:
>> On Fri, 6 Apr 2012 13:01:17 -0700
>> Andrew Lutomirski <luto@mit.edu> wrote:
>>
>>> This has been bugging me for awhile.  Is there any interest in moving
>>> the manpages into the kernel source tree?  Then there could be a
>>> general requirement that new APIs get documented when they're written.
>>
>> Man page (or other documentation) requirements for patch acceptance are a
>> regular kernel summit feature.  People seem to think it's a good idea, but
>> actual enforcement of such requirements always seems to be lacking.  Lots
>> of people have kind of given up trying.  I don't really see that adding
>> the man pages to the tree would help, but I could be wrong...
>
> I largely consider this (moving man pages to kernel.org) a technical
> solution to what is fundamentally a social problem (developers
> reluctant to write documentation), and doubt that the technical
> solution would make much difference. I'd love to be proved wrong, but
> the experiment would require significant start-up effort. (My
> collected thoughts on this can be found here:
> http://www.kernel.org/doc/man-pages/todo.html#migrate_to_kernel_source.
> Note the alternative idea of patch tags mentioned at the end of that
> text.)
>
> Unless, or until there's a paid maintainer, I don't expect things to
> get significantly better than what they currently are. The quite
> significant improvements in man-pages since 2004, when I became
> maintainer were in small part due to the fact that I was for a short
> period paid to do the work, but in much larger part due to a huge
> private effort over those years which over the last couple of years is
> no longer unsustainable for me (man-pages is in competition with
> requirements for my attention from family, working life, and
> (seriously!) seismic events),

Hrm.  Maybe someone could convince Andrew and Linus not to pull new
syscalls or major ABI features unless the patchset includes full docs.

Anyway, I'll write up a detailed description of PR_SET_NO_NEW_PRIVS,
stick it in the changelog, and cc linux-doc.

--Andy

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

* Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
  2012-04-11 19:31           ` [kernel-hardening] " Michael Kerrisk (man-pages)
@ 2012-04-16 19:11             ` Rob Landley
  -1 siblings, 0 replies; 146+ messages in thread
From: Rob Landley @ 2012-04-16 19:11 UTC (permalink / raw)
  To: mtk.manpages
  Cc: Jonathan Corbet, Andrew Lutomirski, Andrew Morton, Will Drewry,
	linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski, linux-man

On 04/11/2012 02:31 PM, Michael Kerrisk (man-pages) wrote:
> On Sat, Apr 7, 2012 at 8:28 AM, Jonathan Corbet <corbet@lwn.net> wrote:
>> On Fri, 6 Apr 2012 13:01:17 -0700
>> Andrew Lutomirski <luto@mit.edu> wrote:
>>
>>> This has been bugging me for awhile.  Is there any interest in moving
>>> the manpages into the kernel source tree?  Then there could be a
>>> general requirement that new APIs get documented when they're written.
>>
>> Man page (or other documentation) requirements for patch acceptance are a
>> regular kernel summit feature.  People seem to think it's a good idea, but
>> actual enforcement of such requirements always seems to be lacking.  Lots
>> of people have kind of given up trying.  I don't really see that adding
>> the man pages to the tree would help, but I could be wrong...
> 
> I largely consider this (moving man pages to kernel.org) a technical
> solution to what is fundamentally a social problem (developers
> reluctant to write documentation), and doubt that the technical
> solution would make much difference.

*nod* *nod*

> I'd love to be proved wrong, but
> the experiment would require significant start-up effort. (My
> collected thoughts on this can be found here:
> http://www.kernel.org/doc/man-pages/todo.html#migrate_to_kernel_source.
> Note the alternative idea of patch tags mentioned at the end of that
> text.)
> 
> Unless, or until there's a paid maintainer, I don't expect things to
> get significantly better than what they currently are.

Maintainer of which, the man pages or the kernel Documentation directory?

I just got handed the Documentation ball (right as relatives were
visiting and a couple days before buying a new house, so I've just put
_tons_ of time into it so far). I have grandiose plans for cleaning it
up, but first I need to get my kernel.org account working again.

That said, I think having man-pages in the kernel directory is a bad
idea, for reasons I already posted to this thread.

> The quite
> significant improvements in man-pages since 2004, when I became
> maintainer were in small part due to the fact that I was for a short
> period paid to do the work, but in much larger part due to a huge
> private effort over those years which over the last couple of years is
> no longer unsustainable for me (man-pages is in competition with
> requirements for my attention from family, working life, and
> (seriously!) seismic events),

Heh, I know the feeling. :)

Circa 2007 I was paid to work on documentation for half a year (hence
the http://kernel.org/doc directory I stopped being able to update when
kernel.org got hacked). These days it competes with my toybox and
aboriginal linux projects, and with my day job.

The way I'm looking at it is I'm _curating_ documentation.  I'm acting
as some kind of of librarian, and my first goal is reshuffling the files
in Documentation into some semblance of order so you can see what's
there.  (I've posted about that before here, moving
architecture-specific stuff under an arch subdirectory and so on.)

I do sometimes write new documentation, but no human being knows
everything there is to know about the kernel. Building expertise is
enormously time consuming,

That said, if anything was going to move into the kernel moving the
syscall info into javadoc might make sense.

Something that might help you is the syscall mining script snippet I
posted last time:

find . -name "*.c" -print0 | \
xargs -n1 -0 sed -n -e 's/.*\(SYSCALL_DEFINE[0-9](\)/\1/' \
  -e 't got;d;:got;s/).*/)/p;t;N;b got'

I might be able to build a script around that which would look up the
system call number, figure out which architectures implement this call,
find any javadoc at the call site, and so on. That way we could automate
this a bit.  For example, kernel/fork.c has two syscalls:

SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr)

/*
 * unshare allows a process to 'unshare' part of the process
 * context which was originally shared using clone.  copy_*
 * functions used by do_fork() cannot be used here directly
 * because they modify an inactive task_struct that is being
 * constructed. Here we are modifying the current, active,
 * task_struct.
 */
SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)

Both of these have man pages which provide way more info than the
comments (if any). Is there any sort of javadoc comment before the
syscall that might provide useful information you could automatically
harvest?  Some sort of standard header briefly defining the syscall?

(P.S. Speaking of man 2 unshare, what's with the #define _GNU_SOURCE for
a new linux kernel syscall? What the heck does the FSF have to do with
anything? This didn't used to be needed in ubuntu 10.04 but then the
headers changed to match the man page, which I found sad...)

> Cheers,
> 
> Michael

Rob
-- 
GNU/Linux isn't: Linux=GPLv2, GNU=GPLv3+, they can't share code.
Either it's "mere aggregation", or a license violation.  Pick one.

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

* [kernel-hardening] Re: [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs
@ 2012-04-16 19:11             ` Rob Landley
  0 siblings, 0 replies; 146+ messages in thread
From: Rob Landley @ 2012-04-16 19:11 UTC (permalink / raw)
  To: mtk.manpages
  Cc: Jonathan Corbet, Andrew Lutomirski, Andrew Morton, Will Drewry,
	linux-kernel, linux-security-module, linux-arch, linux-doc,
	kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
	peterz, rdunlap, mcgrathr, tglx, eparis, serge.hallyn, djm,
	scarybeasts, indan, pmoore, eric.dumazet, markus, coreyb,
	keescook, jmorris, Andy Lutomirski, linux-man

On 04/11/2012 02:31 PM, Michael Kerrisk (man-pages) wrote:
> On Sat, Apr 7, 2012 at 8:28 AM, Jonathan Corbet <corbet@lwn.net> wrote:
>> On Fri, 6 Apr 2012 13:01:17 -0700
>> Andrew Lutomirski <luto@mit.edu> wrote:
>>
>>> This has been bugging me for awhile.  Is there any interest in moving
>>> the manpages into the kernel source tree?  Then there could be a
>>> general requirement that new APIs get documented when they're written.
>>
>> Man page (or other documentation) requirements for patch acceptance are a
>> regular kernel summit feature.  People seem to think it's a good idea, but
>> actual enforcement of such requirements always seems to be lacking.  Lots
>> of people have kind of given up trying.  I don't really see that adding
>> the man pages to the tree would help, but I could be wrong...
> 
> I largely consider this (moving man pages to kernel.org) a technical
> solution to what is fundamentally a social problem (developers
> reluctant to write documentation), and doubt that the technical
> solution would make much difference.

*nod* *nod*

> I'd love to be proved wrong, but
> the experiment would require significant start-up effort. (My
> collected thoughts on this can be found here:
> http://www.kernel.org/doc/man-pages/todo.html#migrate_to_kernel_source.
> Note the alternative idea of patch tags mentioned at the end of that
> text.)
> 
> Unless, or until there's a paid maintainer, I don't expect things to
> get significantly better than what they currently are.

Maintainer of which, the man pages or the kernel Documentation directory?

I just got handed the Documentation ball (right as relatives were
visiting and a couple days before buying a new house, so I've just put
_tons_ of time into it so far). I have grandiose plans for cleaning it
up, but first I need to get my kernel.org account working again.

That said, I think having man-pages in the kernel directory is a bad
idea, for reasons I already posted to this thread.

> The quite
> significant improvements in man-pages since 2004, when I became
> maintainer were in small part due to the fact that I was for a short
> period paid to do the work, but in much larger part due to a huge
> private effort over those years which over the last couple of years is
> no longer unsustainable for me (man-pages is in competition with
> requirements for my attention from family, working life, and
> (seriously!) seismic events),

Heh, I know the feeling. :)

Circa 2007 I was paid to work on documentation for half a year (hence
the http://kernel.org/doc directory I stopped being able to update when
kernel.org got hacked). These days it competes with my toybox and
aboriginal linux projects, and with my day job.

The way I'm looking at it is I'm _curating_ documentation.  I'm acting
as some kind of of librarian, and my first goal is reshuffling the files
in Documentation into some semblance of order so you can see what's
there.  (I've posted about that before here, moving
architecture-specific stuff under an arch subdirectory and so on.)

I do sometimes write new documentation, but no human being knows
everything there is to know about the kernel. Building expertise is
enormously time consuming,

That said, if anything was going to move into the kernel moving the
syscall info into javadoc might make sense.

Something that might help you is the syscall mining script snippet I
posted last time:

find . -name "*.c" -print0 | \
xargs -n1 -0 sed -n -e 's/.*\(SYSCALL_DEFINE[0-9](\)/\1/' \
  -e 't got;d;:got;s/).*/)/p;t;N;b got'

I might be able to build a script around that which would look up the
system call number, figure out which architectures implement this call,
find any javadoc at the call site, and so on. That way we could automate
this a bit.  For example, kernel/fork.c has two syscalls:

SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr)

/*
 * unshare allows a process to 'unshare' part of the process
 * context which was originally shared using clone.  copy_*
 * functions used by do_fork() cannot be used here directly
 * because they modify an inactive task_struct that is being
 * constructed. Here we are modifying the current, active,
 * task_struct.
 */
SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)

Both of these have man pages which provide way more info than the
comments (if any). Is there any sort of javadoc comment before the
syscall that might provide useful information you could automatically
harvest?  Some sort of standard header briefly defining the syscall?

(P.S. Speaking of man 2 unshare, what's with the #define _GNU_SOURCE for
a new linux kernel syscall? What the heck does the FSF have to do with
anything? This didn't used to be needed in ubuntu 10.04 but then the
headers changed to match the man page, which I found sad...)

> Cheers,
> 
> Michael

Rob
-- 
GNU/Linux isn't: Linux=GPLv2, GNU=GPLv3+, they can't share code.
Either it's "mere aggregation", or a license violation.  Pick one.

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

end of thread, other threads:[~2012-04-16 19:11 UTC | newest]

Thread overview: 146+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-29 20:01 [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering Will Drewry
2012-03-29 20:01 ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 01/15] Add PR_{GET,SET}_NO_NEW_PRIVS to prevent execve from granting privs Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-04-06 19:49   ` Andrew Morton
2012-04-06 19:49     ` [kernel-hardening] " Andrew Morton
2012-04-06 19:55     ` Andy Lutomirski
2012-04-06 19:55       ` [kernel-hardening] " Andy Lutomirski
2012-04-06 19:55       ` Andy Lutomirski
2012-04-06 20:47     ` Markus Gutschke
2012-04-06 20:47       ` [kernel-hardening] " Markus Gutschke
2012-04-06 20:54       ` Andrew Lutomirski
2012-04-06 20:54         ` [kernel-hardening] " Andrew Lutomirski
2012-04-06 21:04         ` Markus Gutschke
2012-04-06 21:04           ` [kernel-hardening] " Markus Gutschke
2012-04-06 21:15           ` Andrew Lutomirski
2012-04-06 21:15             ` [kernel-hardening] " Andrew Lutomirski
2012-04-06 21:32             ` Markus Gutschke
2012-04-06 21:32               ` [kernel-hardening] " Markus Gutschke
2012-04-10 19:12     ` Will Drewry
2012-04-10 19:12       ` [kernel-hardening] " Will Drewry
2012-04-06 19:55   ` Andrew Morton
2012-04-06 19:55     ` [kernel-hardening] " Andrew Morton
2012-04-06 19:55     ` Andrew Morton
2012-04-06 20:01     ` Andrew Lutomirski
2012-04-06 20:01       ` [kernel-hardening] " Andrew Lutomirski
2012-04-06 20:28       ` Jonathan Corbet
2012-04-06 20:28         ` [kernel-hardening] " Jonathan Corbet
2012-04-06 20:37         ` Andrew Lutomirski
2012-04-06 20:37           ` [kernel-hardening] " Andrew Lutomirski
2012-04-11 19:31         ` Michael Kerrisk (man-pages)
2012-04-11 19:31           ` [kernel-hardening] " Michael Kerrisk (man-pages)
2012-04-12  0:15           ` Michael Kerrisk (man-pages)
2012-04-12  0:15             ` [kernel-hardening] " Michael Kerrisk (man-pages)
2012-04-12  0:50           ` Andrew Lutomirski
2012-04-12  0:50             ` [kernel-hardening] " Andrew Lutomirski
2012-04-16 19:11           ` Rob Landley
2012-04-16 19:11             ` [kernel-hardening] " Rob Landley
2012-04-10 20:37       ` Rob Landley
2012-04-10 20:37         ` [kernel-hardening] " Rob Landley
2012-04-10 19:03     ` Will Drewry
2012-04-10 19:03       ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 02/15] Fix apparmor for PR_{GET,SET}_NO_NEW_PRIVS Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 03/15] sk_run_filter: add BPF_S_ANC_SECCOMP_LD_W Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 04/15] net/compat.c,linux/filter.h: share compat_sock_fprog Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 05/15] seccomp: kill the seccomp_t typedef Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 06/15] arch/x86: add syscall_get_arch to syscall.h Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 07/15] asm/syscall.h: add syscall_get_arch Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-04-06 20:05   ` Andrew Morton
2012-04-06 20:05     ` [kernel-hardening] " Andrew Morton
2012-04-09 19:24     ` Will Drewry
2012-04-09 19:24       ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 08/15] seccomp: add system call filtering using BPF Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-03-31  4:40   ` Vladimir Murzin
2012-03-31  4:40     ` [kernel-hardening] " Vladimir Murzin
2012-03-31 18:14     ` Will Drewry
2012-03-31 18:14       ` [kernel-hardening] " Will Drewry
2012-04-06 20:23   ` Andrew Morton
2012-04-06 20:23     ` [kernel-hardening] " Andrew Morton
2012-04-06 20:44     ` Kees Cook
2012-04-06 20:44       ` [kernel-hardening] " Kees Cook
2012-04-06 21:05       ` Andrew Morton
2012-04-06 21:05         ` [kernel-hardening] " Andrew Morton
2012-04-06 21:06         ` H. Peter Anvin
2012-04-06 21:06           ` [kernel-hardening] " H. Peter Anvin
2012-04-06 21:09           ` Andrew Morton
2012-04-06 21:09             ` [kernel-hardening] " Andrew Morton
2012-04-08 18:22     ` Indan Zupancic
2012-04-08 18:22       ` [kernel-hardening] " Indan Zupancic
2012-04-09 19:59       ` Will Drewry
2012-04-09 19:59         ` [kernel-hardening] " Will Drewry
2012-04-10  9:48         ` James Morris
2012-04-10  9:48           ` [kernel-hardening] " James Morris
2012-04-10 20:00         ` Andrew Morton
2012-04-10 20:00           ` [kernel-hardening] " Andrew Morton
2012-04-10 20:16           ` Will Drewry
2012-04-10 20:16             ` [kernel-hardening] " Will Drewry
2012-04-10 20:16             ` Will Drewry
2012-04-10 10:34       ` Eric Dumazet
2012-04-10 10:34         ` [kernel-hardening] " Eric Dumazet
2012-04-10 19:54       ` Andrew Morton
2012-04-10 19:54         ` [kernel-hardening] " Andrew Morton
2012-04-10 20:15         ` Will Drewry
2012-04-10 20:15           ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 09/15] seccomp: remove duplicated failure logging Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-04-06 21:14   ` Andrew Morton
2012-04-06 21:14     ` [kernel-hardening] " Andrew Morton
2012-04-09 19:26     ` Will Drewry
2012-04-09 19:26       ` [kernel-hardening] " Will Drewry
2012-04-09 19:26       ` Will Drewry
2012-04-09 19:32       ` Kees Cook
2012-04-09 19:32         ` [kernel-hardening] " Kees Cook
2012-04-09 19:33       ` Eric Paris
2012-04-09 19:33         ` Eric Paris
2012-04-09 19:39         ` [kernel-hardening] " Kees Cook
2012-04-09 19:39           ` Kees Cook
2012-03-29 20:01 ` [PATCH v17 10/15] seccomp: add SECCOMP_RET_ERRNO Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-04-06 21:19   ` Andrew Morton
2012-04-06 21:19     ` [kernel-hardening] " Andrew Morton
2012-04-09 19:19     ` Will Drewry
2012-04-09 19:19       ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 11/15] signal, x86: add SIGSYS info and make it synchronous Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 12/15] seccomp: Add SECCOMP_RET_TRAP Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 13/15] ptrace,seccomp: Add PTRACE_SECCOMP support Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-04-06 21:24   ` Andrew Morton
2012-04-06 21:24     ` [kernel-hardening] " Andrew Morton
2012-04-09 19:38     ` Will Drewry
2012-04-09 19:38       ` [kernel-hardening] " Will Drewry
2012-03-29 20:01 ` [PATCH v17 14/15] x86: Enable HAVE_ARCH_SECCOMP_FILTER Will Drewry
2012-03-29 20:01   ` [kernel-hardening] " Will Drewry
2012-03-29 20:02 ` [PATCH v17 15/15] Documentation: prctl/seccomp_filter Will Drewry
2012-03-29 20:02   ` [kernel-hardening] " Will Drewry
2012-04-06 21:26   ` Andrew Morton
2012-04-06 21:26     ` [kernel-hardening] " Andrew Morton
2012-04-09 19:46     ` Will Drewry
2012-04-09 19:46       ` [kernel-hardening] " Will Drewry
2012-04-09 20:47       ` Markus Gutschke
2012-04-09 20:47         ` [kernel-hardening] " Markus Gutschke
2012-04-09 20:58         ` Ryan Ware
2012-04-09 20:58           ` [kernel-hardening] " Ryan Ware
2012-04-09 20:58           ` Ryan Ware
2012-04-09 22:47           ` Will Drewry
2012-04-09 22:47             ` [kernel-hardening] " Will Drewry
2012-04-10 17:49             ` Ryan Ware
2012-04-10 17:49               ` [kernel-hardening] " Ryan Ware
2012-04-10 17:49               ` Ryan Ware
2012-03-29 23:11 ` [PATCH v17 00/15] seccomp_filter: BPF-based syscall filtering James Morris
2012-03-29 23:11   ` [kernel-hardening] " James Morris
2012-04-06 21:28   ` Andrew Morton
2012-04-06 21:28     ` [kernel-hardening] " Andrew Morton
2012-04-06 21:28     ` Andrew Morton
2012-04-09  3:48     ` James Morris
2012-04-09  3:48       ` [kernel-hardening] " James Morris
2012-04-09  3:48       ` James Morris

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.