linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: linux-kernel@vger.kernel.org
Cc: Kees Cook <keescook@chromium.org>,
	Sargun Dhillon <sargun@sargun.me>,
	Christian Brauner <christian@brauner.io>,
	"David S. Miller" <davem@davemloft.net>,
	Christoph Hellwig <hch@lst.de>, Tycho Andersen <tycho@tycho.ws>,
	Jakub Kicinski <kuba@kernel.org>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	Aleksa Sarai <cyphar@cyphar.com>,
	Matt Denton <mpdenton@google.com>, Jann Horn <jannh@google.com>,
	Chris Palmer <palmer@google.com>,
	Robert Sesek <rsesek@google.com>,
	Giuseppe Scrivano <gscrivan@redhat.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Andy Lutomirski <luto@amacapital.net>,
	Will Drewry <wad@chromium.org>, Shuah Khan <shuah@kernel.org>,
	netdev@vger.kernel.org, containers@lists.linux-foundation.org,
	linux-api@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-kselftest@vger.kernel.org
Subject: [PATCH v4 08/11] selftests/seccomp: Make kcmp() less required
Date: Mon, 15 Jun 2020 20:25:21 -0700	[thread overview]
Message-ID: <20200616032524.460144-9-keescook@chromium.org> (raw)
In-Reply-To: <20200616032524.460144-1-keescook@chromium.org>

The seccomp tests are a bit noisy without CONFIG_CHECKPOINT_RESTORE (due
to missing the kcmp() syscall). The seccomp tests are more accurate with
kcmp(), but it's not strictly required. Refactor the tests to use
alternatives (comparing fd numbers), and provide a central test for
kcmp() so there is a single XFAIL instead of many. Continue to produce
warnings for the other tests, though.

Additionally adds some more bad flag EINVAL tests to the addfd selftest.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 tools/testing/selftests/seccomp/seccomp_bpf.c | 100 +++++++++++-------
 1 file changed, 64 insertions(+), 36 deletions(-)

diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index c4e264b37c30..40ed846744e4 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -258,6 +258,27 @@ int seccomp(unsigned int op, unsigned int flags, void *args)
 #define SIBLING_EXIT_FAILURE	0xbadface
 #define SIBLING_EXIT_NEWPRIVS	0xbadfeed
 
+static int filecmp(pid_t pid1, pid_t pid2, int fd1, int fd2)
+{
+#ifdef __NR_kcmp
+	errno = 0;
+	return syscall(__NR_kcmp, pid1, pid2, KCMP_FILE, fd1, fd2);
+#else
+	errno = ENOSYS;
+	return -1;
+#endif
+}
+
+TEST(kcmp)
+{
+	int ret;
+
+	ret = filecmp(getpid(), getpid(), 1, 1);
+	EXPECT_EQ(ret, 0);
+	if (ret != 0 && errno == ENOSYS)
+		XFAIL(return, "Kernel does not support kcmp() (missing CONFIG_CHECKPOINT_RESTORE?)");
+}
+
 TEST(mode_strict_support)
 {
 	long ret;
@@ -3606,16 +3627,6 @@ TEST(seccomp_get_notif_sizes)
 	EXPECT_EQ(sizes.seccomp_notif_resp, sizeof(struct seccomp_notif_resp));
 }
 
