Received: by 2002:a25:683:0:0:0:0:0 with SMTP id 125csp945878ybg; Wed, 3 Jun 2020 18:55:05 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwmAcSQ7tDiTxc3KMfq92snHSFszNAWyA47iP+muTV3Jzpz9JcXMrj2wrDir/0Q4jpNeUgG X-Received: by 2002:a17:906:70ca:: with SMTP id g10mr1956896ejk.171.1591235705413; Wed, 03 Jun 2020 18:55:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1591235705; cv=none; d=google.com; s=arc-20160816; b=bpoIpOR7YBctmZhi6HCaUo05QsRlyAW46zDwsYm7Dl2x8bf2m2ZF4gUs9AuI4BlVPT epeObqP42rpxLhwrD8i9Coj+FpOsntG/zJrZ0Lwr3KR2AdvZ15EHxF66uHj8nOEXoeQY qtmF/TvvRRicoWD238V08rck+QlVcSJ5yLR1N2bhx9A5dvnqAD7S6Mhw+Ph8B38es4UD qIsEy0nPpXCecfnIzzcf6mdRdUPu89qvqv7/hEoSgpL0FXl7HnYGKxxURjR7EQwDX4/J 160NfbmtdZcrB34qVfoXKOMWo6+jU1GDRa6jib3g3lHNcuJq411XNY3AFLeeuxWDpf1V Kq+w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date; bh=FVAxeH4OcJOPTd8Y+L4JkkiveNpmOjkr+ZD0iR9iZgo=; b=IVmyd1IERRqT9V/7keV0V/xLqt9EoUCTnTjLpvmSB7Ti9uRCGsfpBGi5iNFVR2O0Zp fdkFdCf5Sg6z5zz6hyr57Ig+dA8azYXF8MaDgVj283C4uQX0zYacyGZAp5LMa2puP5ir QHzc5PU0Q5ORUOCCqR8L9mMqv/FxyWiXlJ0gdF5yuvA7peGCUglBhv6mFU7lIlAUxsou kK7ANqP8j0OjoM8HKJ8o3OZHtVoQeKR2LI7gJq4uNk1zZ5pFlZ0uqPM2Y3IYUaD6nRvW Tp2fUvyGE5tygb6JhwPAz3bLHA/iG5uBiec+iDkGVnqx7YP1Dc7Ti5OBlWPWp1i/kd1S DEnw== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id l12si687625eje.751.2020.06.03.18.54.42; Wed, 03 Jun 2020 18:55:05 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727818AbgFDBY7 (ORCPT + 99 others); Wed, 3 Jun 2020 21:24:59 -0400 Received: from youngberry.canonical.com ([91.189.89.112]:42656 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725946AbgFDBY7 (ORCPT ); Wed, 3 Jun 2020 21:24:59 -0400 Received: from ip5f5af183.dynamic.kabel-deutschland.de ([95.90.241.131] helo=wittgenstein) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jgecn-0006qD-L0; Thu, 04 Jun 2020 01:24:53 +0000 Date: Thu, 4 Jun 2020 03:24:52 +0200 From: Christian Brauner To: Sargun Dhillon Cc: Kees Cook , linux-kernel@vger.kernel.org, Tycho Andersen , Matt Denton , Jann Horn , Chris Palmer , Aleksa Sarai , Robert Sesek , containers@lists.linux-foundation.org, Giuseppe Scrivano , Greg Kroah-Hartman , Al Viro , Daniel Wagner , "David S . Miller" , John Fastabend , Tejun Heo , stable@vger.kernel.org, cgroups@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: Re: [PATCH v3 1/4] fs, net: Standardize on file_receive helper to move fds across processes Message-ID: <20200604012452.vh33nufblowuxfed@wittgenstein> References: <20200603011044.7972-1-sargun@sargun.me> <20200603011044.7972-2-sargun@sargun.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20200603011044.7972-2-sargun@sargun.me> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Jun 02, 2020 at 06:10:41PM -0700, Sargun Dhillon wrote: > Previously there were two chunks of code where the logic to receive file > descriptors was duplicated in net. The compat version of copying > file descriptors via SCM_RIGHTS did not have logic to update cgroups. > Logic to change the cgroup data was added in: > commit 48a87cc26c13 ("net: netprio: fd passed in SCM_RIGHTS datagram not set correctly") > commit d84295067fc7 ("net: net_cls: fd passed in SCM_RIGHTS datagram not set correctly") > > This was not copied to the compat path. This commit fixes that, and thus > should be cherry-picked into stable. > > This introduces a helper (file_receive) which encapsulates the logic for > handling calling security hooks as well as manipulating cgroup information. > This helper can then be used other places in the kernel where file > descriptors are copied between processes > > I tested cgroup classid setting on both the compat (x32) path, and the > native path to ensure that when moving the file descriptor the classid > is set. > > Signed-off-by: Sargun Dhillon > Suggested-by: Kees Cook > Cc: Al Viro > Cc: Christian Brauner > Cc: Daniel Wagner > Cc: David S. Miller > Cc: Jann Horn , > Cc: John Fastabend > Cc: Tejun Heo > Cc: Tycho Andersen > Cc: stable@vger.kernel.org > Cc: cgroups@vger.kernel.org > Cc: linux-fsdevel@vger.kernel.org > Cc: linux-kernel@vger.kernel.org > --- > fs/file.c | 35 +++++++++++++++++++++++++++++++++++ > include/linux/file.h | 1 + > net/compat.c | 10 +++++----- > net/core/scm.c | 14 ++++---------- > 4 files changed, 45 insertions(+), 15 deletions(-) > > diff --git a/fs/file.c b/fs/file.c > index abb8b7081d7a..5afd76fca8c2 100644 > --- a/fs/file.c > +++ b/fs/file.c > @@ -18,6 +18,9 @@ > #include > #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,38 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) > return err; > } > > +/* > + * File Receive - Receive a file from another process > + * > + * This function is designed to receive files from other tasks. It encapsulates > + * logic around security and cgroups. The file descriptor provided must be a > + * freshly allocated (unused) file descriptor. > + * > + * This helper does not consume a reference to the file, so the caller must put > + * their reference. > + * > + * Returns 0 upon success. > + */ > +int file_receive(int fd, struct file *file) This is all just a remote version of fd_install(), yet it deviates from fd_install()'s semantics and naming. That's not great imho. What about naming this something like: fd_install_received() and move the get_file() out of there so it has the same semantics as fd_install(). It seems rather dangerous to have a function like fd_install() that consumes a reference once it returned and another version of this that is basically the same thing but doesn't consume a reference because it takes its own. Seems an invitation for confusion. Does that make sense? > +{ > + struct socket *sock; > + int err; > + > + err = security_file_receive(file); > + if (err) > + return err; > + > + fd_install(fd, get_file(file)); > + > + sock = sock_from_file(file, &err); > + if (sock) { > + sock_update_netprioidx(&sock->sk->sk_cgrp_data); > + sock_update_classid(&sock->sk->sk_cgrp_data); > + } > + > + 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 142d102f285e..7b56dc23e560 100644 > --- a/include/linux/file.h > +++ b/include/linux/file.h > @@ -94,4 +94,5 @@ extern void fd_install(unsigned int fd, struct file *file); > extern void flush_delayed_fput(void); > extern void __fput_sync(struct file *); > > +extern int file_receive(int fd, struct file *file); > #endif /* __LINUX_FILE_H */ > diff --git a/net/compat.c b/net/compat.c > index 4bed96e84d9a..8ac0e7e09208 100644 > --- a/net/compat.c > +++ b/net/compat.c > @@ -293,9 +293,6 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) > > for (i = 0, cmfptr = (int __user *) CMSG_COMPAT_DATA(cm); i < fdmax; i++, cmfptr++) { > int new_fd; > - err = security_file_receive(fp[i]); > - if (err) > - break; > err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & kmsg->msg_flags > ? O_CLOEXEC : 0); > if (err < 0) > @@ -306,8 +303,11 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) > put_unused_fd(new_fd); > break; > } > - /* Bump the usage count and install the file. */ > - fd_install(new_fd, get_file(fp[i])); > + err = file_receive(new_fd, fp[i]); > + if (err) { > + put_unused_fd(new_fd); > + break; > + } > } > > if (i > 0) { > diff --git a/net/core/scm.c b/net/core/scm.c > index dc6fed1f221c..ba93abf2881b 100644 > --- a/net/core/scm.c > +++ b/net/core/scm.c > @@ -303,11 +303,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) > for (i=0, cmfptr=(__force int __user *)CMSG_DATA(cm); i i++, cmfptr++) > { > - struct socket *sock; > int new_fd; > - err = security_file_receive(fp[i]); > - if (err) > - break; > err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & msg->msg_flags > ? O_CLOEXEC : 0); > if (err < 0) > @@ -318,13 +314,11 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) > put_unused_fd(new_fd); > break; > } > - /* Bump the usage count and install the file. */ > - sock = sock_from_file(fp[i], &err); > - if (sock) { > - sock_update_netprioidx(&sock->sk->sk_cgrp_data); > - sock_update_classid(&sock->sk->sk_cgrp_data); > + err = file_receive(new_fd, fp[i]); > + if (err) { > + put_unused_fd(new_fd); > + break; > } > - fd_install(new_fd, get_file(fp[i])); > } > > if (i > 0) > -- > 2.25.1 >