Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp946918pxk; Mon, 31 Aug 2020 05:59:05 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxrGptkjIO4BlpSdVeSiCy91Zkl+gxiQU6k+v42NfIAGAgiK5gOZ6s2+zeROQc2REKYI0Ib X-Received: by 2002:aa7:dc0e:: with SMTP id b14mr1165373edu.158.1598878745682; Mon, 31 Aug 2020 05:59:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598878745; cv=none; d=google.com; s=arc-20160816; b=OnzQb4XS5hqjn81Kgnj93whKM7rqCR1odO/TZUNVqGvMlfIffoz+1uPC226FwGlF+I 3TxXYkh51ffctF3UbG7H6nRjNLXh0ZtrwMExnRU38LCFY3S9uxzoazylrsW1kml/V1bd A+FF5JWiwIBG9cSVa/STqA9VsaVK8IPySlKuwSvJKnwa6S0d2CRMKrDP/4ekP5o75RLn b1LVthmk1KK5Sr23y4s/R8FfNz2lYGfqDP5blcXG9fcgY7/7CAXmxE5ULayuaBWDU8zV djboEkjfCMX0JM7nnlJscB2bf4VYHDf3O4+wjqAJKDYyhUXOtCw0wr+7CB0/rktQr2OC eG4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=OxlUi6u7RvI/lLHyWwWGbfBxsLdJDDAmBdnAn1iuBHw=; b=aEbxPKqea9PqA/08mXh4/eThppcuk9CJAoVlx9MpHw8u4a1TdVIsLaw4BsXjbOUFoQ 5plAHD9Ek+KSdxRm1rCm+6F+TMfWfJkD9qMo5Rl59NV1IFLqPuduahRbPO8ngJJmCJ1/ LTlCvhzmZjvOd4z+LRiYoJdHYEuildFgs/1toWKcFtlTwfxG6eE5OYCkgseqFDXRlG/O mJJX0HMv05v3IRfoNlEhfPqh1WwM1fZYwXV4lGrzDA0h9G4fyf5T3Z3x+meGl7ZG8jdh 5+tZV0Ras9xD3p1kiCMavvub+Le34JaFN9q8TuRRwPrwoaoiY3HFZRQnlZGU2wWBhByP mIYQ== 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 z70si5205362ede.247.2020.08.31.05.58.37; Mon, 31 Aug 2020 05:59: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 S1727786AbgHaM5P (ORCPT + 99 others); Mon, 31 Aug 2020 08:57:15 -0400 Received: from brightrain.aerifal.cx ([216.12.86.13]:48460 "EHLO brightrain.aerifal.cx" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726489AbgHaM5J (ORCPT ); Mon, 31 Aug 2020 08:57:09 -0400 Date: Mon, 31 Aug 2020 08:57:07 -0400 From: Rich Felker To: Jann Horn Cc: linux-fsdevel , kernel list , Linux API , Alexander Viro Subject: Re: [RESEND PATCH] vfs: add RWF_NOAPPEND flag for pwritev2 Message-ID: <20200831125707.GM3265@brightrain.aerifal.cx> References: <20200829020002.GC3265@brightrain.aerifal.cx> <20200830163657.GD3265@brightrain.aerifal.cx> <20200830184334.GE3265@brightrain.aerifal.cx> <20200830200029.GF3265@brightrain.aerifal.cx> <20200831014633.GJ3265@brightrain.aerifal.cx> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Aug 31, 2020 at 11:15:57AM +0200, Jann Horn wrote: > On Mon, Aug 31, 2020 at 3:46 AM Rich Felker wrote: > > On Mon, Aug 31, 2020 at 03:15:04AM +0200, Jann Horn wrote: > > > On Sun, Aug 30, 2020 at 10:00 PM Rich Felker wrote: > > > > On Sun, Aug 30, 2020 at 09:02:31PM +0200, Jann Horn wrote: > > > > > On Sun, Aug 30, 2020 at 8:43 PM Rich Felker wrote: > > > > > > On Sun, Aug 30, 2020 at 08:31:36PM +0200, Jann Horn wrote: > > > > > > > On Sun, Aug 30, 2020 at 6:36 PM Rich Felker wrote: > > > > > > > > So just checking IS_APPEND in the code paths used by > > > > > > > > pwritev2 (and erroring out rather than silently writing output at the > > > > > > > > wrong place) should suffice to preserve all existing security > > > > > > > > invariants. > > > > > > > > > > > > > > Makes sense. > > > > > > > > > > > > There are 3 places where kiocb_set_rw_flags is called with flags that > > > > > > seem to be controlled by userspace: aio.c, io_uring.c, and > > > > > > read_write.c. Presumably each needs to EPERM out on RWF_NOAPPEND if > > > > > > the underlying inode is S_APPEND. To avoid repeating the same logic in > > > > > > an error-prone way, should kiocb_set_rw_flags's signature be updated > > > > > > to take the filp so that it can obtain the inode and check IS_APPEND > > > > > > before accepting RWF_NOAPPEND? It's inline so this should avoid > > > > > > actually loading anything except in the codepath where > > > > > > flags&RWF_NOAPPEND is nonzero. > > > > > > > > > > You can get the file pointer from ki->ki_filp. See the RWF_NOWAIT > > > > > branch of kiocb_set_rw_flags(). > > > > > > > > Thanks. I should have looked for that. OK, so a fixup like this on top > > > > of the existing patch? > > > > > > > > diff --git a/include/linux/fs.h b/include/linux/fs.h > > > > index 473289bff4c6..674131e8d139 100644 > > > > --- a/include/linux/fs.h > > > > +++ b/include/linux/fs.h > > > > @@ -3457,8 +3457,11 @@ static inline int kiocb_set_rw_flags(struct kiocb *ki, rwf_t flags) > > > > ki->ki_flags |= (IOCB_DSYNC | IOCB_SYNC); > > > > if (flags & RWF_APPEND) > > > > ki->ki_flags |= IOCB_APPEND; > > > > - if (flags & RWF_NOAPPEND) > > > > + if (flags & RWF_NOAPPEND) { > > > > + if (IS_APPEND(file_inode(ki->ki_filp))) > > > > + return -EPERM; > > > > ki->ki_flags &= ~IOCB_APPEND; > > > > + } > > > > return 0; > > > > } > > > > > > > > If this is good I'll submit a v2 as the above squashed with the > > > > original patch. > > > > > > Looks good to me. > > > > Actually it's not quite. I think it should be: > > > > if ((flags & RWF_NOAPPEND) & (ki->ki_flags & IOCB_APPEND)) { > > if (IS_APPEND(file_inode(ki->ki_filp))) > > return -EPERM; > > ki->ki_flags &= ~IOCB_APPEND; > > } > > > > i.e. don't refuse RWF_NOAPPEND on a file that was already successfully > > opened without O_APPEND that only subsequently got chattr +a. The > > permission check should only be done if it's overriding the default > > action for how the file is open. > > > > This is actually related to the fcntl corner case mentioned before. > > > > Are you ok with this change? If so I'll go ahead and prepare a v2. > > Ah, yeah, I guess that makes sense to keep things more consistent. > > (You'll have to write that as "(flags & RWF_NOAPPEND) && (ki->ki_flags > & IOCB_APPEND)" though (logical AND, not bitwise AND).) Thanks, no idea how I made that mistake -- probably typing code in email. While reparing this I rebased against Linus's tree, and found conflicts with 1752f0adea98ef85 which were easy to resolve. Unfortunately the same improvement made in that commit does not work for the new RWF_NOAPPEND, since it needs to inspect and mask bits off the original ki_flags, not the local set of added flags, but the penalty should be isolated to this branch. I'm not opposed to adding unlikely() around it if you think that would help codegen for the common cases. Alternatively, kiocb_flags could be initialized to ki->ki_flags, with assignment-back in place of |= at the end of the function. This might be more elegant but I'm not sure if the emitted code would improve. Rich