All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tycho Andersen <tycho-E0fblnxP3wo@public.gmane.org>
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
Cc: Kees Cook <keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>,
	Akihiro Suda
	<suda.akihiro-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>,
	Oleg Nesterov <oleg-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
	Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>,
	"Eric W . Biederman"
	<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>,
	Christian Brauner
	<christian.brauner-GeWIH/nMZzLQT0dZR+AlfA@public.gmane.org>,
	Tyler Hicks <tyhicks-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
Subject: [RFC 3/3] seccomp: add a way to get a listener fd from ptrace
Date: Sun,  4 Feb 2018 11:49:46 +0100	[thread overview]
Message-ID: <20180204104946.25559-4-tycho__4675.53979619897$1517741358$gmane$org@tycho.ws> (raw)
In-Reply-To: <20180204104946.25559-1-tycho-E0fblnxP3wo@public.gmane.org>

As an alternative to SECCOMP_FILTER_FLAG_GET_LISTENER, perhaps a ptrace()
version which can acquire filters is useful. There are at least two reasons
this is preferable, even though it uses ptrace:

1. You can control tasks that aren't cooperating with you
2. You can control tasks whose filters block sendmsg() and socket(); if the
   task installs a filter which blocks these calls, there's no way with
   SECCOMP_FILTER_FLAG_GET_LISTENER to get the fd out to the privileged task.

Signed-off-by: Tycho Andersen <tycho-E0fblnxP3wo@public.gmane.org>
CC: Kees Cook <keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
CC: Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>
CC: Oleg Nesterov <oleg-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
CC: Eric W. Biederman <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
CC: "Serge E. Hallyn" <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org>
CC: Christian Brauner <christian.brauner-GeWIH/nMZzLQT0dZR+AlfA@public.gmane.org>
CC: Tyler Hicks <tyhicks-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
CC: Akihiro Suda <suda.akihiro-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
---
 include/linux/seccomp.h                       | 11 +++++
 include/uapi/linux/ptrace.h                   |  1 +
 kernel/ptrace.c                               |  4 ++
 kernel/seccomp.c                              | 24 ++++++++++
 tools/testing/selftests/seccomp/seccomp_bpf.c | 66 +++++++++++++++++++++++++++
 5 files changed, 106 insertions(+)

diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index ce07da2ffd53..0d4750e04bb1 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -103,4 +103,15 @@ static inline long seccomp_get_filter(struct task_struct *task,
 	return -EINVAL;
 }
 #endif /* CONFIG_SECCOMP_FILTER && CONFIG_CHECKPOINT_RESTORE */
+
+#ifdef CONFIG_SECCOMP_USER_NOTIFICATION
+extern long seccomp_get_listener(struct task_struct *task,
+				 unsigned long filter_off);
+#else
+static inline long seccomp_get_listener(struct task_struct *task,
+					unsigned long filter_off)
+{
+	return -EINVAL;
+}
+#endif/* CONFIG_SECCOMP_USER_NOTIFICATION */
 #endif /* _LINUX_SECCOMP_H */
diff --git a/include/uapi/linux/ptrace.h b/include/uapi/linux/ptrace.h
index e3939e00980b..60113de59b04 100644
--- a/include/uapi/linux/ptrace.h
+++ b/include/uapi/linux/ptrace.h
@@ -66,6 +66,7 @@ struct ptrace_peeksiginfo_args {
 #define PTRACE_SETSIGMASK	0x420b
 
 #define PTRACE_SECCOMP_GET_FILTER	0x420c
+#define PTRACE_SECCOMP_GET_LISTENER	0x420d
 
 /* Read signals from a shared (process wide) queue */
 #define PTRACE_PEEKSIGINFO_SHARED	(1 << 0)
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 84b1367935e4..50d8cc8be054 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -1092,6 +1092,10 @@ int ptrace_request(struct task_struct *child, long request,
 		ret = seccomp_get_filter(child, addr, datavp);
 		break;
 
+	case PTRACE_SECCOMP_GET_LISTENER:
+		ret = seccomp_get_listener(child, addr);
+		break;
+
 	default:
 		break;
 	}
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 800db3f2866f..0b1f65273d2a 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -1605,4 +1605,28 @@ static struct file *init_listener(struct seccomp_filter *filter)
 	mutex_unlock(&filter->notify_lock);
 	return ret;
 }
+
+long seccomp_get_listener(struct task_struct *task,
+			  unsigned long filter_off)
+{
+	struct seccomp_filter *filter;
+	struct file *listener;
+	int fd;
+
+	filter = get_nth_filter(task, filter_off);
+	if (IS_ERR(filter))
+		return PTR_ERR(filter);
+
+	listener = init_listener(filter);
+	if (IS_ERR(listener))
+		return PTR_ERR(listener);
+
+	fd = get_unused_fd_flags(O_RDWR);
+	if (fd < 0)
+		put_filp(listener);
+	else
+		fd_install(fd, listener);
+
+	return fd;
+}
 #endif
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index b43e2a70b08c..80f89a766895 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -168,6 +168,10 @@ int seccomp(unsigned int op, unsigned int flags, void *args)
 }
 #endif
 