-static int filecmp(pid_t pid1, pid_t pid2, int fd1, int fd2)
-{
-#ifdef __NR_kcmp
-	return syscall(__NR_kcmp, pid1, pid2, KCMP_FILE, fd1, fd2);
-#else
-	errno = ENOSYS;
-	return -1;
-#endif
-}
-
 TEST(user_notification_continue)
 {
 	pid_t pid;
@@ -3640,20 +3651,20 @@ TEST(user_notification_continue)
 		int dup_fd, pipe_fds[2];
 		pid_t self;
 
-		ret = pipe(pipe_fds);
-		if (ret < 0)
-			exit(1);
+		ASSERT_GE(pipe(pipe_fds), 0);
 
 		dup_fd = dup(pipe_fds[0]);
-		if (dup_fd < 0)
-			exit(1);
+		ASSERT_GE(dup_fd, 0);
+		EXPECT_NE(pipe_fds[0], dup_fd);
 
 		self = getpid();
-
 		ret = filecmp(self, self, pipe_fds[0], dup_fd);
-		if (ret)
-			exit(2);
-
+		if (ret != 0) {
+			if (ret < 0 && errno == ENOSYS) {
+				TH_LOG("kcmp() syscall missing (test is less accurate)");
+			} else
+				ASSERT_EQ(ret, 0);
+		}
 		exit(0);
 	}
 
@@ -3700,12 +3711,7 @@ TEST(user_notification_continue)
 skip:
 	EXPECT_EQ(waitpid(pid, &status, 0), pid);
 	EXPECT_EQ(true, WIFEXITED(status));
-	EXPECT_EQ(0, WEXITSTATUS(status)) {
-		if (WEXITSTATUS(status) == 2) {
-			XFAIL(return, "Kernel does not support kcmp() syscall");
-			return;
-		}
-	}
+	EXPECT_EQ(0, WEXITSTATUS(status));
 }
 
 TEST(user_notification_filter_empty)
@@ -3847,7 +3853,7 @@ TEST(user_notification_sendfd)
 {
 	pid_t pid;
 	long ret;
-	int status, listener, memfd;
+	int status, listener, memfd, fd;
 	struct seccomp_notif_addfd addfd = {};
 	struct seccomp_notif req = {};
 	struct seccomp_notif_resp resp = {};
@@ -3880,34 +3886,56 @@ TEST(user_notification_sendfd)
 
 	addfd.size = sizeof(addfd);
 	addfd.srcfd = memfd;
-	addfd.newfd_flags = O_CLOEXEC;
 	addfd.newfd = 0;
 	addfd.id = req.id;
-	addfd.flags = 0xff;
+	addfd.flags = 0;
+
+	/* Verify bad newfd_flags cannot be set */
+	addfd.newfd_flags = ~O_CLOEXEC;
+	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);
+	EXPECT_EQ(errno, EINVAL);
+	addfd.newfd_flags = O_CLOEXEC;
 
 	/* Verify bad flags cannot be set */
+	addfd.flags = 0xff;
 	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);
 	EXPECT_EQ(errno, EINVAL);
+	addfd.flags = 0;
 
 	/* Verify that remote_fd cannot be set without setting flags */
-	addfd.flags = 0;
 	addfd.newfd = 1;
 	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1);
 	EXPECT_EQ(errno, EINVAL);
-
-	/* Verify we can set an arbitrary remote fd */
 	addfd.newfd = 0;
 
-	ret = ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd);
-	EXPECT_GE(ret, 0);
-	EXPECT_EQ(filecmp(getpid(), pid, memfd, ret), 0);
+	/* Verify we can set an arbitrary remote fd */
+	fd = ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd);
+	/*
+	 * The child has fds 0(stdin), 1(stdout), 2(stderr), 3(memfd),
+	 * 4(listener), so the newly allocated fd should be 5.
+	 */
+	EXPECT_EQ(fd, 5);
+	ret = filecmp(getpid(), pid, memfd, fd);
+	if (ret != 0) {
+		if (ret < 0 && errno == ENOSYS) {
+			TH_LOG("kcmp() syscall missing (test is less accurate)");
+		} else
+			EXPECT_EQ(ret, 0);
+	}
 
 	/* Verify we can set a specific remote fd */
 	addfd.newfd = 42;
 	addfd.flags = SECCOMP_ADDFD_FLAG_SETFD;
 
