Received: by 2002:a25:ef43:0:0:0:0:0 with SMTP id w3csp1043517ybm; Fri, 29 May 2020 19:47:24 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwgEPQafU0o2fZwA6Xe8P5848DBRmaIji1ipGBuW6fqp5kMVIYqK+EoSKP5dKNPc/qQg5MW X-Received: by 2002:a05:6402:1d82:: with SMTP id dk2mr9588085edb.75.1590806844211; Fri, 29 May 2020 19:47:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1590806844; cv=none; d=google.com; s=arc-20160816; b=o7O5Z8a+8JrZ0r9J0uE+BMgMZKWi+CvMVxvcNsdG0XQhE8A6GzCJkncKcU11cgpn5u TbbLXVgjHp5ZTT5m1cUhQuhwhzhbVVGmrTi0YxyU/hZ4CVc6ozehGu01yoKBbcl/kBST qY/VqUgIAVjemLPBYqP0fy2JKGUws3vwG2ta29oNEpyJCHq9volC2X7sFCxzjYtUNvN2 Y8ntRkrMtB1vdon8kbKUo5619RM+tKNceVZbUZAkqr2lXvhm2sr3yXE7xtDdH3csmO+2 4IRBwZUp4ny2IEZFBqS3iT4lj98ly4kquRwAbmbufO8crN2rCKXmNHwqaf1VrPrq8Nr9 I8rw== 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 :dkim-signature; bh=oDYQmVPOibs4z3Bqe4WQyN6ZoKMzb3qd/HP7vLURjZU=; b=lExTXetK+te/9tJhiC+Ik4I9m0bOgWzK7iKqB3r7LR+RXw1JCzx12zbsjAgwb3Und6 UFxhM5/j8LwN57gbA431I0fcsmjuYhrhd6e8awkF1Endb3hImuh5FXr35HMGC4ve4grQ NITcXPUbL3IOiv9b1rqN4P4a0M/smEiBFCe3m4fSe63d1L5dXv/20sqiSHBOb+cTul5Y AhqNAx/AO2yRFZJhTmTwoOueVRdcoPa6pwD5j6i6nVDuEAKM3/we387jGS9DKdTAO9gt SSJa+7Anl45QUfXKjXiY6gp20JZI9dTSTyibD4Cx+AbWCPuXooqEfYHzoms9ZlbzM6/d dHeg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=FLEvSuRe; 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 ny24si6560774ejb.445.2020.05.29.19.47.00; Fri, 29 May 2020 19:47:24 -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=FLEvSuRe; 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 S1728751AbgE3CnO (ORCPT + 99 others); Fri, 29 May 2020 22:43:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42180 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728406AbgE3CnN (ORCPT ); Fri, 29 May 2020 22:43:13 -0400 Received: from mail-pl1-x641.google.com (mail-pl1-x641.google.com [IPv6:2607:f8b0:4864:20::641]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 17EA0C08C5C9 for ; Fri, 29 May 2020 19:43:13 -0700 (PDT) Received: by mail-pl1-x641.google.com with SMTP id m7so1950319plt.5 for ; Fri, 29 May 2020 19:43:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=oDYQmVPOibs4z3Bqe4WQyN6ZoKMzb3qd/HP7vLURjZU=; b=FLEvSuReL5H6hsXVKHoXO8isNCsg+p4fYK7Y90FENXhZQDsrmnLwiS7rRtjySYUzPw 42MDTFgWSby4XuFD3/rL5UWXp8f4xvZEkGnsD4lnvApIoaPjZqPEG/wkx4SebJEyiRcJ Arr+LH+BgVy+XxpSa/mXl4LVHmbgyhWrEzu6k= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=oDYQmVPOibs4z3Bqe4WQyN6ZoKMzb3qd/HP7vLURjZU=; b=n+fFt/6fUpKyaV9KjBztgUOBB/QariHnZ2KakJ0tSI0ICyfs7tJaK+KLaw4Ibw/Gi8 THHhknLO3CXQZ01b58dYrnhYxcnldTkUISH/XzQ91HcUsMS0V3wgAscJm6MRpHTwxOAO ttpVCX9V41TW19YgeHmO+e6sLMkGPLinrR4yAqXwFsBWgrSsNxC//etlo8neGx0TYFm4 DqPdrsIegO2/r9+xTiq2Ex/ZrP2qBGXP/DMtjpJWCrxISDi9ddTL1YOLxCPyVirm9zyS hEiy68pqjwrG2ikz5hX/4fYwR7FPfi4idX2BZHWJPw2HGgZ9IvAdM8BzYe8fbvv5N2v1 PnCQ== X-Gm-Message-State: AOAM530bJIuYXtcE7zWK45DLI/xm2Wi3X1G0QA5bA4Iqxt35hgJmKsRM YRDfzFIocabIpWpEbBCV1g6F1g== X-Received: by 2002:a17:90b:3d7:: with SMTP id go23mr12372080pjb.9.1590806592564; Fri, 29 May 2020 19:43:12 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id o27sm8105034pgd.18.2020.05.29.19.43.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2020 19:43:11 -0700 (PDT) Date: Fri, 29 May 2020 19:43:10 -0700 From: Kees Cook To: Sargun Dhillon Cc: christian.brauner@ubuntu.com, containers@lists.linux-foundation.org, cyphar@cyphar.com, jannh@google.com, jeffv@google.com, linux-api@vger.kernel.org, linux-kernel@vger.kernel.org, palmer@google.com, rsesek@google.com, tycho@tycho.ws, Matt Denton , Al Viro Subject: Re: [PATCH v2 2/3] seccomp: Introduce addfd ioctl to seccomp user notifier Message-ID: <202005291926.E9004B4@keescook> References: <20200528110858.3265-1-sargun@sargun.me> <20200528110858.3265-3-sargun@sargun.me> <202005282345.573B917@keescook> <20200530011054.GA14852@ircssh-2.c.rugged-nimbus-611.internal> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200530011054.GA14852@ircssh-2.c.rugged-nimbus-611.internal> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, May 30, 2020 at 01:10:55AM +0000, Sargun Dhillon wrote: > // And then SCM reads: > for (i=0, cmfptr=(__force int __user *)CMSG_DATA(cm); i i++, cmfptr++) > { > int new_fd; > err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & msg->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; > } > > err = file_receive(new_fd, fp[i]); > if (err) { > put_unused_fd(new_fd); > break; > } > } > > And our code reads: > > > static void seccomp_handle_addfd(struct seccomp_kaddfd *addfd) > { > int ret, err; > > /* > * Remove the notification, and reset the list pointers, indicating > * that it has been handled. > */ > list_del_init(&addfd->list); > > if (addfd->fd == -1) { > ret = get_unused_fd_flags(addfd->flags); > if (ret < 0) > goto err; > > err = file_receive(ret, addfd->file); > if (err) { > put_unused_fd(ret); > ret = err; > } > } else { > ret = file_receive_replace(addfd->fd, addfd->flags, > addfd->file); > } > > err: > addfd->ret = ret; > complete(&addfd->completion); > } > > > And the pidfd getfd code reads: > > static int pidfd_getfd(struct pid *pid, int fd) > { > struct task_struct *task; > struct file *file; > int ret, err; > > task = get_pid_task(pid, PIDTYPE_PID); > if (!task) > return -ESRCH; > > file = __pidfd_fget(task, fd); > put_task_struct(task); > if (IS_ERR(file)) > return PTR_ERR(file); > > ret = get_unused_fd_flags(O_CLOEXEC); > if (ret >= 0) { > err = file_receive(ret, file); > if (err) { > put_unused_fd(ret); > ret = err; > } > } > > fput(file); > return ret; > } I mean, yes, that's certainly better, but it just seems a shame that everyone has to do the get_unused/put_unused dance just because of how SCM_RIGHTS does this weird put_user() in the middle. Can anyone clarify the expected failure mode from SCM_RIGHTS? Can we move the put_user() after instead? I think cleanup would just be: replace_fd(fd, NULL, 0) So: (updated to skip sock updates on failure; thank you Christian!) int file_receive(int fd, unsigned long flags, struct file *file) { struct socket *sock; int ret; ret = security_file_receive(file); if (ret) return ret; /* Install the file. */ if (fd == -1) { ret = get_unused_fd_flags(flags); if (ret >= 0) fd_install(ret, get_file(file)); } else { ret = replace_fd(fd, file, flags); } /* Bump the sock usage counts. */ if (ret >= 0) { sock = sock_from_file(addfd->file, &err); if (sock) { sock_update_netprioidx(&sock->sk->sk_cgrp_data); sock_update_classid(&sock->sk->sk_cgrp_data); } } return ret; } scm_detach_fds() ... for (i=0, cmfptr=(__force int __user *)CMSG_DATA(cm); imsg_flags ? O_CLOEXEC : 0, fp[i]); if (err < 0) break; new_fd = err; err = put_user(err, cmfptr); if (err) { /* * If we can't notify userspace that it got the * fd, we need to unwind and remove it again. */ replace_fd(new_fd, NULL, 0); break; } } ... -- Kees Cook