From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B0A69C433E3 for ; Thu, 9 Jul 2020 18:27:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8723B207D0 for ; Thu, 9 Jul 2020 18:27:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="fOSIJ+Sg" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727121AbgGIS1W (ORCPT ); Thu, 9 Jul 2020 14:27:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55338 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726863AbgGIS04 (ORCPT ); Thu, 9 Jul 2020 14:26:56 -0400 Received: from mail-pj1-x1043.google.com (mail-pj1-x1043.google.com [IPv6:2607:f8b0:4864:20::1043]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10C15C08E89D for ; Thu, 9 Jul 2020 11:26:55 -0700 (PDT) Received: by mail-pj1-x1043.google.com with SMTP id f16so1487150pjt.0 for ; Thu, 09 Jul 2020 11:26:55 -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=m9EvYkpK8m2+eOZfx9Q9uzmaDoSgXM6/WboltFVCshE=; b=fOSIJ+Sgip42jp27tz4InB+igGqj6wu3SRAzdjCsack3vu0Qh5VUr694HYRBKAK8DA vO2bI0cKp0b0Uo8qLGwo12xSeFZZFLL5h6rfdt9IdzIpqDwqImYiW33UIiz4mhSZ1Bi8 uMB8wurGC4s9lzvPZpZLUfsEVT6tzdAJFlg7E= 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=m9EvYkpK8m2+eOZfx9Q9uzmaDoSgXM6/WboltFVCshE=; b=biAVMnB+aOVl+QOkj+MscE90Fkk3Th7Jz7AZe9E0MqJ5xSgtckmRyiNcor8jpGK1yP BkE/7XNxnk0rjClRsJLHXu4EQFveKhfKun6thOJJWmXdPyGJDnvOdnCOoLF66pYRRVq9 tPk6ZDSESrM/y+uzHxySW6JcBrb5M7f3BSeaYgMZQJwkcF1HWFvR9UKXV4rcEOlsSCMG 3KViASvkZef5U+jSLgXSJnFHefQp5vVVNPRn41cVgArapEBRbX3gmISrPlXMD0cxsDP+ UVIBJMvRsgz5COlA6YOsjdOPEUVU345hStDUWldR5xuYkCn7CHjWiK0fpmLRvUM0lDM4 PD2Q== X-Gm-Message-State: AOAM5326/Gj+u2bzF0qaX5mlXgDD4zJkr8BLA2XE95d9jbMoLQPLUVWD 9zCu9/Whdxs5fN80UbgbD829AQ== X-Google-Smtp-Source: ABdhPJzOiJdo9XUhfFmzsLtKE9Q4WqODbec7Lh1dEoOnSgjn1Ka/VvFiaw9y4DfHmmNv9NU8D+hzRg== X-Received: by 2002:a17:90a:c715:: with SMTP id o21mr1512547pjt.35.1594319214617; Thu, 09 Jul 2020 11:26:54 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id y6sm3364322pji.2.2020.07.09.11.26.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2020 11:26:51 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Sargun Dhillon , Christian Brauner , 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 v7 7/9] fs: Expand __receive_fd() to accept existing fd Date: Thu, 9 Jul 2020 11:26:40 -0700 Message-Id: <20200709182642.1773477-8-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200709182642.1773477-1-keescook@chromium.org> References: <20200709182642.1773477-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 Expand __receive_fd() with support for replace_fd() for the coming seccomp "addfd" ioctl(). Add new wrapper receive_fd_replace() for the new behavior and update existing wrappers to retain old behavior. Thanks to Colin Ian King for pointing out an uninitialized variable exposure in an earlier version of this patch. Reviewed-by: Sargun Dhillon Acked-by: Christian Brauner Signed-off-by: Kees Cook --- fs/file.c | 25 +++++++++++++++++++------ include/linux/file.h | 10 +++++++--- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/fs/file.c b/fs/file.c index 87954bab9306..feebdc17bf46 100644 --- a/fs/file.c +++ b/fs/file.c @@ -935,6 +935,7 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) /** * __receive_fd() - 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: __user pointer to write new fd number to * @o_flags: the O_* flags to apply to the new fd entry @@ -948,7 +949,7 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) * * Returns newly install fd or -ve on error. */ -int __receive_fd(struct file *file, int __user *ufd, unsigned int o_flags) +int __receive_fd(int fd, struct file *file, int __user *ufd, unsigned int o_flags) { int new_fd; int error; @@ -957,21 +958,33 @@ int __receive_fd(struct file *file, int __user *ufd, unsigned int o_flags) 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; + } else { + new_fd = fd; + } if (ufd) { error = put_user(new_fd, ufd); if (error) { - put_unused_fd(new_fd); + if (fd < 0) + put_unused_fd(new_fd); return error; } } + if (fd < 0) { + fd_install(new_fd, get_file(file)); + } else { + error = replace_fd(new_fd, file, o_flags); + if (error) + return error; + } + /* Bump the sock usage counts, if any. */ __receive_sock(file); - fd_install(new_fd, get_file(file)); return new_fd; } diff --git a/include/linux/file.h b/include/linux/file.h index d9fee9f5c8da..225982792fa2 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -92,18 +92,22 @@ extern void put_unused_fd(unsigned int fd); extern void fd_install(unsigned int fd, struct file *file); -extern int __receive_fd(struct file *file, int __user *ufd, +extern int __receive_fd(int fd, struct file *file, int __user *ufd, unsigned int o_flags); static inline int receive_fd_user(struct file *file, int __user *ufd, unsigned int o_flags) { if (ufd == NULL) return -EFAULT; - return __receive_fd(file, ufd, o_flags); + return __receive_fd(-1, file, ufd, o_flags); } static inline int receive_fd(struct file *file, unsigned int o_flags) { - return __receive_fd(file, NULL, o_flags); + return __receive_fd(-1, file, NULL, o_flags); +} +static inline int receive_fd_replace(int fd, struct file *file, unsigned int o_flags) +{ + return __receive_fd(fd, file, NULL, o_flags); } extern void flush_delayed_fput(void); -- 2.25.1