From patchwork Wed Oct 16 14:20:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 1177947 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=brauner.io Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=brauner.io header.i=@brauner.io header.b="cdWFKyg4"; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46tZFl6hngz9sQm; Thu, 17 Oct 2019 01:20:27 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1iKkA3-0004KC-TY; Wed, 16 Oct 2019 14:20:23 +0000 Received: from mail-wr1-f66.google.com ([209.85.221.66]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1iKkA0-0004J6-GK for kernel-team@lists.ubuntu.com; Wed, 16 Oct 2019 14:20:20 +0000 Received: by mail-wr1-f66.google.com with SMTP id r3so28309645wrj.6 for ; Wed, 16 Oct 2019 07:20:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brauner.io; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RCiB6GZvJyQUHRbeN8mGYGgDTfYoRHyH5M5eZcOmg18=; b=cdWFKyg4B3vFNPeQ7SV/WAySZQYlAil5Z8QezY2hwXpwquK8WpFh8+kPJWk4+XRgKC JkX//pyPcXVnASv93Ovn+drg61lFu7RVVQTkM0C9sdGwdMUHqnQIy/AM0l5+fANtoVtE OUGzbf3ARpdgU6/36mFtC0TOS8hoR7nyU5hFoKcGEmRsxrcYK8E+XiqpfTtaCX7wEkR9 9mlSgORaH3SU+lU2pdTU0r0pn11v3KpqigKvFhMcPd0coV7L5eo6pTgs9aQPcmDQ9eS9 WSUwyXzHmRYhm3a+EiO8sCojx4Z4UbgoAMP7vAIf1zn1gwuRyUhCBrr/D3FK//2+8qgN 8vLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RCiB6GZvJyQUHRbeN8mGYGgDTfYoRHyH5M5eZcOmg18=; b=bWffud6Eg6xZJDfzd8Y8jAJpj8YVeeXZGSDmNvSvDGyrPZdL+DJTHzUgIe667/Yxbj RlX8G267cDIVoPk1mFM8mwiKYDYOBQDKdoflwibqyZNGQH6RCSR4zTlr2GFv9rj34ebH VQesQkk/bzO0jTjGvz4fTVPnACKSc1evo1mSfLdH8Xele6lHGvKgINl3iUG/7rmKbdpv bnA3Gvxf9EIdUlMeDYfFbA7Tv/9RYLorKt/qebcjDlDGleOH/JWo9Tcln2H/9YstvDM0 TE1zoi934gMyI44A6dYpLSU2jj7/vYMOxoL57OBvQfRihxLPr1TDPwNMtdeDoJHq/0j1 GgRA== X-Gm-Message-State: APjAAAWfi43pPleerM4Dy9R0xdGPNbErzjEO2EtrKSq7Gi8ZF9G7nRR3 YwIn/IvPNMRZ2ATGjs+Rd2dufAlyR10QOA== X-Google-Smtp-Source: APXvYqzQ+7abK3iePegI6u/4MqtbqkGMSRwJglE4zi1VZ4hb+sBPhEVjcuBACgo65Kfz8fxMDGG2WA== X-Received: by 2002:adf:dbcf:: with SMTP id e15mr3031614wrj.134.1571235619879; Wed, 16 Oct 2019 07:20:19 -0700 (PDT) Received: from localhost.localdomain ([213.220.153.21]) by smtp.gmail.com with ESMTPSA id n22sm2579132wmk.19.2019.10.16.07.20.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Oct 2019 07:20:18 -0700 (PDT) From: Christian Brauner To: kernel-team@lists.ubuntu.com Subject: [PATCH 2/2][SRU][UNSTABLE] UBUNTU: SAUCE: seccomp: test SECCOMP_USER_NOTIF_FLAG_CONTINUE Date: Wed, 16 Oct 2019 16:20:06 +0200 Message-Id: <20191016142006.24975-3-christian@brauner.io> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191016142006.24975-1-christian@brauner.io> References: <20191016142006.24975-1-christian@brauner.io> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: stgraber@ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Christian Brauner BugLink: https://bugs.launchpad.net/bugs/1847744 Test whether a syscall can be performed after having been intercepted by the seccomp notifier. The test uses dup() and kcmp() since it allows us to nicely test whether the dup() syscall actually succeeded by comparing whether the fds refer to the same underlying struct file. Signed-off-by: Christian Brauner Cc: Andy Lutomirski Cc: Will Drewry Cc: Shuah Khan Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Martin KaFai Lau Cc: Song Liu Cc: Yonghong Song Cc: Tycho Andersen CC: Tyler Hicks Cc: stable@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Cc: netdev@vger.kernel.org Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20190920083007.11475-4-christian.brauner@ubuntu.com Signed-off-by: Kees Cook (cherry picked from commit 0eebfed2954f152259cae0ad57b91d3ea92968e8 https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git) Signed-off-by: Christian Brauner --- tools/testing/selftests/seccomp/seccomp_bpf.c | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 6ef7f16c4cf5..31a0e3daf326 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -166,6 +167,10 @@ struct seccomp_metadata { #define SECCOMP_RET_USER_NOTIF 0x7fc00000U +#ifndef SECCOMP_USER_NOTIF_FLAG_CONTINUE +#define SECCOMP_USER_NOTIF_FLAG_CONTINUE 0x00000001 +#endif + #define SECCOMP_IOC_MAGIC '!' #define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr) #define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type) @@ -3480,6 +3485,108 @@ 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; + long ret; + int status, listener; + struct seccomp_notif req = {}; + struct seccomp_notif_resp resp = {}; + struct pollfd pollfd; + + ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + ASSERT_EQ(0, ret) { + TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!"); + } + + listener = user_trap_syscall(__NR_dup, SECCOMP_FILTER_FLAG_NEW_LISTENER); + ASSERT_GE(listener, 0); + + pid = fork(); + ASSERT_GE(pid, 0); + + if (pid == 0) { + int dup_fd, pipe_fds[2]; + pid_t self; + + ret = pipe(pipe_fds); + if (ret < 0) + exit(1); + + dup_fd = dup(pipe_fds[0]); + if (dup_fd < 0) + exit(1); + + self = getpid(); + + ret = filecmp(self, self, pipe_fds[0], dup_fd); + if (ret) + exit(2); + + exit(0); + } + + pollfd.fd = listener; + pollfd.events = POLLIN | POLLOUT; + + EXPECT_GT(poll(&pollfd, 1, -1), 0); + EXPECT_EQ(pollfd.revents, POLLIN); + + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); + + pollfd.fd = listener; + pollfd.events = POLLIN | POLLOUT; + + EXPECT_GT(poll(&pollfd, 1, -1), 0); + EXPECT_EQ(pollfd.revents, POLLOUT); + + EXPECT_EQ(req.data.nr, __NR_dup); + + resp.id = req.id; + resp.flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE; + + /* + * Verify that setting SECCOMP_USER_NOTIF_FLAG_CONTINUE enforces other + * args be set to 0. + */ + resp.error = 0; + resp.val = USER_NOTIF_MAGIC; + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1); + EXPECT_EQ(errno, EINVAL); + + resp.error = USER_NOTIF_MAGIC; + resp.val = 0; + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1); + EXPECT_EQ(errno, EINVAL); + + resp.error = 0; + resp.val = 0; + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0) { + if (errno == EINVAL) + XFAIL(goto skip, "Kernel does not support SECCOMP_USER_NOTIF_FLAG_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; + } + } +} + /* * TODO: * - add microbenchmarks