From patchwork Tue Jun 16 03:25:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 11606333 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EEFD5912 for ; Tue, 16 Jun 2020 03:26:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D050D207D4 for ; Tue, 16 Jun 2020 03:26:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="HpjCg7s8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726523AbgFPDZq (ORCPT ); Mon, 15 Jun 2020 23:25:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44644 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726837AbgFPDZd (ORCPT ); Mon, 15 Jun 2020 23:25:33 -0400 Received: from mail-pf1-x441.google.com (mail-pf1-x441.google.com [IPv6:2607:f8b0:4864:20::441]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F2306C00862E for ; Mon, 15 Jun 2020 20:25:31 -0700 (PDT) Received: by mail-pf1-x441.google.com with SMTP id j1so8841916pfe.4 for ; Mon, 15 Jun 2020 20:25:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=oyriWhFwZcOqgM4PO4Jyyu/qJTCulFv+DEEh0q062EY=; b=HpjCg7s834tKul7kAuPNlzps+b+PtwMmuQnNQtB2ybY3eNYyVlVAX1E48bUa7ifziY WEuk2wRaWqHWnePpikebUGzfRspaYQogiR4RsBpv6GtXmEkjb8kybzAdAlRIe/VV+0B4 TETdfRwh1in+J+7dzhfIAcqWQUA58SGX8lcSU= 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=oyriWhFwZcOqgM4PO4Jyyu/qJTCulFv+DEEh0q062EY=; b=F0NaI7JfAdn/APf93xXTF9vGg4iq3yI0gxfkhYms8BGqU+ivUy0NKAQce0Lc5agcGp mLb6LI1x3QgP+OnH/n8jyMxmt8hbjthplZHgtvDdXMOeXk51nBqdifBfQh/03XaEAcm+ 8vyFuIZ3FGH1p6PpHGieav7XXF2676L7jJpKf7teE6UdZgBVC84Q1rLEplfjdDVQc5qM mivw4DDHfenBVwbex7B0iYo6/feVN8BhfNJsok74OVdT6WSoa0t19QSAUJ9tbWZdKaN3 yygzGhvwq0dOG7CRlaQl6xe6+Q/kaTvtfIEBRhVXe2pkn/H0MuePPWazqM23y0uPBT1q nDBQ== X-Gm-Message-State: AOAM532Ye3sUOPR5W/rm/yATDEp82OTeMsbkvQr66xFjdktthNP1aysL HqeipyvuU8wZEO3FJ/lr7UJaXQ== X-Google-Smtp-Source: ABdhPJw7pibyApxcW0HTCKGuo+wGuZHjGWqDQ1geQiQj5yzGoxu4dCsSmOiutEA0KBdqVhPfsovK+w== X-Received: by 2002:a62:1407:: with SMTP id 7mr267875pfu.282.1592277931423; Mon, 15 Jun 2020 20:25:31 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id l63sm15635109pfd.122.2020.06.15.20.25.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2020 20:25:28 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Christian Brauner , "David S. Miller" , Christoph Hellwig , Tycho Andersen , Jakub Kicinski , Alexander Viro , Aleksa Sarai , Matt Denton , Jann Horn , Chris Palmer , Robert Sesek , Giuseppe Scrivano , Greg Kroah-Hartman , Andy Lutomirski , Will Drewry , Shuah Khan , 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 01/11] net/scm: Regularize compat handling of scm_detach_fds() Date: Mon, 15 Jun 2020 20:25:14 -0700 Message-Id: <20200616032524.460144-2-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200616032524.460144-1-keescook@chromium.org> References: <20200616032524.460144-1-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Duplicate the cleanups from commit 2618d530dd8b ("net/scm: cleanup scm_detach_fds") into the compat code. Move the check added in commit 1f466e1f15cf ("net: cleanly handle kernel vs user buffers for ->msg_control") to before the compat call, even though it should be impossible for an in-kernel call to also be compat. Correct the int "flags" argument to unsigned int to match fd_install() and similar APIs. Regularize any remaining differences, including a whitespace issue, a checkpatch warning, and add the check from commit 6900317f5eff ("net, scm: fix PaX detected msg_controllen overflow in scm_detach_fds") which fixed an overflow unique to 64-bit. To avoid confusion when comparing the compat handler to the native handler, just include the same check in the compat handler. Fixes: 48a87cc26c13 ("net: netprio: fd passed in SCM_RIGHTS datagram not set correctly") Fixes: d84295067fc7 ("net: net_cls: fd passed in SCM_RIGHTS datagram not set correctly") Signed-off-by: Kees Cook --- include/net/scm.h | 1 + net/compat.c | 55 +++++++++++++++++++++-------------------------- net/core/scm.c | 18 ++++++++-------- 3 files changed, 35 insertions(+), 39 deletions(-) diff --git a/include/net/scm.h b/include/net/scm.h index 1ce365f4c256..581a94d6c613 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -37,6 +37,7 @@ struct scm_cookie { #endif }; +int __scm_install_fd(struct file *file, int __user *ufd, unsigned int o_flags); void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm); void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm); int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm); diff --git a/net/compat.c b/net/compat.c index 5e3041a2c37d..27d477fdcaa0 100644 --- a/net/compat.c +++ b/net/compat.c @@ -281,39 +281,31 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat return 0; } -void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) +static int scm_max_fds_compat(struct msghdr *msg) { - struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control; - int fdmax = (kmsg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int); - int fdnum = scm->fp->count; - struct file **fp = scm->fp->fp; - int __user *cmfptr; - int err = 0, i; + if (msg->msg_controllen <= sizeof(struct compat_cmsghdr)) + return 0; + return (msg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int); +} - if (fdnum < fdmax) - fdmax = fdnum; +void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm) +{ + struct compat_cmsghdr __user *cm = + (struct compat_cmsghdr __user *)msg->msg_control; + unsigned int o_flags = (msg->msg_flags & MSG_CMSG_CLOEXEC) ? O_CLOEXEC : 0; + int fdmax = min_t(int, scm_max_fds_compat(msg), scm->fp->count); + int __user *cmsg_data = CMSG_USER_DATA(cm); + int err = 0, i; - for (i = 0, cmfptr = (int __user *) CMSG_COMPAT_DATA(cm); i < fdmax; i++, cmfptr++) { - int new_fd; - err = security_file_receive(fp[i]); + for (i = 0; i < fdmax; i++) { + err = __scm_install_fd(scm->fp->fp[i], cmsg_data + i, o_flags); if (err) break; - err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & kmsg->msg_flags - ? O_CLOEXEC : 0); - if (err < 0) - break; - new_fd = err; - err = put_user(new_fd, cmfptr); - if (err) { - put_unused_fd(new_fd); - break; - } - /* Bump the usage count and install the file. */ - fd_install(new_fd, get_file(fp[i])); } if (i > 0) { int cmlen = CMSG_COMPAT_LEN(i * sizeof(int)); + err = put_user(SOL_SOCKET, &cm->cmsg_level); if (!err) err = put_user(SCM_RIGHTS, &cm->cmsg_type); @@ -321,16 +313,19 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) err = put_user(cmlen, &cm->cmsg_len); if (!err) { cmlen = CMSG_COMPAT_SPACE(i * sizeof(int)); - kmsg->msg_control += cmlen; - kmsg->msg_controllen -= cmlen; + if (msg->msg_controllen < cmlen) + cmlen = msg->msg_controllen; + msg->msg_control += cmlen; + msg->msg_controllen -= cmlen; } } - if (i < fdnum) - kmsg->msg_flags |= MSG_CTRUNC; + + if (i < scm->fp->count || (scm->fp->count && fdmax <= 0)) + msg->msg_flags |= MSG_CTRUNC; /* - * All of the files that fit in the message have had their - * usage counts incremented, so we just free the list. + * All of the files that fit in the message have had their usage counts + * incremented, so we just free the list. */ __scm_destroy(scm); } diff --git a/net/core/scm.c b/net/core/scm.c index 875df1c2989d..6151678c73ed 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -280,7 +280,7 @@ void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_inter } EXPORT_SYMBOL(put_cmsg_scm_timestamping); -static int __scm_install_fd(struct file *file, int __user *ufd, int o_flags) +int __scm_install_fd(struct file *file, int __user *ufd, unsigned int o_flags) { struct socket *sock; int new_fd; @@ -319,29 +319,29 @@ static int scm_max_fds(struct msghdr *msg) void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) { - struct cmsghdr __user *cm - = (__force struct cmsghdr __user*)msg->msg_control; - int o_flags = (msg->msg_flags & MSG_CMSG_CLOEXEC) ? O_CLOEXEC : 0; + struct cmsghdr __user *cm = + (__force struct cmsghdr __user *)msg->msg_control; + unsigned int o_flags = (msg->msg_flags & MSG_CMSG_CLOEXEC) ? O_CLOEXEC : 0; int fdmax = min_t(int, scm_max_fds(msg), scm->fp->count); int __user *cmsg_data = CMSG_USER_DATA(cm); int err = 0, i; + /* no use for FD passing from kernel space callers */ + if (WARN_ON_ONCE(!msg->msg_control_is_user)) + return; + if (msg->msg_flags & MSG_CMSG_COMPAT) { scm_detach_fds_compat(msg, scm); return; } - /* no use for FD passing from kernel space callers */ - if (WARN_ON_ONCE(!msg->msg_control_is_user)) - return; - for (i = 0; i < fdmax; i++) { err = __scm_install_fd(scm->fp->fp[i], cmsg_data + i, o_flags); if (err) break; } - if (i > 0) { + if (i > 0) { int cmlen = CMSG_LEN(i * sizeof(int)); err = put_user(SOL_SOCKET, &cm->cmsg_level); From patchwork Tue Jun 16 03:25:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 11606305 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CEEE413A0 for ; Tue, 16 Jun 2020 03:25:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AB48120810 for ; Tue, 16 Jun 2020 03:25:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="PIBeP28Q" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726649AbgFPDZb (ORCPT ); Mon, 15 Jun 2020 23:25:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44640 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726025AbgFPDZa (ORCPT ); Mon, 15 Jun 2020 23:25:30 -0400 Received: from mail-pg1-x542.google.com (mail-pg1-x542.google.com [IPv6:2607:f8b0:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 028A5C08C5C2 for ; Mon, 15 Jun 2020 20:25:30 -0700 (PDT) Received: by mail-pg1-x542.google.com with SMTP id e9so8573384pgo.9 for ; Mon, 15 Jun 2020 20:25:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0u5RwpdHP0W7Xlp8ThKh0o2tWC+AL641STHEfKkDVtc=; b=PIBeP28Qi996NpOXEmjqyu8KFo/EizP6EF5S74TuPVtry1BT7hFhCNMNo16tt/rAWq bFtbUl4aEjuf9b7nSQKTWM2Uv7CwlV1rZmHxS46H6z8KgphCOHYvKBrC44wDyuAwu+YL bWD9IGNuYG7gTraFEkUA309RRxh5x7K1kLdw8= 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=0u5RwpdHP0W7Xlp8ThKh0o2tWC+AL641STHEfKkDVtc=; b=lp083hl/g3yBxhWIHhgSPWXZaqUMkf+cKrtQQPtBPoaRPn2y7qxnnEaddwjtfoMddH Z+IcqmhzghVTlmvMKwkqMmZbzigRvrjri/BFpgIEOmfFnZvUmpcOwwTKi5RRTrGSlqWQ mEZzjj42suqQ11RlhkyN7lIfLdtkVeESpZFD0mKnp7RKitGETAJYiNRj24opFi3zFnVI uWxAL4viNcCr28tWlNa1Ib5R1i2etr3SJj3V2rGDvWcVNaNE/yvhAbBFJY4aQGJdfcvE oxiCoLcT7ZAXJpV5psRpV7wUc6mTw0Lno4BkAAPTNIJBRbABIJgTCQnfGDkUNOpmpSj8 j+bQ== X-Gm-Message-State: AOAM530XGcqqx5tKHnT8KRTFg1dObPlAyQFbQyPJ2A/EChtRh2wbmhjD 0apsiD1nXod2+NuKMKzPbiaiFA== X-Google-Smtp-Source: ABdhPJzUa9JhwNcHMDvXVrfHKbgAjcAYa6z4ac/1sqGloTKRah21aXS2igvGroXKeWgdwRpBEbd7Sw== X-Received: by 2002:aa7:972b:: with SMTP id k11mr259824pfg.299.1592277929332; Mon, 15 Jun 2020 20:25:29 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id m14sm12922278pgn.83.2020.06.15.20.25.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2020 20:25:28 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Christian Brauner , "David S. Miller" , Christoph Hellwig , Tycho Andersen , Jakub Kicinski , Alexander Viro , Aleksa Sarai , Matt Denton , Jann Horn , Chris Palmer , Robert Sesek , Giuseppe Scrivano , Greg Kroah-Hartman , Andy Lutomirski , Will Drewry , Shuah Khan , 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 02/11] fs: Move __scm_install_fd() to __fd_install_received() Date: Mon, 15 Jun 2020 20:25:15 -0700 Message-Id: <20200616032524.460144-3-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200616032524.460144-1-keescook@chromium.org> References: <20200616032524.460144-1-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org In preparation for users of the "install a received file" logic outside of net/ (pidfd and seccomp), relocate and rename __scm_install_fd() from net/core/scm.c to __fd_install_received() in fs/file.c, and provide a wrapper named fd_install_received_user(), as future patches will change the interface to __fd_install_received(). Signed-off-by: Kees Cook --- fs/file.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/file.h | 8 ++++++++ include/net/scm.h | 1 - net/compat.c | 2 +- net/core/scm.c | 32 +----------------------------- 5 files changed, 57 insertions(+), 33 deletions(-) diff --git a/fs/file.c b/fs/file.c index abb8b7081d7a..fcfddae0d252 100644 --- a/fs/file.c +++ b/fs/file.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,8 @@ #include #include #include +#include +#include unsigned int sysctl_nr_open __read_mostly = 1024*1024; unsigned int sysctl_nr_open_min = BITS_PER_LONG; @@ -931,6 +934,50 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) return err; } +/** + * __fd_install_received() - Install received file into file descriptor table + * + * @fd: fd to install into (if negative, a new fd will be allocated) + * @file: struct file that was received from another process + * @ufd_required: true to use @ufd for writing fd number to userspace + * @ufd: __user pointer to write new fd number to + * @o_flags: the O_* flags to apply to the new fd entry + * + * Installs a received file into the file descriptor table, with appropriate + * checks and count updates. Optionally writes the fd number to userspace. + * + * Returns -ve on error. + */ +int __fd_install_received(struct file *file, int __user *ufd, unsigned int o_flags) +{ + struct socket *sock; + int new_fd; + int error; + + error = security_file_receive(file); + if (error) + return error; + + new_fd = get_unused_fd_flags(o_flags); + if (new_fd < 0) + return new_fd; + + error = put_user(new_fd, ufd); + if (error) { + put_unused_fd(new_fd); + return error; + } + + /* Bump the usage count and install the file. */ + sock = sock_from_file(file, &error); + if (sock) { + sock_update_netprioidx(&sock->sk->sk_cgrp_data); + sock_update_classid(&sock->sk->sk_cgrp_data); + } + fd_install(new_fd, get_file(file)); + return 0; +} + static int ksys_dup3(unsigned int oldfd, unsigned int newfd, int flags) { int err = -EBADF; diff --git a/include/linux/file.h b/include/linux/file.h index 122f80084a3e..fe18a1a0d555 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -91,6 +91,14 @@ extern void put_unused_fd(unsigned int fd); extern void fd_install(unsigned int fd, struct file *file); +extern int __fd_install_received(struct file *file, int __user *ufd, + unsigned int o_flags); +static inline int fd_install_received_user(struct file *file, int __user *ufd, + unsigned int o_flags) +{ + return __fd_install_received(file, ufd, o_flags); +} + extern void flush_delayed_fput(void); extern void __fput_sync(struct file *); diff --git a/include/net/scm.h b/include/net/scm.h index 581a94d6c613..1ce365f4c256 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -37,7 +37,6 @@ struct scm_cookie { #endif }; -int __scm_install_fd(struct file *file, int __user *ufd, unsigned int o_flags); void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm); void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm); int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm); diff --git a/net/compat.c b/net/compat.c index 27d477fdcaa0..94f288e8dac5 100644 --- a/net/compat.c +++ b/net/compat.c @@ -298,7 +298,7 @@ void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm) int err = 0, i; for (i = 0; i < fdmax; i++) { - err = __scm_install_fd(scm->fp->fp[i], cmsg_data + i, o_flags); + err = fd_install_received_user(scm->fp->fp[i], cmsg_data + i, o_flags); if (err) break; } diff --git a/net/core/scm.c b/net/core/scm.c index 6151678c73ed..df190f1fdd28 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -280,36 +280,6 @@ void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_inter } EXPORT_SYMBOL(put_cmsg_scm_timestamping); -int __scm_install_fd(struct file *file, int __user *ufd, unsigned int o_flags) -{ - struct socket *sock; - int new_fd; - int error; - - error = security_file_receive(file); - if (error) - return error; - - new_fd = get_unused_fd_flags(o_flags); - if (new_fd < 0) - return new_fd; - - error = put_user(new_fd, ufd); - if (error) { - put_unused_fd(new_fd); - return error; - } - - /* Bump the usage count and install the file. */ - sock = sock_from_file(file, &error); - if (sock) { - sock_update_netprioidx(&sock->sk->sk_cgrp_data); - sock_update_classid(&sock->sk->sk_cgrp_data); - } - fd_install(new_fd, get_file(file)); - return 0; -} - static int scm_max_fds(struct msghdr *msg) { if (msg->msg_controllen <= sizeof(struct cmsghdr)) @@ -336,7 +306,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) } for (i = 0; i < fdmax; i++) { - err = __scm_install_fd(scm->fp->fp[i], cmsg_data + i, o_flags); + err = fd_install_received_user(scm->fp->fp[i], cmsg_data + i, o_flags); if (err) break; } From patchwork Tue Jun 16 03:25:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 11606353 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 07981912 for ; Tue, 16 Jun 2020 03:27:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DEFFE208C3 for ; Tue, 16 Jun 2020 03:27:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Jegoy+Im" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727826AbgFPD1J (ORCPT ); Mon, 15 Jun 2020 23:27:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44648 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726616AbgFPDZa (ORCPT ); Mon, 15 Jun 2020 23:25:30 -0400 Received: from mail-pl1-x642.google.com (mail-pl1-x642.google.com [IPv6:2607:f8b0:4864:20::642]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 529FAC061A0E for ; Mon, 15 Jun 2020 20:25:30 -0700 (PDT) Received: by mail-pl1-x642.google.com with SMTP id y18so7766897plr.4 for ; Mon, 15 Jun 2020 20:25:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zOXpbwk+FYeg+wu5gfCMVFIRednwchEzSw3IN7NhShA=; b=Jegoy+ImIb22KyoXp2Lgme0ClHmOz9Blu6VsgODhiFeLlvX/BNBHxqFy1TJ1k+IXSY 6JRHYPeSzrhzHZdeYziEblivMKh7b2Pf5h6pQwiMOm0Mkd0PHmLQOF3cSaJbex8DWg6M TM92HMSoujeVyauo9K44w0jWRKWz1xCKbKhAY= 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=zOXpbwk+FYeg+wu5gfCMVFIRednwchEzSw3IN7NhShA=; b=aQe8+AwzvkYNiG1wsdwTjcInVPnv5h+i3r+CDcz16mao3LUgV+M/eoSuk2sVt4CTt7 RuKg6Vrcz+jD1dCYSuHsI/JR+DZlubta+JrdT1Zq2ycCuH9zrPg37KY1Nk5Z3z9FzGqu szLrYomStzMdCgbfRsucpaasY+tglOwYJDo6sdYvfv0iEZgikthMOaTLOPqmEhzukG+x 9GN9dfHDpPMue0NskWHvr5HKMMG+JtgwQuNbTKqF+6ddKCz6V5UPmN5/mRDmNbFU3KLO mok2daTuO56n1chpGUhnr4w9dCrHTp4R4ZnVfMaAps3Q5GNtktdDf9ie3neXWNqO11m4 ijKQ== X-Gm-Message-State: AOAM533LkodBLqjhj/l3671yuwPHp9rC3zmGSZQwXIOsXdTdxP7FB2On CpkuCIL80/OeMXNEAMhblFUn4A== X-Google-Smtp-Source: ABdhPJwThdt6mE/aeL5PuxLl4Ur5r0/2jL7+3w7ytzuC9KloSLkl6RxwicPdEa4MwtjmwhcgzDbZhA== X-Received: by 2002:a17:90a:e60d:: with SMTP id j13mr796521pjy.127.1592277929895; Mon, 15 Jun 2020 20:25:29 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id y7sm796010pjy.21.2020.06.15.20.25.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2020 20:25:28 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Christian Brauner , "David S. Miller" , Christoph Hellwig , Tycho Andersen , Jakub Kicinski , Alexander Viro , Aleksa Sarai , Matt Denton , Jann Horn , Chris Palmer , Robert Sesek , Giuseppe Scrivano , Greg Kroah-Hartman , Andy Lutomirski , Will Drewry , Shuah Khan , 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 03/11] fs: Add fd_install_received() wrapper for __fd_install_received() Date: Mon, 15 Jun 2020 20:25:16 -0700 Message-Id: <20200616032524.460144-4-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200616032524.460144-1-keescook@chromium.org> References: <20200616032524.460144-1-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org For both pidfd and seccomp, the __user pointer is not used. Update __fd_install_received() to make writing to ufd optional. (ufd itself cannot checked for NULL because this changes the SCM_RIGHTS interface behavior.) In these cases, the new fd needs to be returned on success. Update the existing callers to handle it. Add new wrapper fd_install_received() for pidfd and seccomp that does not use the ufd argument. Signed-off-by: Kees Cook --- fs/file.c | 26 +++++++++++++++++--------- include/linux/file.h | 10 +++++++--- net/compat.c | 2 +- net/core/scm.c | 2 +- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/fs/file.c b/fs/file.c index fcfddae0d252..14a8ef74efb2 100644 --- a/fs/file.c +++ b/fs/file.c @@ -944,11 +944,14 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) * @o_flags: the O_* flags to apply to the new fd entry * * Installs a received file into the file descriptor table, with appropriate - * checks and count updates. Optionally writes the fd number to userspace. + * checks and count updates. Optionally writes the fd number to userspace, if + * @ufd_required is true (@ufd cannot just be tested for NULL because NULL may + * actually get passed into SCM_RIGHTS). * - * Returns -ve on error. + * Returns newly install fd or -ve on error. */ -int __fd_install_received(struct file *file, int __user *ufd, unsigned int o_flags) +int __fd_install_received(struct file *file, bool ufd_required, int __user *ufd, + unsigned int o_flags) { struct socket *sock; int new_fd; @@ -962,20 +965,25 @@ int __fd_install_received(struct file *file, int __user *ufd, unsigned int o_fla if (new_fd < 0) return new_fd; - error = put_user(new_fd, ufd); - if (error) { - put_unused_fd(new_fd); - return error; + if (ufd_required) { + error = put_user(new_fd, ufd); + if (error) { + put_unused_fd(new_fd); + return error; + } } - /* Bump the usage count and install the file. */ + /* Bump the usage count and install the file. The resulting value of + * "error" is ignored here since we only need to take action when + * the file is a socket and testing "sock" for NULL is sufficient. + */ sock = sock_from_file(file, &error); if (sock) { sock_update_netprioidx(&sock->sk->sk_cgrp_data); sock_update_classid(&sock->sk->sk_cgrp_data); } fd_install(new_fd, get_file(file)); - return 0; + return new_fd; } static int ksys_dup3(unsigned int oldfd, unsigned int newfd, int flags) diff --git a/include/linux/file.h b/include/linux/file.h index fe18a1a0d555..999a2c56db07 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -91,12 +91,16 @@ extern void put_unused_fd(unsigned int fd); extern void fd_install(unsigned int fd, struct file *file); -extern int __fd_install_received(struct file *file, int __user *ufd, - unsigned int o_flags); +extern int __fd_install_received(struct file *file, bool ufd_required, + int __user *ufd, unsigned int o_flags); static inline int fd_install_received_user(struct file *file, int __user *ufd, unsigned int o_flags) { - return __fd_install_received(file, ufd, o_flags); + return __fd_install_received(file, true, ufd, o_flags); +} +static inline int fd_install_received(struct file *file, unsigned int o_flags) +{ + return __fd_install_received(file, false, NULL, o_flags); } extern void flush_delayed_fput(void); diff --git a/net/compat.c b/net/compat.c index 94f288e8dac5..71494337cca7 100644 --- a/net/compat.c +++ b/net/compat.c @@ -299,7 +299,7 @@ void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm) for (i = 0; i < fdmax; i++) { err = fd_install_received_user(scm->fp->fp[i], cmsg_data + i, o_flags); - if (err) + if (err < 0) break; } diff --git a/net/core/scm.c b/net/core/scm.c index df190f1fdd28..b9a0442ebd26 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -307,7 +307,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) for (i = 0; i < fdmax; i++) { err = fd_install_received_user(scm->fp->fp[i], cmsg_data + i, o_flags); - if (err) + if (err < 0) break; } From patchwork Tue Jun 16 03:25:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 11606315 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 81969912 for ; Tue, 16 Jun 2020 03:25:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6821C20810 for ; Tue, 16 Jun 2020 03:25:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="IgudgnzK" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726681AbgFPDZq (ORCPT ); Mon, 15 Jun 2020 23:25:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44660 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726704AbgFPDZb (ORCPT ); Mon, 15 Jun 2020 23:25:31 -0400 Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D7E39C08C5C2 for ; Mon, 15 Jun 2020 20:25:30 -0700 (PDT) Received: by mail-pl1-x644.google.com with SMTP id n9so7775700plk.1 for ; Mon, 15 Jun 2020 20:25:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=d7bw5q/TJxpqMicrHyIFon0t9gt+svhVPDuc7AUFnrI=; b=IgudgnzK6YOeQXxO/GhbZyRnD7yKsB19/poCwHH5zYg0DNwv/OjS7ClaVfKBcPYMJl gk02nAiuMCNLKeX/ZV8hAsNyo4xkNMZpUlVd73LjLWPTM3vu0gDsAt4qIgmqVBNttPDZ W8gmwOqh2kvJFeY1MjkoUB2YMUS901i5ZFCmE= 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=d7bw5q/TJxpqMicrHyIFon0t9gt+svhVPDuc7AUFnrI=; b=NEqkDD4QIJ8/MN5k+/YMTQwcfv1hmhx2Ua9+1ep3Q5Dg4/ZJX1uXsKgOE3XtxhAOMs MJvFs9EgwO5blZawjbgfTQfeq4KTLNIeXV5nldBPgDjcTEMwfJxBdVW6tmOlcAvEihnR u6pN228+cKbTco8Ri+aOeoyRL7mYKAMR5t9I4wyDUWY+IeFB31BkauD12g2v2LIu6y/H hz1UWPkwJUCWztRoBHgHROX4EbTtvsPpKNzIlZ0f6ZV49lysT3tnVinn89Lp1huiwhOo xBAn8uFT9mAOZ4SGp/PE7JgNzn5IaAK68y67dr/ie0NZdzxV00+S7P+Y7/BqKb66/2s0 gAMQ== X-Gm-Message-State: AOAM531f0gKtGSDgLFwHiGT4q9p/zfDKSyUMrvI21kWT52NJn6sG07W4 ZrpUYozFlTid6tHom1HT4/ePzw== X-Google-Smtp-Source: ABdhPJw66Qb+fMMy1G2QTWCPav55PuClQnfisvC1pdmVOLwHIqdy34tq0HaqwNMimHEa+bRLc4w0yQ== X-Received: by 2002:a17:902:8346:: with SMTP id z6mr329196pln.27.1592277930455; Mon, 15 Jun 2020 20:25:30 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id u4sm762715pjn.42.2020.06.15.20.25.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2020 20:25:28 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Christian Brauner , "David S. Miller" , Christoph Hellwig , Tycho Andersen , Jakub Kicinski , Alexander Viro , Aleksa Sarai , Matt Denton , Jann Horn , Chris Palmer , Robert Sesek , Giuseppe Scrivano , Greg Kroah-Hartman , Andy Lutomirski , Will Drewry , Shuah Khan , 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 04/11] pidfd: Replace open-coded partial fd_install_received() Date: Mon, 15 Jun 2020 20:25:17 -0700 Message-Id: <20200616032524.460144-5-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200616032524.460144-1-keescook@chromium.org> References: <20200616032524.460144-1-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org The sock counting (sock_update_netprioidx() and sock_update_classid()) was missing from pidfd's implementation of received fd installation. Replace the open-coded version with a call to the new fd_install_received() helper. Fixes: 8649c322f75c ("pid: Implement pidfd_getfd syscall") Signed-off-by: Kees Cook --- kernel/pid.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/kernel/pid.c b/kernel/pid.c index f1496b757162..24924ec5df0e 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -635,18 +635,9 @@ static int pidfd_getfd(struct pid *pid, int fd) if (IS_ERR(file)) return PTR_ERR(file); - ret = security_file_receive(file); - if (ret) { - fput(file); - return ret; - } - - ret = get_unused_fd_flags(O_CLOEXEC); + ret = fd_install_received(file, O_CLOEXEC); if (ret < 0) fput(file); - else - fd_install(ret, file); - return ret; } From patchwork Tue Jun 16 03:25:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 11606341 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E9D04912 for ; Tue, 16 Jun 2020 03:26:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D1216207E8 for ; Tue, 16 Jun 2020 03:26:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Ni9Nj86T" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726091AbgFPD0p (ORCPT ); Mon, 15 Jun 2020 23:26:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44652 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726909AbgFPDZg (ORCPT ); Mon, 15 Jun 2020 23:25:36 -0400 Received: from mail-pg1-x542.google.com (mail-pg1-x542.google.com [IPv6:2607:f8b0:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E02CC08C5CB for ; Mon, 15 Jun 2020 20:25:34 -0700 (PDT) Received: by mail-pg1-x542.google.com with SMTP id s10so8602857pgm.0 for ; Mon, 15 Jun 2020 20:25:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=HcknO+2U6NyZmGxMbR3CAHSQ4G454UQIfBRNwJsDAGs=; b=Ni9Nj86TxOCxN+Q1noSGMuOS4x3lT9BEmWWFkE5gXguwF94uaaqkDDRC0ZDI2dFwqH 6UQCDz5uppetU9OsClPUQVnfL7QLC7Lhie+Nj/0QfNVNZRco/pe3pJZKvxbx48Yw93YL K9aHPzSRk0B6z5wkni3ESg09Vw41qQyXw7c2w= 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=HcknO+2U6NyZmGxMbR3CAHSQ4G454UQIfBRNwJsDAGs=; b=p0+DNgntb0nISPmqmNlBhktiTcLTfU/ETDOc7x1GniPn5HUtUFWQcsxlrxQpmjLBmV qPHaPzJvXw3DDcK1PtDVVxkyD7PqBtgYq3zLJVD2WZQ85ct9nfDEsDJelmueWp6xR694 DfKMXrESqeC6htzHafa+DKDiMUKHSRDFaqVWH8Sd4USJ8SVQpRPVVaeMyTAN2BNC/tX1 G/cJuzrrhurtE1oasR1aMMxLHnwEA14tOfKTuP8HGeHytrlbMhjPBkAn+xkmP4FQXWF0 xw6LQULGu2pURMfhgqeAE5rRzgpl8rrsR3aQcR/kHnoDOpgnpZupkzDdAo24ByUzHVUi FEoQ== X-Gm-Message-State: AOAM530wg3/r3Hqx8pyQObipSOyP0bUsPrRU9b4rn99s4Y07J6Q6nuPX ma1XBO+W+cYwtGVLGaaQYEkb1w== X-Google-Smtp-Source: ABdhPJwQdqKI0yfpNYbLt1UQTfVscQHjWyX7NqI+wJHdQip2vpApLLc4Cl2Na7ZB9UMEzOWHLaarVQ== X-Received: by 2002:a05:6a00:84e:: with SMTP id q14mr252444pfk.309.1592277933644; Mon, 15 Jun 2020 20:25:33 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id c2sm12623848pgk.77.2020.06.15.20.25.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2020 20:25:32 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Christian Brauner , "David S. Miller" , Christoph Hellwig , Tycho Andersen , Jakub Kicinski , Alexander Viro , Aleksa Sarai , Matt Denton , Jann Horn , Chris Palmer , Robert Sesek , Giuseppe Scrivano , Greg Kroah-Hartman , Andy Lutomirski , Will Drewry , Shuah Khan , 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 05/11] fs: Expand __fd_install_received() to accept fd Date: Mon, 15 Jun 2020 20:25:18 -0700 Message-Id: <20200616032524.460144-6-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200616032524.460144-1-keescook@chromium.org> References: <20200616032524.460144-1-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Expand __fd_install_received() with support for replace_fd() for the coming seccomp "addfd" ioctl(). Add new wrapper fd_replace_received() for the new mode and update existing wrappers to retain old mode. Signed-off-by: Kees Cook --- fs/file.c | 22 ++++++++++++++++------ include/linux/file.h | 10 +++++++--- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/fs/file.c b/fs/file.c index 14a8ef74efb2..b583e7c60571 100644 --- a/fs/file.c +++ b/fs/file.c @@ -950,8 +950,8 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) * * Returns newly install fd or -ve on error. */ -int __fd_install_received(struct file *file, bool ufd_required, int __user *ufd, - unsigned int o_flags) +int __fd_install_received(int fd, struct file *file, bool ufd_required, + int __user *ufd, unsigned int o_flags) { struct socket *sock; int new_fd; @@ -961,9 +961,11 @@ int __fd_install_received(struct file *file, bool ufd_required, int __user *ufd, if (error) return error; - new_fd = get_unused_fd_flags(o_flags); - if (new_fd < 0) - return new_fd; + if (fd < 0) { + new_fd = get_unused_fd_flags(o_flags); + if (new_fd < 0) + return new_fd; + } if (ufd_required) { error = put_user(new_fd, ufd); @@ -973,6 +975,15 @@ int __fd_install_received(struct file *file, bool ufd_required, int __user *ufd, } } + if (fd < 0) + fd_install(new_fd, get_file(file)); + else { + new_fd = fd; + error = replace_fd(new_fd, file, o_flags); + if (error) + return error; + } + /* Bump the usage count and install the file. The resulting value of * "error" is ignored here since we only need to take action when * the file is a socket and testing "sock" for NULL is sufficient. @@ -982,7 +993,6 @@ int __fd_install_received(struct file *file, bool ufd_required, int __user *ufd, sock_update_netprioidx(&sock->sk->sk_cgrp_data); sock_update_classid(&sock->sk->sk_cgrp_data); } - fd_install(new_fd, get_file(file)); return new_fd; } diff --git a/include/linux/file.h b/include/linux/file.h index 999a2c56db07..f1d16e24a12e 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -91,16 +91,20 @@ extern void put_unused_fd(unsigned int fd); extern void fd_install(unsigned int fd, struct file *file); -extern int __fd_install_received(struct file *file, bool ufd_required, +extern int __fd_install_received(int fd, struct file *file, bool ufd_required, int __user *ufd, unsigned int o_flags); static inline int fd_install_received_user(struct file *file, int __user *ufd, unsigned int o_flags) { - return __fd_install_received(file, true, ufd, o_flags); + return __fd_install_received(-1, file, true, ufd, o_flags); } static inline int fd_install_received(struct file *file, unsigned int o_flags) { - return __fd_install_received(file, false, NULL, o_flags); + return __fd_install_received(-1, file, false, NULL, o_flags); +} +static inline int fd_replace_received(int fd, struct file *file, unsigned int o_flags) +{ + return __fd_install_received(fd, file, false, NULL, o_flags); } extern void flush_delayed_fput(void); From patchwork Tue Jun 16 03:25:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 11606317 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 508D913A0 for ; Tue, 16 Jun 2020 03:25:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2E2AE207D3 for ; Tue, 16 Jun 2020 03:25:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="H6W7RXGg" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726699AbgFPDZ5 (ORCPT ); Mon, 15 Jun 2020 23:25:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44682 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726846AbgFPDZv (ORCPT ); Mon, 15 Jun 2020 23:25:51 -0400 Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 572A5C0085C1 for ; Mon, 15 Jun 2020 20:25:37 -0700 (PDT) Received: by mail-pl1-x643.google.com with SMTP id d8so7756772plo.12 for ; Mon, 15 Jun 2020 20:25:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vY6XnehwafBZJOkQHoxk+049ZnyiWS2rNzwOao2yGyU=; b=H6W7RXGgrY5QaaraC5tiCpRsU2fQjleZAbAysPWcLB/lm4uvRa4nDCyrB7m5Fpv68L sFaHX1//uplN2O2KasdqIAT1ZcPKCkxL7o44qnplZN7SG5a1kFcuUZsiBOYrynPhn69y b2TZ01u48Wnn5F82vOy3WCTHh8BuZPHjk/uK8= 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=vY6XnehwafBZJOkQHoxk+049ZnyiWS2rNzwOao2yGyU=; b=IxARCgYvBgue2moMSADmpKh6TKx3nLxLZ4jWk4a7NhoGxZYgLifDFAkXJ1fDxrvZcK KVbIgi0JwDtPI9K/vRMz/KzfpLn+16iPnlTaysKrjmNkjpvaw98fcxILBhnqSvhRTgUF RUTleCXiPD0W5p/GP4KK9HQXBOg/o1MFLt3lIzsaHglsWd8U2wSsA5UYuLv+ZfmQj/85 KaRkVl8rHGySSg159/oZp27BftCwUryjw8AAUalrkDlEbOmrYtyP6tmsvTWdT0Xmptmd giygNkgHWZ+Rygte5l6cJ4EqmvoJVBLIILoX4HUmEy5JkgDAUe5uRo/oU4lRCOkFK75L 95vg== X-Gm-Message-State: AOAM532E7krXQkN2BYIGasefLNSiQs4a69y+C+hjFHSlOBqWlBHtWwK1 UTWLySkLdBogSaFbIdH1qI24Uw== X-Google-Smtp-Source: ABdhPJyih+Kodk3wUY89vUdRFHOPEIv8KpSbbjXu+ND3SdRoOfgZEnFg+Ja+pXOE9M61S+nyEKMgug== X-Received: by 2002:a17:90a:c797:: with SMTP id gn23mr756375pjb.165.1592277936331; Mon, 15 Jun 2020 20:25:36 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id o1sm767346pja.49.2020.06.15.20.25.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2020 20:25:32 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Matt Denton , Christian Brauner , "David S. Miller" , Christoph Hellwig , Tycho Andersen , Jakub Kicinski , Alexander Viro , Aleksa Sarai , Jann Horn , Chris Palmer , Robert Sesek , Giuseppe Scrivano , Greg Kroah-Hartman , Andy Lutomirski , Will Drewry , Shuah Khan , 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 06/11] seccomp: Introduce addfd ioctl to seccomp user notifier Date: Mon, 15 Jun 2020 20:25:19 -0700 Message-Id: <20200616032524.460144-7-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200616032524.460144-1-keescook@chromium.org> References: <20200616032524.460144-1-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org From: Sargun Dhillon This adds a seccomp notifier ioctl which allows for the listener to "add" file descriptors to a process which originated a seccomp user notification. This allows calls like mount, and mknod to be "implemented", as the return value, and the arguments are data in memory. On the other hand, calls like connect can be "implemented" using pidfd_getfd. Unfortunately, there are calls which return file descriptors, like open, which are vulnerable to ToCToU attacks, and require that the more privileged supervisor can inspect the argument, and perform the syscall on behalf of the process generating the notification. This allows the file descriptor generated from that open call to be returned to the calling process. In addition, there is functionality to allow for replacement of specific file descriptors, following dup2-like semantics. As a note, the seccomp_notif_addfd structure is laid out based on 8-byte alignment without requiring packing as there have been packing issues with uapi highlighted before[1][2]. Although we could overload the newfd field and use -1 to indicate that it is not to be used, doing so requires changing the size of the fd field, and introduces struct packing complexity. [1]: https://lore.kernel.org/lkml/87o8w9bcaf.fsf@mid.deneb.enyo.de/ [2]: https://lore.kernel.org/lkml/a328b91d-fd8f-4f27-b3c2-91a9c45f18c0@rasmusvillemoes.dk/ Suggested-by: Matt Denton Link: https://lore.kernel.org/r/20200603011044.7972-4-sargun@sargun.me Signed-off-by: Sargun Dhillon Signed-off-by: Kees Cook --- include/uapi/linux/seccomp.h | 25 ++++++ kernel/seccomp.c | 165 ++++++++++++++++++++++++++++++++++- 2 files changed, 189 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h index c1735455bc53..c347160378e5 100644 --- a/include/uapi/linux/seccomp.h +++ b/include/uapi/linux/seccomp.h @@ -113,6 +113,27 @@ struct seccomp_notif_resp { __u32 flags; }; +/* valid flags for seccomp_notif_addfd */ +#define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0) /* Specify remote fd */ + +/** + * struct seccomp_notif_addfd + * @size: The size of the seccomp_notif_addfd structure + * @id: The ID of the seccomp notification + * @flags: SECCOMP_ADDFD_FLAG_* + * @srcfd: The local fd number + * @newfd: Optional remote FD number if SETFD option is set, otherwise 0. + * @newfd_flags: The O_* flags the remote FD should have applied + */ +struct seccomp_notif_addfd { + __u64 size; + __u64 id; + __u32 flags; + __u32 srcfd; + __u32 newfd; + __u32 newfd_flags; +}; + #define SECCOMP_IOC_MAGIC '!' #define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr) #define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type) @@ -124,4 +145,8 @@ struct seccomp_notif_resp { #define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, \ struct seccomp_notif_resp) #define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOR(2, __u64) +/* On success, the return value is the remote process's added fd number */ +#define SECCOMP_IOCTL_NOTIF_ADDFD SECCOMP_IOW(3, \ + struct seccomp_notif_addfd) + #endif /* _UAPI_LINUX_SECCOMP_H */ diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 0016cad0e605..3c913f3b8451 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -78,10 +78,42 @@ struct seccomp_knotif { long val; u32 flags; - /* Signals when this has entered SECCOMP_NOTIFY_REPLIED */ + /* + * Signals when this has changed states, such as the listener + * dying, a new seccomp addfd message, or changing to REPLIED + */ struct completion ready; struct list_head list; + + /* outstanding addfd requests */ + struct list_head addfd; +}; + +/** + * struct seccomp_kaddfd - container for seccomp_addfd ioctl messages + * + * @file: A reference to the file to install in the other task + * @fd: The fd number to install it at. If the fd number is -1, it means the + * installing process should allocate the fd as normal. + * @flags: The flags for the new file descriptor. At the moment, only O_CLOEXEC + * is allowed. + * @ret: The return value of the installing process. It is set to the fd num + * upon success (>= 0). + * @completion: Indicates that the installing process has completed fd + * installation, or gone away (either due to successful + * reply, or signal) + * + */ +struct seccomp_kaddfd { + struct file *file; + int fd; + unsigned int flags; + + /* To only be set on reply */ + int ret; + struct completion completion; + struct list_head list; }; /** @@ -784,6 +816,17 @@ static u64 seccomp_next_notify_id(struct seccomp_filter *filter) return filter->notif->next_id++; } +static void seccomp_handle_addfd(struct seccomp_kaddfd *addfd) +{ + /* + * Remove the notification, and reset the list pointers, indicating + * that it has been handled. + */ + list_del_init(&addfd->list); + addfd->ret = fd_replace_received(addfd->fd, addfd->file, addfd->flags); + complete(&addfd->completion); +} + static int seccomp_do_user_notification(int this_syscall, struct seccomp_filter *match, const struct seccomp_data *sd) @@ -792,6 +835,7 @@ static int seccomp_do_user_notification(int this_syscall, u32 flags = 0; long ret = 0; struct seccomp_knotif n = {}; + struct seccomp_kaddfd *addfd, *tmp; mutex_lock(&match->notify_lock); err = -ENOSYS; @@ -804,6 +848,7 @@ static int seccomp_do_user_notification(int this_syscall, n.id = seccomp_next_notify_id(match); init_completion(&n.ready); list_add(&n.list, &match->notif->notifications); + INIT_LIST_HEAD(&n.addfd); up(&match->notif->request); wake_up_poll(&match->wqh, EPOLLIN | EPOLLRDNORM); @@ -812,14 +857,31 @@ static int seccomp_do_user_notification(int this_syscall, /* * This is where we wait for a reply from userspace. */ +wait: err = wait_for_completion_interruptible(&n.ready); mutex_lock(&match->notify_lock); if (err == 0) { + /* Check if we were woken up by a addfd message */ + addfd = list_first_entry_or_null(&n.addfd, + struct seccomp_kaddfd, list); + if (addfd && n.state != SECCOMP_NOTIFY_REPLIED) { + seccomp_handle_addfd(addfd); + mutex_unlock(&match->notify_lock); + goto wait; + } ret = n.val; err = n.error; flags = n.flags; } + /* If there were any pending addfd calls, clear them out */ + list_for_each_entry_safe(addfd, tmp, &n.addfd, list) { + /* The process went away before we got a chance to handle it */ + addfd->ret = -ESRCH; + list_del_init(&addfd->list); + complete(&addfd->completion); + } + /* * Note that it's possible the listener died in between the time when * we were notified of a respons (or a signal) and when we were able to @@ -1060,6 +1122,11 @@ static int seccomp_notify_release(struct inode *inode, struct file *file) knotif->error = -ENOSYS; knotif->val = 0; + /* + * We do not need to wake up any pending addfd messages, as + * the notifier will do that for us, as this just looks + * like a standard reply. + */ complete(&knotif->ready); } @@ -1224,6 +1291,100 @@ static long seccomp_notify_id_valid(struct seccomp_filter *filter, return ret; } +static long seccomp_notify_addfd(struct seccomp_filter *filter, + struct seccomp_notif_addfd __user *uaddfd) +{ + struct seccomp_notif_addfd addfd; + struct seccomp_knotif *knotif; + struct seccomp_kaddfd kaddfd; + u64 size; + int ret; + + ret = get_user(size, &uaddfd->size); + if (ret) + return ret; + + ret = copy_struct_from_user(&addfd, sizeof(addfd), uaddfd, size); + if (ret) + return ret; + + if (addfd.newfd_flags & ~O_CLOEXEC) + return -EINVAL; + + if (addfd.flags & ~SECCOMP_ADDFD_FLAG_SETFD) + return -EINVAL; + + if (addfd.newfd && !(addfd.flags & SECCOMP_ADDFD_FLAG_SETFD)) + return -EINVAL; + + kaddfd.file = fget(addfd.srcfd); + if (!kaddfd.file) + return -EBADF; + + kaddfd.flags = addfd.newfd_flags; + kaddfd.fd = (addfd.flags & SECCOMP_ADDFD_FLAG_SETFD) ? + addfd.newfd : -1; + init_completion(&kaddfd.completion); + + ret = mutex_lock_interruptible(&filter->notify_lock); + if (ret < 0) + goto out; + + knotif = find_notification(filter, addfd.id); + if (!knotif) { + ret = -ENOENT; + goto out_unlock; + } + + /* + * We do not want to allow for FD injection to occur before the + * notification has been picked up by a userspace handler, or after + * the notification has been replied to. + */ + if (knotif->state != SECCOMP_NOTIFY_SENT) { + ret = -EINPROGRESS; + goto out_unlock; + } + + list_add(&kaddfd.list, &knotif->addfd); + complete(&knotif->ready); + mutex_unlock(&filter->notify_lock); + + /* Now we wait for it to be processed or be interrupted */ + ret = wait_for_completion_interruptible(&kaddfd.completion); + if (ret == 0) { + /* + * We had a successful completion. The other side has already + * removed us from the addfd queue, and + * wait_for_completion_interruptible has a memory barrier upon + * success that lets us read this value directly without + * locking. + */ + ret = kaddfd.ret; + goto out; + } + + mutex_lock(&filter->notify_lock); + /* + * Even though we were woken up by a signal and not a successful + * completion, a completion may have happened in the mean time. + * + * We need to check again if the addfd request has been handled, + * and if not, we will remove it from the queue. + */ + if (list_empty(&kaddfd.list)) + ret = kaddfd.ret; + else + list_del(&kaddfd.list); + +out_unlock: + mutex_unlock(&filter->notify_lock); +out: + fput(kaddfd.file); + + return ret; +} + static long seccomp_notify_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1237,6 +1398,8 @@ static long seccomp_notify_ioctl(struct file *file, unsigned int cmd, return seccomp_notify_send(filter, buf); case SECCOMP_IOCTL_NOTIF_ID_VALID: return seccomp_notify_id_valid(filter, buf); + case SECCOMP_IOCTL_NOTIF_ADDFD: + return seccomp_notify_addfd(filter, buf); default: return -EINVAL; } From patchwork Tue Jun 16 03:25:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 11606347 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 676F4912 for ; Tue, 16 Jun 2020 03:26:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4AE24207D4 for ; Tue, 16 Jun 2020 03:26:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="be9HSNva" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727086AbgFPD0p (ORCPT ); Mon, 15 Jun 2020 23:26:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44664 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726863AbgFPDZf (ORCPT ); Mon, 15 Jun 2020 23:25:35 -0400 Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A70C5C08C5CA for ; Mon, 15 Jun 2020 20:25:34 -0700 (PDT) Received: by mail-pj1-x1042.google.com with SMTP id a45so659053pje.1 for ; Mon, 15 Jun 2020 20:25:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=aWh5lElW/7ccftZHL3bZeOP7ElRbbCS5z6Iyk301O4M=; b=be9HSNvaCEr3M8WffUkDBl3zphEnJZZbkYJodEsZj3DQ29d3u0+zWo2/SzVQch8Clg xYvfYEg9K8XrLCZgFUN1cgNWX8c+skTOKifRq+N8U7wD7h+t+I/+dMLA1w8WwhV8hoRm DhBkRMAFxZewoWgjfQuedvEonO/umyVkInOuI= 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=aWh5lElW/7ccftZHL3bZeOP7ElRbbCS5z6Iyk301O4M=; b=dBwTYnpdsEqwJJVRk6qI/jJoC4BxuObi1NIsHbe5KxbLBn+kLtgBGmSeDYKK5FZqKB u6UDix9KGebgvI2tJReH611Bf/ANQpDQtlu2lh2/x8lHg4Y+noazYpTxnsyQkIbP6Z81 5oQrOChBzhpurb0KANBZvNOKJaE/P6k57P5d6dCW7VTo3xAsFLSdkmpjAAJyHHehdvWY rQHZ+W73OwhC9VNlY9AqygoH7cmNkzO6EXLXutHX6tMNvttm1KU4KJtB/2cGykBMcy6E 4CcweGjV5CmB36S/OUMH1w0HCDGNTraoXfjX9bJTTo/aPyMY9Y5my0LRV2Pc2qry2KfL GZLQ== X-Gm-Message-State: AOAM532USvZwvTbZWiL95Occ+gYj+X3iAFO2Prv0BQOpN8jbOMWYl8sO R5X3jT0QaoO9tuj+yUzNhEqH5A== X-Google-Smtp-Source: ABdhPJxt49m1w44D+xHPvHZHatkz/S2ffGer11Fx7PrHDm4CiS7xyBuAAA93jBOTXmjz0LnDbZun2g== X-Received: by 2002:a17:902:6a83:: with SMTP id n3mr351980plk.42.1592277934197; Mon, 15 Jun 2020 20:25:34 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id u6sm5432357pfc.83.2020.06.15.20.25.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2020 20:25:32 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Christian Brauner , "David S. Miller" , Christoph Hellwig , Tycho Andersen , Jakub Kicinski , Alexander Viro , Aleksa Sarai , Matt Denton , Jann Horn , Chris Palmer , Robert Sesek , Giuseppe Scrivano , Greg Kroah-Hartman , Andy Lutomirski , Will Drewry , Shuah Khan , 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 07/11] selftests/seccomp: Test SECCOMP_IOCTL_NOTIF_ADDFD Date: Mon, 15 Jun 2020 20:25:20 -0700 Message-Id: <20200616032524.460144-8-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200616032524.460144-1-keescook@chromium.org> References: <20200616032524.460144-1-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org From: Sargun Dhillon Test whether we can add file descriptors in response to notifications. This injects the file descriptors via notifications, and then uses kcmp to determine whether or not it has been successful. It also includes some basic sanity checking for arguments. Signed-off-by: Sargun Dhillon Link: https://lore.kernel.org/r/20200603011044.7972-5-sargun@sargun.me Signed-off-by: Kees Cook --- tools/testing/selftests/seccomp/seccomp_bpf.c | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 402ccb3a4e52..c4e264b37c30 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -168,7 +169,9 @@ struct seccomp_metadata { #ifndef SECCOMP_FILTER_FLAG_NEW_LISTENER #define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3) +#endif +#ifndef SECCOMP_RET_USER_NOTIF #define SECCOMP_RET_USER_NOTIF 0x7fc00000U #define SECCOMP_IOC_MAGIC '!' @@ -204,6 +207,24 @@ struct seccomp_notif_sizes { }; #endif +#ifndef SECCOMP_IOCTL_NOTIF_ADDFD +/* On success, the return value is the remote process's added fd number */ +#define SECCOMP_IOCTL_NOTIF_ADDFD SECCOMP_IOW(3, \ + struct seccomp_notif_addfd) + +/* valid flags for seccomp_notif_addfd */ +#define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0) /* Specify remote fd */ + +struct seccomp_notif_addfd { + __u64 size; + __u64 id; + __u32 flags; + __u32 srcfd; + __u32 newfd; + __u32 newfd_flags; +}; +#endif + #ifndef PTRACE_EVENTMSG_SYSCALL_ENTRY #define PTRACE_EVENTMSG_SYSCALL_ENTRY 1 #define PTRACE_EVENTMSG_SYSCALL_EXIT 2 @@ -3822,6 +3843,173 @@ TEST(user_notification_filter_empty_threaded) EXPECT_GT((pollfd.revents & POLLHUP) ?: 0, 0); } +TEST(user_notification_sendfd) +{ + pid_t pid; + long ret; + int status, listener, memfd; + struct seccomp_notif_addfd addfd = {}; + struct seccomp_notif req = {}; + struct seccomp_notif_resp resp = {}; + /* 100 ms */ + struct timespec delay = { .tv_nsec = 100000000 }; + + memfd = memfd_create("test", 0); + ASSERT_GE(memfd, 0); + + 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!"); + } + + /* Check that the basic notification machinery works */ + listener = user_trap_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); + ASSERT_GE(listener, 0); + + pid = fork(); + ASSERT_GE(pid, 0); + + if (pid == 0) { + if (syscall(__NR_getppid) != USER_NOTIF_MAGIC) + exit(1); + exit(syscall(__NR_getppid) != USER_NOTIF_MAGIC); + } + + ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); + + addfd.size = sizeof(addfd); + addfd.srcfd = memfd; + addfd.newfd_flags = O_CLOEXEC; + addfd.newfd = 0; + addfd.id = req.id; + addfd.flags = 0xff; + + /* Verify bad flags cannot be set */ + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1); + EXPECT_EQ(errno, EINVAL); + + /* 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 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); + + resp.id = req.id; + resp.error = 0; + resp.val = USER_NOTIF_MAGIC; + + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0); + + /* + * This sets the ID of the ADD FD to the last request plus 1. The + * notification ID increments 1 per notification. + */ + addfd.id = req.id + 1; + + /* This spins until the underlying notification is generated */ + while (ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd) != -1 && + errno != -EINPROGRESS) + nanosleep(&delay, NULL); + + memset(&req, 0, sizeof(req)); + ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); + ASSERT_EQ(addfd.id, req.id); + + resp.id = req.id; + resp.error = 0; + resp.val = USER_NOTIF_MAGIC; + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0); + + + EXPECT_EQ(waitpid(pid, &status, 0), pid); + EXPECT_EQ(true, WIFEXITED(status)); + EXPECT_EQ(0, WEXITSTATUS(status)); + + close(memfd); +} + +TEST(user_notification_sendfd_rlimit) +{ + pid_t pid; + long ret; + int status, listener, memfd; + struct seccomp_notif_addfd addfd = {}; + struct seccomp_notif req = {}; + struct seccomp_notif_resp resp = {}; + const struct rlimit lim = { + .rlim_cur = 0, + .rlim_max = 0, + }; + + memfd = memfd_create("test", 0); + ASSERT_GE(memfd, 0); + + 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!"); + } + + /* Check that the basic notification machinery works */ + listener = user_trap_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); + ASSERT_GE(listener, 0); + + pid = fork(); + ASSERT_GE(pid, 0); + + if (pid == 0) + exit(syscall(__NR_getppid) != USER_NOTIF_MAGIC); + + + ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); + + ASSERT_EQ(prlimit(pid, RLIMIT_NOFILE, &lim, NULL), 0); + + addfd.size = sizeof(addfd); + addfd.srcfd = memfd; + addfd.newfd_flags = O_CLOEXEC; + addfd.newfd = 0; + addfd.id = req.id; + addfd.flags = 0; + + /* Should probably spot check /proc/sys/fs/file-nr */ + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1); + EXPECT_EQ(errno, EMFILE); + + addfd.newfd = 100; + addfd.flags = SECCOMP_ADDFD_FLAG_SETFD; + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd), -1); + EXPECT_EQ(errno, EBADF); + + resp.id = req.id; + resp.error = 0; + resp.val = USER_NOTIF_MAGIC; + + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0); + + + EXPECT_EQ(waitpid(pid, &status, 0), pid); + EXPECT_EQ(true, WIFEXITED(status)); + EXPECT_EQ(0, WEXITSTATUS(status)); + + close(memfd); +} + /* * TODO: * - expand NNP testing From patchwork Tue Jun 16 03:25:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 11606329 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 44812912 for ; Tue, 16 Jun 2020 03:26:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 293C420882 for ; Tue, 16 Jun 2020 03:26:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="X0n1cxGN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726992AbgFPD0Y (ORCPT ); Mon, 15 Jun 2020 23:26:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44654 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726979AbgFPDZr (ORCPT ); Mon, 15 Jun 2020 23:25:47 -0400 Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0C96EC008639 for ; Mon, 15 Jun 2020 20:25:36 -0700 (PDT) Received: by mail-pj1-x1042.google.com with SMTP id a45so659084pje.1 for ; Mon, 15 Jun 2020 20:25:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KTfRvQ2+mCIDg0D8OuodXNewLgRfaqh/goGXJ65dENQ=; b=X0n1cxGNpvYeOHV2yPu2fBSFtc2MKAx3yZ0vLy7WL65O5apqTRKBhNQ4cLyYniRtqA YIsZEQnj/LbWXG8JdYe19vjrgC11ZH94DIAwq1Z5BFk1A00VDCjehfs2gVsj0Ngd59yG hrpViber5y5CaAhre8WjGi+EtY95WWh28cVKo= 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=KTfRvQ2+mCIDg0D8OuodXNewLgRfaqh/goGXJ65dENQ=; b=qlM7UDa4CyJl5H+w4exJflJj9ExRMRx8eBZgC6qK/vqaOFuAApeVxXYgmKB3nN4ywP yhWHhLmFvhMdZh0lxNNOd2LQOSdQ9quiNFHmQ7fWhM5oNHPSRpWEerI2FHKGr5obRla0 Z0xcvuDEcEGwgmxkmkaZEVF7BSWgNaAf/RWL7zINoB0bHr857sKZmsdnAkLZbuSj9OA2 ih2ir+4mCy0Hcb1CIk4WDqGjI/d+u6T6eGyKRyHAcPfg3mlwbQhRbKHHguy+kt7e8c89 Gh6uy/2CqYg7BLgjdh1jU7WvNTXyHPZ4mwXo4ACHr2lHlWBzh2X2sziJpKKbtBXEjR7o mkxQ== X-Gm-Message-State: AOAM531bDaWIlxU3j/5iEOUdnzM/K6sOrx/KxI1C6416l8WecYoy3qHt aHWYqHJxb+HuhzZFkTaD/EcSyg== X-Google-Smtp-Source: ABdhPJx6ntz1tupSkb6Z5KF9pZydUmMhD/o4/B/Oo+8svDxMTBwbLKSSqbRRvTlmCqWioCbQypQnnA== X-Received: by 2002:a17:90a:250b:: with SMTP id j11mr1073537pje.194.1592277934971; Mon, 15 Jun 2020 20:25:34 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id m10sm775999pjs.27.2020.06.15.20.25.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2020 20:25:32 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Christian Brauner , "David S. Miller" , Christoph Hellwig , Tycho Andersen , Jakub Kicinski , Alexander Viro , Aleksa Sarai , Matt Denton , Jann Horn , Chris Palmer , Robert Sesek , Giuseppe Scrivano , Greg Kroah-Hartman , Andy Lutomirski , Will Drewry , Shuah Khan , 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 Message-Id: <20200616032524.460144-9-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200616032524.460144-1-keescook@chromium.org> References: <20200616032524.460144-1-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.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 --- 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; From patchwork Tue Jun 16 03:25:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 11606337 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 52716912 for ; Tue, 16 Jun 2020 03:26:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3476C207E8 for ; Tue, 16 Jun 2020 03:26:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="V3XA0nHM" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726392AbgFPD0g (ORCPT ); Mon, 15 Jun 2020 23:26:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44698 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726306AbgFPDZi (ORCPT ); Mon, 15 Jun 2020 23:25:38 -0400 Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B978C08C5C4 for ; Mon, 15 Jun 2020 20:25:36 -0700 (PDT) Received: by mail-pj1-x1042.google.com with SMTP id m2so893259pjv.2 for ; Mon, 15 Jun 2020 20:25:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rE3Y2iFwUUd87kC4LPkJ/n5Ro7lODcTLpnlUXVeVqP4=; b=V3XA0nHMmtCHiAAjYJ+ZyCD0LYHJYFVci/dawxxSgdePAiA4xV8RysbhxpPr+L3zVP 34KqKhpQ2oyvvwl6p1Hw7IgxnST9JWeyZLSe5rxdOOI4bbcYAgkCRIRj4tk0JM60C9JZ M+G42YS35Vm30gy42rDJy0fo0E5XO0KuRrgn0= 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=rE3Y2iFwUUd87kC4LPkJ/n5Ro7lODcTLpnlUXVeVqP4=; b=t5JGBHO3HaQyWc/RdrRM6iRb9ULfWPku4ytv4bf1JYpodrzW70ln89EAUERm9+faF5 boQeyeg0Tiy42OOeiC74S00VBc66cZlWODdzDctiv66D9aQWzmnykrDQTaA3SlbHEx1c clEBzunhvUvrrpR4FvEhH7P0udHkDtJj3GEYRE+RFTBJ7SVeIuWWC5Y7eC1Ik1czCOeK OFwJ3/f7qSn2f2vTkJv/38d0qYG5ZUoDoH5Jx609YEsZHbXki4umPYaSULB0QpfVGGBe tneHaSL6oL8FtGCykBI8jjRJoM/6Wpt/r/aHSge8yLUThbG0rqp87TijfFFgyjiWu7fn F7zQ== X-Gm-Message-State: AOAM530B2mNWq3zrOv03iiRy1HrC+x0125gXvB5h8ur3qcgS0kchHeQh 9gyirORFNUyklqyfAIy2GL2eLw== X-Google-Smtp-Source: ABdhPJxCZqVuV3kzeXed/HFT/JXAbaWaHZ3nnHfrJBQ1uX2cvtIopqK121014OWTVMCuzhtnGpPz3A== X-Received: by 2002:a17:90b:234c:: with SMTP id ms12mr836787pjb.164.1592277935719; Mon, 15 Jun 2020 20:25:35 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id ds11sm785227pjb.0.2020.06.15.20.25.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2020 20:25:32 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Christian Brauner , "David S. Miller" , Christoph Hellwig , Tycho Andersen , Jakub Kicinski , Alexander Viro , Aleksa Sarai , Matt Denton , Jann Horn , Chris Palmer , Robert Sesek , Giuseppe Scrivano , Greg Kroah-Hartman , Andy Lutomirski , Will Drewry , Shuah Khan , 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 09/11] selftests/seccomp: Rename user_trap_syscall() to user_notif_syscall() Date: Mon, 15 Jun 2020 20:25:22 -0700 Message-Id: <20200616032524.460144-10-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200616032524.460144-1-keescook@chromium.org> References: <20200616032524.460144-1-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org The user_trap_syscall() helper creates a filter with SECCOMP_RET_USER_NOTIF. To avoid confusion with SECCOMP_RET_TRAP, rename the helper to user_notif_syscall(). Additionally fix a redundant "return" after XFAIL. Signed-off-by: Kees Cook Reviewed-by: Tycho Andersen --- tools/testing/selftests/seccomp/seccomp_bpf.c | 60 +++++++++---------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 40ed846744e4..95b134933831 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -3110,10 +3110,8 @@ TEST(get_metadata) long ret; /* Only real root can get metadata. */ - if (geteuid()) { - XFAIL(return, "get_metadata requires real root"); - return; - } + if (geteuid()) + XFAIL(return, "get_metadata test requires real root"); ASSERT_EQ(0, pipe(pipefd)); @@ -3170,7 +3168,7 @@ TEST(get_metadata) ASSERT_EQ(0, kill(pid, SIGKILL)); } -static int user_trap_syscall(int nr, unsigned int flags) +static int user_notif_syscall(int nr, unsigned int flags) { struct sock_filter filter[] = { BPF_STMT(BPF_LD+BPF_W+BPF_ABS, @@ -3216,7 +3214,7 @@ TEST(user_notification_basic) /* Check that we get -ENOSYS with no listener attached */ if (pid == 0) { - if (user_trap_syscall(__NR_getppid, 0) < 0) + if (user_notif_syscall(__NR_getppid, 0) < 0) exit(1); ret = syscall(__NR_getppid); exit(ret >= 0 || errno != ENOSYS); @@ -3233,13 +3231,13 @@ TEST(user_notification_basic) EXPECT_EQ(seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog), 0); /* Check that the basic notification machinery works */ - listener = user_trap_syscall(__NR_getppid, - SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); ASSERT_GE(listener, 0); /* Installing a second listener in the chain should EBUSY */ - EXPECT_EQ(user_trap_syscall(__NR_getppid, - SECCOMP_FILTER_FLAG_NEW_LISTENER), + EXPECT_EQ(user_notif_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER), -1); EXPECT_EQ(errno, EBUSY); @@ -3303,12 +3301,12 @@ TEST(user_notification_with_tsync) /* these were exclusive */ flags = SECCOMP_FILTER_FLAG_NEW_LISTENER | SECCOMP_FILTER_FLAG_TSYNC; - ASSERT_EQ(-1, user_trap_syscall(__NR_getppid, flags)); + ASSERT_EQ(-1, user_notif_syscall(__NR_getppid, flags)); ASSERT_EQ(EINVAL, errno); /* but now they're not */ flags |= SECCOMP_FILTER_FLAG_TSYNC_ESRCH; - ret = user_trap_syscall(__NR_getppid, flags); + ret = user_notif_syscall(__NR_getppid, flags); close(ret); ASSERT_LE(0, ret); } @@ -3326,8 +3324,8 @@ TEST(user_notification_kill_in_middle) TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!"); } - listener = user_trap_syscall(__NR_getppid, - SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); ASSERT_GE(listener, 0); /* @@ -3380,8 +3378,8 @@ TEST(user_notification_signal) ASSERT_EQ(socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair), 0); - listener = user_trap_syscall(__NR_gettid, - SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_gettid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); ASSERT_GE(listener, 0); pid = fork(); @@ -3450,8 +3448,8 @@ TEST(user_notification_closed_listener) TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!"); } - listener = user_trap_syscall(__NR_getppid, - SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); ASSERT_GE(listener, 0); /* @@ -3484,8 +3482,8 @@ TEST(user_notification_child_pid_ns) ASSERT_EQ(unshare(CLONE_NEWUSER | CLONE_NEWPID), 0); - listener = user_trap_syscall(__NR_getppid, - SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); ASSERT_GE(listener, 0); pid = fork(); @@ -3524,8 +3522,8 @@ TEST(user_notification_sibling_pid_ns) TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!"); } - listener = user_trap_syscall(__NR_getppid, - SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); ASSERT_GE(listener, 0); pid = fork(); @@ -3589,8 +3587,8 @@ TEST(user_notification_fault_recv) ASSERT_EQ(unshare(CLONE_NEWUSER), 0); - listener = user_trap_syscall(__NR_getppid, - SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); ASSERT_GE(listener, 0); pid = fork(); @@ -3641,7 +3639,7 @@ TEST(user_notification_continue) TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!"); } - listener = user_trap_syscall(__NR_dup, SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_dup, SECCOMP_FILTER_FLAG_NEW_LISTENER); ASSERT_GE(listener, 0); pid = fork(); @@ -3736,7 +3734,7 @@ TEST(user_notification_filter_empty) if (pid == 0) { int listener; - listener = user_trap_syscall(__NR_mknod, SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_mknod, SECCOMP_FILTER_FLAG_NEW_LISTENER); if (listener < 0) _exit(EXIT_FAILURE); @@ -3792,7 +3790,7 @@ TEST(user_notification_filter_empty_threaded) int listener, status; pthread_t thread; - listener = user_trap_syscall(__NR_dup, SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_dup, SECCOMP_FILTER_FLAG_NEW_LISTENER); if (listener < 0) _exit(EXIT_FAILURE); @@ -3869,8 +3867,8 @@ TEST(user_notification_sendfd) } /* Check that the basic notification machinery works */ - listener = user_trap_syscall(__NR_getppid, - SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); ASSERT_GE(listener, 0); pid = fork(); @@ -3993,8 +3991,8 @@ TEST(user_notification_sendfd_rlimit) } /* Check that the basic notification machinery works */ - listener = user_trap_syscall(__NR_getppid, - SECCOMP_FILTER_FLAG_NEW_LISTENER); + listener = user_notif_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); ASSERT_GE(listener, 0); pid = fork(); From patchwork Tue Jun 16 03:25:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 11606323 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E4E29912 for ; Tue, 16 Jun 2020 03:26:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C951D207E8 for ; Tue, 16 Jun 2020 03:26:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="FKACMKyf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727070AbgFPD0O (ORCPT ); Mon, 15 Jun 2020 23:26:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44690 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727003AbgFPDZx (ORCPT ); Mon, 15 Jun 2020 23:25:53 -0400 Received: from mail-pl1-x642.google.com (mail-pl1-x642.google.com [IPv6:2607:f8b0:4864:20::642]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61F59C0085C6 for ; Mon, 15 Jun 2020 20:25:37 -0700 (PDT) Received: by mail-pl1-x642.google.com with SMTP id j4so4510328plk.3 for ; Mon, 15 Jun 2020 20:25:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0XLeJlm9EgjXcakcD9qCa51hLblsobf6+bsB3dZc0i8=; b=FKACMKyfxUA7EW9AFaoKVvRC5y/1zAscVNsROkN95jbzPz/DVctU6B9b39AAvKij7N 6Nlikz3HjI7F5mqdklSF71vSDdkiuk/lo6fE6XK2BMW71zU3jrwvPABfdtnLEM9oR5Bn 531elB+kI1SaW2n2BDWmttY4VIZSDBG5Z5y28= 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=0XLeJlm9EgjXcakcD9qCa51hLblsobf6+bsB3dZc0i8=; b=No9j1f6CbeJCgCM06g6KQoa66js7cMhzSzu8ZJhrUGZBxuoPdEpwELsTNlrEfX8yAg biz8sJHkSzUotzXwKZDqHcwOLg1ydQDNyFX3+6IEZ15dOv7uhuvYCqH7ocZyglwgprBJ ImPGDENW+pO0FZJSyXEa+Mt2D/O9r4XcANhdAPwCuhwFQKoPE3PKeOePL4as3mrPb5C4 BQf7KF37VB3d4OlnNJ0Hzl44xrT2JXtQVXM8opamf3LSotEkceKDrld0lyg0CkZZB4TO oazbz9npQAkH0vyLN7iRqRvmz8+ABEXuUl2HSx0KWqCXFC3l6mFRykgFi1/EbiIZytAV D6ig== X-Gm-Message-State: AOAM532jR6HCtB1eywpUb1iunw4m3xthNJhNJUyflw979nEdRV2Q09hK JkOeJcnOJ5M2NfBLz5I1KH5jqQ== X-Google-Smtp-Source: ABdhPJwVGDqjGiwBmdUw+0CM58qrM4XZkDqMs17lV5U6dITKbuVhjYUHCQGtjBUBVlvKZE+GWSFt+Q== X-Received: by 2002:a17:90a:634a:: with SMTP id v10mr851059pjs.50.1592277937337; Mon, 15 Jun 2020 20:25:37 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id 140sm15093613pfy.95.2020.06.15.20.25.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2020 20:25:32 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Christian Brauner , "David S. Miller" , Christoph Hellwig , Tycho Andersen , Jakub Kicinski , Alexander Viro , Aleksa Sarai , Matt Denton , Jann Horn , Chris Palmer , Robert Sesek , Giuseppe Scrivano , Greg Kroah-Hartman , Andy Lutomirski , Will Drewry , Shuah Khan , 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 10/11] seccomp: Switch addfd to Extensible Argument ioctl Date: Mon, 15 Jun 2020 20:25:23 -0700 Message-Id: <20200616032524.460144-11-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200616032524.460144-1-keescook@chromium.org> References: <20200616032524.460144-1-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org This patch is based on discussions[1] with Sargun Dhillon, Christian Brauner, and David Laight. Instead of building size into the addfd structure, make it a function of the ioctl command (which is how sizes are normally passed to ioctls). To support forward and backward compatibility, just mask out the direction and size, and match everything. The size (and any future direction) checks are done along with copy_struct_from_user() logic. Also update the selftests to check size bounds. [1] https://lore.kernel.org/lkml/20200612104629.GA15814@ircssh-2.c.rugged-nimbus-611.internal Signed-off-by: Kees Cook --- include/uapi/linux/seccomp.h | 2 - kernel/seccomp.c | 21 ++++++---- tools/testing/selftests/seccomp/seccomp_bpf.c | 40 ++++++++++++++++--- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h index c347160378e5..473a61695ac3 100644 --- a/include/uapi/linux/seccomp.h +++ b/include/uapi/linux/seccomp.h @@ -118,7 +118,6 @@ struct seccomp_notif_resp { /** * struct seccomp_notif_addfd - * @size: The size of the seccomp_notif_addfd structure * @id: The ID of the seccomp notification * @flags: SECCOMP_ADDFD_FLAG_* * @srcfd: The local fd number @@ -126,7 +125,6 @@ struct seccomp_notif_resp { * @newfd_flags: The O_* flags the remote FD should have applied */ struct seccomp_notif_addfd { - __u64 size; __u64 id; __u32 flags; __u32 srcfd; diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 3c913f3b8451..9660abf91135 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -1292,17 +1292,17 @@ static long seccomp_notify_id_valid(struct seccomp_filter *filter, } static long seccomp_notify_addfd(struct seccomp_filter *filter, - struct seccomp_notif_addfd __user *uaddfd) + struct seccomp_notif_addfd __user *uaddfd, + unsigned int size) { struct seccomp_notif_addfd addfd; struct seccomp_knotif *knotif; struct seccomp_kaddfd kaddfd; - u64 size; int ret; - ret = get_user(size, &uaddfd->size); - if (ret) - return ret; + /* 24 is original sizeof(struct seccomp_notif_addfd) */ + if (size < 24 || size >= PAGE_SIZE) + return -EINVAL; ret = copy_struct_from_user(&addfd, sizeof(addfd), uaddfd, size); if (ret) @@ -1391,6 +1391,7 @@ static long seccomp_notify_ioctl(struct file *file, unsigned int cmd, struct seccomp_filter *filter = file->private_data; void __user *buf = (void __user *)arg; + /* Fixed-size ioctls */ switch (cmd) { case SECCOMP_IOCTL_NOTIF_RECV: return seccomp_notify_recv(filter, buf); @@ -1398,11 +1399,17 @@ static long seccomp_notify_ioctl(struct file *file, unsigned int cmd, return seccomp_notify_send(filter, buf); case SECCOMP_IOCTL_NOTIF_ID_VALID: return seccomp_notify_id_valid(filter, buf); - case SECCOMP_IOCTL_NOTIF_ADDFD: - return seccomp_notify_addfd(filter, buf); + } + + /* Extensible Argument ioctls */ +#define EA_IOCTL(cmd) ((cmd) & ~(IOC_INOUT | IOCSIZE_MASK)) + switch (EA_IOCTL(cmd)) { + case EA_IOCTL(SECCOMP_IOCTL_NOTIF_ADDFD): + return seccomp_notify_addfd(filter, buf, _IOC_SIZE(cmd)); default: return -EINVAL; } +#undef EA_IOCTL } static __poll_t seccomp_notify_poll(struct file *file, diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 95b134933831..cf1480e498ea 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -216,7 +216,6 @@ struct seccomp_notif_sizes { #define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0) /* Specify remote fd */ struct seccomp_notif_addfd { - __u64 size; __u64 id; __u32 flags; __u32 srcfd; @@ -225,6 +224,22 @@ struct seccomp_notif_addfd { }; #endif +struct seccomp_notif_addfd_small { + __u64 id; + char weird[4]; +}; +#define SECCOMP_IOCTL_NOTIF_ADDFD_SMALL \ + SECCOMP_IOW(3, struct seccomp_notif_addfd_small) + +struct seccomp_notif_addfd_big { + union { + struct seccomp_notif_addfd addfd; + char buf[sizeof(struct seccomp_notif_addfd) + 8]; + }; +}; +#define SECCOMP_IOCTL_NOTIF_ADDFD_BIG \ + SECCOMP_IOWR(3, struct seccomp_notif_addfd_big) + #ifndef PTRACE_EVENTMSG_SYSCALL_ENTRY #define PTRACE_EVENTMSG_SYSCALL_ENTRY 1 #define PTRACE_EVENTMSG_SYSCALL_EXIT 2 @@ -3853,6 +3868,8 @@ TEST(user_notification_sendfd) long ret; int status, listener, memfd, fd; struct seccomp_notif_addfd addfd = {}; + struct seccomp_notif_addfd_small small = {}; + struct seccomp_notif_addfd_big big = {}; struct seccomp_notif req = {}; struct seccomp_notif_resp resp = {}; /* 100 ms */ @@ -3882,7 +3899,6 @@ TEST(user_notification_sendfd) ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); - addfd.size = sizeof(addfd); addfd.srcfd = memfd; addfd.newfd = 0; addfd.id = req.id; @@ -3906,6 +3922,16 @@ TEST(user_notification_sendfd) EXPECT_EQ(errno, EINVAL); addfd.newfd = 0; + /* Verify small size cannot be set */ + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD_SMALL, &small), -1); + EXPECT_EQ(errno, EINVAL); + + /* Verify we can't send bits filled in unknown buffer area */ + memset(&big, 0xAA, sizeof(big)); + big.addfd = addfd; + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD_BIG, &big), -1); + EXPECT_EQ(errno, E2BIG); + /* Verify we can set an arbitrary remote fd */ fd = ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd); /* @@ -3921,10 +3947,15 @@ TEST(user_notification_sendfd) EXPECT_EQ(ret, 0); } + /* Verify we can set an arbitrary remote fd with large size */ + memset(&big, 0x0, sizeof(big)); + big.addfd = addfd; + fd = ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD_BIG, &big); + EXPECT_EQ(fd, 6); + /* Verify we can set a specific remote fd */ addfd.newfd = 42; addfd.flags = SECCOMP_ADDFD_FLAG_SETFD; - fd = ioctl(listener, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd); EXPECT_EQ(fd, 42); ret = filecmp(getpid(), pid, memfd, fd); @@ -3935,10 +3966,10 @@ TEST(user_notification_sendfd) EXPECT_EQ(ret, 0); } + /* Resume syscall */ resp.id = req.id; resp.error = 0; resp.val = USER_NOTIF_MAGIC; - EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0); /* @@ -4006,7 +4037,6 @@ TEST(user_notification_sendfd_rlimit) ASSERT_EQ(prlimit(pid, RLIMIT_NOFILE, &lim, NULL), 0); - addfd.size = sizeof(addfd); addfd.srcfd = memfd; addfd.newfd_flags = O_CLOEXEC; addfd.newfd = 0; From patchwork Tue Jun 16 03:25:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 11606325 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5AB7813A0 for ; Tue, 16 Jun 2020 03:26:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 429B4207E8 for ; Tue, 16 Jun 2020 03:26:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="S1Ljgo8z" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727064AbgFPD0O (ORCPT ); Mon, 15 Jun 2020 23:26:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44698 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727022AbgFPDZz (ORCPT ); Mon, 15 Jun 2020 23:25:55 -0400 Received: from mail-pg1-x543.google.com (mail-pg1-x543.google.com [IPv6:2607:f8b0:4864:20::543]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 814CBC0085C8 for ; Mon, 15 Jun 2020 20:25:38 -0700 (PDT) Received: by mail-pg1-x543.google.com with SMTP id s10so8602965pgm.0 for ; Mon, 15 Jun 2020 20:25:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FgXZgAefh49mTlceIe2gMjyNtNfme1hD6/ROx37cyNY=; b=S1Ljgo8zfvhVzanePE7S94hAQri20mgqdjLW6ZcKLS6mTkJUfcTmnH4BEuciFBypo5 yLWzTGO7qRQ8fikTyxEylXhFYKidtnuktnSCAyG9hUsTVHRIs7tKGNPxSrXIQPwYPsOY BRevYE/VxN46fKeOiOKqs7U325LSQxVUFKdvM= 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=FgXZgAefh49mTlceIe2gMjyNtNfme1hD6/ROx37cyNY=; b=EXbx4+1S/Ybtsx5kzJ6/QoSi47f5b+/zNdYT8HVZm/2h8Pb1lXBYwym7LAfisBxH5W qFQiYmmzOnWF8lxMs3cglBxPOVzBsTLL2zsxe4EnQq9k8aXzYadSSSrd0V2XFl3tUbz8 dSHO3f61Bv7M45Ncx46bwu7zezqo29Z9JpqMKky6dDVRGrU2WatY62NHBZ0z5mcEMCKW +YWExQuy7LOFgzdCYx1AUdBcUkxT3XrNNLrUoxdUZR4plzbKnY/DgtD8ApQWapyOgWWR ItJCsTm/pIOwshXLJseRslArF7EPbcnkeJUKIlPB5GCPU77TuEMMcX0ffY4U4CpngmeO QfMQ== X-Gm-Message-State: AOAM533Q3/Zx/2dQyyCEblunhVhsudivWJhSoKh9QHns5tr9ClLiIT2L IqxBB0+NdHsLosscwcYDmr1bIg== X-Google-Smtp-Source: ABdhPJz8g8MvECoY+P37sOjiU/K6JaO1aTPm3WR2ovoaD+ETVPlO0tQ326sVmyypOrheNxONtOEH1g== X-Received: by 2002:a62:178b:: with SMTP id 133mr272094pfx.238.1592277938070; Mon, 15 Jun 2020 20:25:38 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id c7sm13160189pgh.84.2020.06.15.20.25.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2020 20:25:32 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , stable@vger.kernel.org, Sargun Dhillon , Christian Brauner , "David S. Miller" , Christoph Hellwig , Tycho Andersen , Jakub Kicinski , Alexander Viro , Aleksa Sarai , Matt Denton , Jann Horn , Chris Palmer , Robert Sesek , Giuseppe Scrivano , Greg Kroah-Hartman , Andy Lutomirski , Will Drewry , Shuah Khan , 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 11/11] seccomp: Fix ioctl number for SECCOMP_IOCTL_NOTIF_ID_VALID Date: Mon, 15 Jun 2020 20:25:24 -0700 Message-Id: <20200616032524.460144-12-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200616032524.460144-1-keescook@chromium.org> References: <20200616032524.460144-1-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org When SECCOMP_IOCTL_NOTIF_ID_VALID was first introduced it had the wrong direction flag set. While this isn't a big deal as nothing currently enforces these bits in the kernel, it should be defined correctly. Fix the define and provide support for the old command until it is no longer needed for backward compatibility. Fixes: 6a21cc50f0c7 ("seccomp: add a return code to trap to userspace") Cc: stable@vger.kernel.org Signed-off-by: Kees Cook --- include/uapi/linux/seccomp.h | 2 +- kernel/seccomp.c | 9 +++++++++ tools/testing/selftests/seccomp/seccomp_bpf.c | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h index 473a61695ac3..6ba18b82a02e 100644 --- a/include/uapi/linux/seccomp.h +++ b/include/uapi/linux/seccomp.h @@ -142,7 +142,7 @@ struct seccomp_notif_addfd { #define SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif) #define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, \ struct seccomp_notif_resp) -#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOR(2, __u64) +#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOW(2, __u64) /* On success, the return value is the remote process's added fd number */ #define SECCOMP_IOCTL_NOTIF_ADDFD SECCOMP_IOW(3, \ struct seccomp_notif_addfd) diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 9660abf91135..61e556bca338 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -43,6 +43,14 @@ #include #include +/* + * When SECCOMP_IOCTL_NOTIF_ID_VALID was first introduced, it had the + * wrong direction flag in the ioctl number. This is the broken one, + * which the kernel needs to keep supporting until all userspaces stop + * using the wrong command number. + */ +#define SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR SECCOMP_IOR(2, __u64) + enum notify_state { SECCOMP_NOTIFY_INIT, SECCOMP_NOTIFY_SENT, @@ -1397,6 +1405,7 @@ static long seccomp_notify_ioctl(struct file *file, unsigned int cmd, return seccomp_notify_recv(filter, buf); case SECCOMP_IOCTL_NOTIF_SEND: return seccomp_notify_send(filter, buf); + case SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR: case SECCOMP_IOCTL_NOTIF_ID_VALID: return seccomp_notify_id_valid(filter, buf); } diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index cf1480e498ea..403c6d0f149e 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -184,7 +184,7 @@ struct seccomp_metadata { #define SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif) #define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, \ struct seccomp_notif_resp) -#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOR(2, __u64) +#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOW(2, __u64) struct seccomp_notif { __u64 id;