+#ifndef PTRACE_SECCOMP_GET_LISTENER
+#define PTRACE_SECCOMP_GET_LISTENER 0x420d
+#endif
+
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 #define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))
 #elif __BYTE_ORDER == __BIG_ENDIAN
@@ -2957,6 +2961,68 @@ TEST(get_user_notification_syscall)
 	close(listener);
 }
 
+TEST(get_user_notification_ptrace)
+{
+	pid_t pid;
+	int status, listener;
+	int sk_pair[2];
+	char c;
+	struct seccomp_notif req;
+	struct seccomp_notif_resp resp;
+
+	ASSERT_EQ(socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair), 0);
+
+	pid = fork();
+	ASSERT_GE(pid, 0);
+
+	if (pid == 0) {
+		ASSERT_EQ(user_trap_syscall(__NR_getpid, 0), 0);
+
+		/* Test that we get ENOSYS while not attached */
+		ASSERT_EQ(syscall(__NR_getpid), -1);
+		ASSERT_EQ(errno, ENOSYS);
+
+		/* Signal we're ready and have installed the filter. */
+		ASSERT_EQ(write(sk_pair[1], "J", 1), 1);
+
+		ASSERT_EQ(read(sk_pair[1], &c, 1), 1);
+		ASSERT_EQ(c, 'H');
+
+		exit(syscall(__NR_getpid) != USER_NOTIF_MAGIC);
+	}
+
+	ASSERT_EQ(read(sk_pair[0], &c, 1), 1);
+	ASSERT_EQ(c, 'J');
+
+	ASSERT_EQ(ptrace(PTRACE_ATTACH, pid), 0);
+	ASSERT_EQ(waitpid(pid, NULL, 0), pid);
+	listener = ptrace(PTRACE_SECCOMP_GET_LISTENER, pid, 0);
+	ASSERT_GE(listener, 0);
+
+	/* EBUSY for second listener */
+	ASSERT_EQ(ptrace(PTRACE_SECCOMP_GET_LISTENER, pid, 0), -1);
+	ASSERT_EQ(errno, EBUSY);
+
+	ASSERT_EQ(ptrace(PTRACE_DETACH, pid, NULL, 0), 0);
+
+	/* Now signal we are done and respond with magic */
+	ASSERT_EQ(write(sk_pair[0], "H", 1), 1);
+
+	ASSERT_EQ(read(listener, &req, sizeof(req)), sizeof(req));
+
+	resp.id = req.id;
+	resp.error = 0;
+	resp.val = USER_NOTIF_MAGIC;
+
+	ASSERT_EQ(write(listener, &resp, sizeof(resp)), sizeof(resp));
+
+	ASSERT_EQ(waitpid(pid, &status, 0), pid);
+	ASSERT_EQ(true, WIFEXITED(status));
+	ASSERT_EQ(0, WEXITSTATUS(status));
+
+	close(listener);
+}
+
 /*
  * TODO:
  * - add microbenchmarks
-- 
2.14.1

  parent reply	other threads:[~2018-02-04 10:49 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-04 10:49 [RFC 0/3] seccomp trap to userspace Tycho Andersen
2018-02-04 10:49 ` [RFC 1/3] seccomp: add a return code to " Tycho Andersen
2018-02-13 21:09   ` Kees Cook
     [not found]     ` <CAGXu5jLAAKY19a9iC1PmXRyuwdn1Zxr2Cb318zdzkqgYt8vtdg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-14 15:29       ` Tycho Andersen
2018-02-14 15:29         ` Tycho Andersen
2018-02-14 17:19         ` Andy Lutomirski
2018-02-14 17:23           ` Tycho Andersen
2018-02-15 14:48           ` Christian Brauner
     [not found]           ` <CALCETrXeZZfVzXh7SwKhyB=+ySDk5fhrrdrXrcABsQ=JpQT7Tg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-14 17:23             ` Tycho Andersen
2018-02-15 14:48             ` Christian Brauner
2018-02-27  0:49             ` Kees Cook
2018-02-27  0:49           ` Kees Cook
     [not found]             ` <CAGXu5jKBmej+fXhEc+Jy7Guy+vXEZkHnc=4LNm1NNEsc1=DFVA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-27  3:27               ` Andy Lutomirski
2018-02-27  3:27                 ` Andy Lutomirski
2018-02-14 17:19         ` Andy Lutomirski
     [not found]   ` <20180204104946.25559-2-tycho-E0fblnxP3wo@public.gmane.org>
2018-02-04 17:36     ` Andy Lutomirski
2018-02-04 17:36       ` Andy Lutomirski
     [not found]       ` <CALCETrWgu5n+SMqrsZQ7MVYPtzs8otuc7hpA5uPH+JNtFrMBkQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-04 20:01         ` Tycho Andersen
2018-02-04 20:01           ` Tycho Andersen
2018-02-04 20:33           ` Andy Lutomirski
     [not found]             ` <CALCETrV81yr_zhuBbCTE8NgYx42oq=qvP=nLMsST0iS2wtOZng-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-05  8:47               ` Tycho Andersen
2018-02-05  8:47             ` Tycho Andersen
2018-02-04 20:33           ` Andy Lutomirski
2018-02-13 21:09     ` Kees Cook
2018-02-04 10:49 ` [RFC 2/3] seccomp: hoist out filter resolving logic Tycho Andersen
     [not found]   ` <20180204104946.25559-3-tycho-E0fblnxP3wo@public.gmane.org>
2018-02-13 21:29     ` Kees Cook
2018-02-13 21:29   ` Kees Cook
2018-02-14 15:33     ` Tycho Andersen
2018-02-14 15:33     ` Tycho Andersen
     [not found] ` <20180204104946.25559-1-tycho-E0fblnxP3wo@public.gmane.org>
2018-02-04 10:49   ` [RFC 1/3] seccomp: add a return code to trap to userspace Tycho Andersen
2018-02-04 10:49   ` [RFC 2/3] seccomp: hoist out filter resolving logic Tycho Andersen
2018-02-04 10:49   ` Tycho Andersen [this message]
2018-03-15 16:09   ` [RFC 0/3] seccomp trap to userspace Christian Brauner
2018-02-04 10:49 ` [RFC 3/3] seccomp: add a way to get a listener fd from ptrace Tycho Andersen
     [not found]   ` <20180204104946.25559-4-tycho-E0fblnxP3wo@public.gmane.org>
2018-02-13 21:32     ` Kees Cook
2018-02-13 21:32       ` Kees Cook
     [not found]       ` <CAGXu5jLS2dzCjZOKa-W4kUdOPoJkRAq5Rsw1t5jX99v34yaoQw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-14 15:33         ` Tycho Andersen
2018-02-14 15:33       ` Tycho Andersen
2018-03-15 16:09 ` [RFC 0/3] seccomp trap to userspace Christian Brauner
     [not found]   ` <20180315160924.GA12744-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2018-03-15 16:56     ` Andy Lutomirski
2018-03-15 16:56       ` Andy Lutomirski
2018-03-15 17:05       ` Serge E. Hallyn
2018-03-15 17:11         ` Andy Lutomirski
2018-03-15 17:35           ` Tycho Andersen
2018-03-16  0:46             ` Andy Lutomirski
2018-03-16  0:46               ` Andy Lutomirski
     [not found]               ` <CALCETrWH7HbY2gS6O_cYKfp9QqqWBWVcHb++GaP3uUiSO9oo6g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-03-16 14:47                 ` Christian Brauner
2018-03-16 14:47                   ` Christian Brauner
2018-03-16 16:01                   ` Andy Lutomirski
     [not found]                     ` <D73E5C37-DC92-4D58-A163-0B20143AAEEB-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>
2018-03-16 16:40                       ` Christian Brauner
2018-03-16 16:40                     ` Christian Brauner
     [not found]                   ` <20180316144751.GA3304-cl+VPiYnx/1AfugRpC6u6w@public.gmane.org>
2018-03-16 16:01                     ` Andy Lutomirski
     [not found]           ` <CALCETrXPcCNbpFJhXktkVS9gOPpmnU_bbY6Z8RrsBarq0dP4Lg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-03-15 17:25             ` Christian Brauner
2018-03-15 17:25               ` Christian Brauner
     [not found]               ` <20180315172558.GA28108-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2018-03-15 17:30                 ` Andy Lutomirski
2018-03-15 17:30                   ` Andy Lutomirski
2018-03-15 17:35             ` Tycho Andersen
     [not found]         ` <20180315170509.GA32766-7LNsyQBKDXoIagZqoN9o3w@public.gmane.org>
2018-03-15 17:11           ` Andy Lutomirski
     [not found]       ` <CALCETrVnvbZLx5v=DMu2N1JtR+ys507X5CYBi-qQnus3VMQdwg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-03-15 17:05         ` Serge E. Hallyn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='20180204104946.25559-4-tycho__4675.53979619897$1517741358$gmane$org@tycho.ws' \
    --to=tycho-e0fblnxp3wo@public.gmane.org \
    --cc=christian.brauner-GeWIH/nMZzLQT0dZR+AlfA@public.gmane.org \
    --cc=containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
    --cc=ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org \
    --cc=keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org \
    --cc=oleg-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=suda.akihiro-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org \
    --cc=tyhicks-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.