-	EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), 42);
-	EXPECT_EQ(filecmp(getpid(), pid, memfd, 42), 0);
+	fd = ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd);
+	EXPECT_EQ(fd, 42);
+	ret = filecmp(getpid(), pid, memfd, fd);
+	if (ret != 0) {
+		if (ret < 0 && errno == ENOSYS) {
+			TH_LOG("kcmp() syscall missing (test is less accurate)");
+		} else
+			EXPECT_EQ(ret, 0);
+	}
 
 	resp.id = req.id;
 	resp.error = 0;
-- 
2.25.1


  parent reply	other threads:[~2020-06-16  3:26 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-16  3:25 [PATCH v4 00/11] Add seccomp notifier ioctl that enables adding fds Kees Cook
2020-06-16  3:25 ` [PATCH v4 01/11] net/scm: Regularize compat handling of scm_detach_fds() Kees Cook
2020-06-16  3:25 ` [PATCH v4 02/11] fs: Move __scm_install_fd() to __fd_install_received() Kees Cook
2020-06-16  5:29   ` Sargun Dhillon
2020-06-16  5:48     ` Kees Cook
2020-06-17 15:25   ` David Laight
2020-06-17 18:40     ` Kees Cook
2020-06-18  8:56   ` Christian Brauner
2020-06-18 20:05     ` Kees Cook
2020-06-16  3:25 ` [PATCH v4 03/11] fs: Add fd_install_received() wrapper for __fd_install_received() Kees Cook
2020-06-17 15:35   ` David Laight
2020-06-17 19:58     ` Kees Cook
2020-06-18  8:19       ` David Laight
2020-06-16  3:25 ` [PATCH v4 04/11] pidfd: Replace open-coded partial fd_install_received() Kees Cook
2020-06-16  3:25 ` [PATCH v4 05/11] fs: Expand __fd_install_received() to accept fd Kees Cook
2020-06-16  3:25 ` [PATCH v4 06/11] seccomp: Introduce addfd ioctl to seccomp user notifier Kees Cook
2020-06-16  3:25 ` [PATCH v4 07/11] selftests/seccomp: Test SECCOMP_IOCTL_NOTIF_ADDFD Kees Cook
2020-06-16  3:25 ` Kees Cook [this message]
2020-06-16 14:57   ` [PATCH v4 08/11] selftests/seccomp: Make kcmp() less required Tycho Andersen
2020-06-16 16:03     ` Kees Cook
2020-06-16  3:25 ` [PATCH v4 09/11] selftests/seccomp: Rename user_trap_syscall() to user_notif_syscall() Kees Cook
2020-06-16 14:56   ` Tycho Andersen
2020-06-16  3:25 ` [PATCH v4 10/11] seccomp: Switch addfd to Extensible Argument ioctl Kees Cook
2020-06-16 14:55   ` Tycho Andersen
2020-06-16 16:05     ` Kees Cook
2020-06-16 16:18       ` Tycho Andersen
2020-06-16  3:25 ` [PATCH v4 11/11] seccomp: Fix ioctl number for SECCOMP_IOCTL_NOTIF_ID_VALID Kees Cook
2020-06-18 22:16 ` [PATCH v4 00/11] Add seccomp notifier ioctl that enables adding fds Sargun Dhillon

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=20200616032524.460144-9-keescook@chromium.org \
    --to=keescook@chromium.org \
    --cc=christian@brauner.io \
    --cc=containers@lists.linux-foundation.org \
    --cc=cyphar@cyphar.com \
    --cc=davem@davemloft.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=gscrivan@redhat.com \
    --cc=hch@lst.de \
    --cc=jannh@google.com \
    --cc=kuba@kernel.org \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=mpdenton@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=palmer@google.com \
    --cc=rsesek@google.com \
    --cc=sargun@sargun.me \
    --cc=shuah@kernel.org \
    --cc=tycho@tycho.ws \
    --cc=viro@zeniv.linux.org.uk \
    --cc=wad@chromium.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).