Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp822390ybt; Wed, 17 Jun 2020 15:07:34 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxCI7eJ7qDIs7DFNL4bc8AzydZcf3MbNvj4lYqD47SD0hcqp1TO4xGyCO0ERaeUWEFq4zFM X-Received: by 2002:a17:906:f6d6:: with SMTP id jo22mr1175458ejb.310.1592431653914; Wed, 17 Jun 2020 15:07:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592431653; cv=none; d=google.com; s=arc-20160816; b=l2hQ9ML/mZx/2SumW/bnCPo8++lA0aL4TPTMVQcmtnCO6WLw5CQZCzm+PRy4b5xV5J QbpQtHsj1cTGSlgysuGIgT/1qv6QqfrbpEr8ezu1MiInUJqtfJDd8uMAafDJ/3Rwg7vb 1/qfDMngR4bh30aQmN5A4GkCnctiHelote5QXB316BV4IM479SkXbwI9eR3wQ/AYFowg oAwo9m7sx4QJQO9YLXHbBAdcZiVpHejR/o/yGy3j5iHpI+na/PgLFXqRhIlnJh7L1kRC l3MXIGacN/3/ppJhbaE9YGiakExDaZLYVxfuMy7x+b/pdI8+CT/I/AdI8nfc2IMn1Zn6 VPDw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=JfpI1GG/4ASH8XTwm9WwhsnqJPuQkeJ3KfU5iE0siPk=; b=Y2b3352qEqOPrM5HR64SArgoDrpfcDZ4DEjbtbUHTHIUVeg+2zuBli+LdRHlPzrFdn GmmburKLNbYgs//8OA4tkwLJgy5uv24bOcm+/LS4yxL6PtmpYmO5xtRyS5b0JSQBnC1z nXqnC/k6zCMI4Ml4ST0HSkW+mywgV2yPs6BwUWSkE8CCmC/NvWtHIFy6oBJkBE9G49nI 2xBNpVqp8kAaxdEf5EhcQFygppCTPIE1Df56hFpO5pszX4SKAqViJjtKNylsAs7QFIBl 0ZYe8UmGqw7wZVbUxaZTtMiv82XlTx87Bo/BfJmhClPrlOMPy8iG2NOGE9szM//0DTcL OvqA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=CyK2Y7jK; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id 89si791522edo.459.2020.06.17.15.07.11; Wed, 17 Jun 2020 15:07:33 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=CyK2Y7jK; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727089AbgFQWDf (ORCPT + 99 others); Wed, 17 Jun 2020 18:03:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44908 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727073AbgFQWDd (ORCPT ); Wed, 17 Jun 2020 18:03:33 -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 A6F3BC0613ED for ; Wed, 17 Jun 2020 15:03:32 -0700 (PDT) Received: by mail-pl1-x643.google.com with SMTP id d8so1547612plo.12 for ; Wed, 17 Jun 2020 15:03:32 -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=JfpI1GG/4ASH8XTwm9WwhsnqJPuQkeJ3KfU5iE0siPk=; b=CyK2Y7jKcg3jWb83XP40NF0XUYGVXD+1V+4pT7KZSo4wCLqQ9iB9bRiDEd4nW56PXM hpIQOB7drdivotPmqckm3icsG3S6fJqxUXZUgTWB/JGpBy0Mts6JHOvn0vGN1qiSJx8E A8747kbFVyLgnx3F2OQvdMh3YUSLu0KYMhp+0= 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=JfpI1GG/4ASH8XTwm9WwhsnqJPuQkeJ3KfU5iE0siPk=; b=ahG7BBRQk3nffj1y+Kcv9KDmck1RlOoIgqluYnfCVxqjNNwzdbTtBiQsjfu3OI4ZGo AgrkRdgDCR+zFEi8QjLdCq67pZBOxg2L/r4dkI2mbmLth6kBNi/+cRM9Yz0jz792EIGD 2kUP/cuXWGNjDdl6JiBi76i8+RDJWYTwd8G2J5muLYMvDcj70eMHZXz+I0Y0lt3p7pMr sQ0CkNXRGIDB8fuh3OWnsDO6Ku2fQ5bzP5+caDGalwqBgOWV3CCZ3xPlscx2B3sKpULK 21ZsmY8Rv1LcRzNlOz4wGIzMvjtlKa3pSpeFy9ydVedA67AdRV6AZkT9y+CgEpnEXvxM +10w== X-Gm-Message-State: AOAM5327s2Vi4ORpaFUqut6dNDHey6uAcBLoi2ZbVfcPZkykmkjTF2hj kCir+p03uyeDFXWtO7Oj+xmAFw== X-Received: by 2002:a17:90a:d803:: with SMTP id a3mr1130991pjv.125.1592431412195; Wed, 17 Jun 2020 15:03:32 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id t201sm755132pfc.104.2020.06.17.15.03.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Jun 2020 15:03:30 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Christian Brauner , Tycho Andersen , David Laight , Christoph Hellwig , "David S. Miller" , 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 v5 3/7] fs: Add fd_install_received() wrapper for __fd_install_received() Date: Wed, 17 Jun 2020 15:03:23 -0700 Message-Id: <20200617220327.3731559-4-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200617220327.3731559-1-keescook@chromium.org> References: <20200617220327.3731559-1-keescook@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org For both pidfd and seccomp, the __user pointer is not used. Update __fd_install_received() to make writing to ufd optional via a NULL check. However, for the fd_install_received_user() wrapper, ufd is NULL checked so an -EFAULT can be returned to avoid changing the SCM_RIGHTS interface behavior. Add new wrapper fd_install_received() for pidfd and seccomp that does not use the ufd argument. For the new helper, the new fd needs to be returned on success. Update the existing callers to handle it. Signed-off-by: Kees Cook --- fs/file.c | 22 ++++++++++++++-------- include/linux/file.h | 7 +++++++ net/compat.c | 2 +- net/core/scm.c | 2 +- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/fs/file.c b/fs/file.c index f2167d6feec6..de85a42defe2 100644 --- a/fs/file.c +++ b/fs/file.c @@ -942,9 +942,10 @@ 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. Writes the fd number to userspace. + * checks and count updates. Optionally writes the fd number to userspace, if + * @ufd is non-NULL. * - * 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) { @@ -960,20 +961,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) { + 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..e19974ed9322 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -9,6 +9,7 @@ #include #include #include +#include struct file; @@ -96,8 +97,14 @@ extern int __fd_install_received(struct file *file, int __user *ufd, static inline int fd_install_received_user(struct file *file, int __user *ufd, unsigned int o_flags) { + if (ufd == NULL) + return -EFAULT; return __fd_install_received(file, ufd, o_flags); } +static inline int fd_install_received(struct file *file, unsigned int o_flags) +{ + return __fd_install_received(file, NULL, o_flags); +} extern void flush_delayed_fput(void); extern void __fput_sync(struct file *); 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; } -- 2.25.1