Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp324695pxp; Wed, 16 Mar 2022 06:36:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyBe491GpqmJ3obuQmFgzEDGQvkDsuKQrAgdSpedeKw5Kh4QuJHbWlkSwbwX3IqJ4Zav896 X-Received: by 2002:a63:513:0:b0:380:1180:9b48 with SMTP id 19-20020a630513000000b0038011809b48mr28863680pgf.623.1647437804315; Wed, 16 Mar 2022 06:36:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1647437804; cv=none; d=google.com; s=arc-20160816; b=dUS1J0gvvMx7fMAg418/gxut+ZtAfU9FENhTKYNEFhMnF6v6aokvESu/Tbs+bm48kh TY4wgE3otwZ6ETMmiEooH/kAqg+1uHpaT9p0AjQDg+dgBFpbs1o4tOdPYpiBSkaZ6plp PW+NNJOchtig7We36AFzgn81nqy/4vaSk3vHdlX0fvUltas5325Ojx5rGDy8lGENDRIa dqDVdwE5msW0+E0e+Ebl9o+pJdDyQrq2ploewcsfjPZBHWBlR4+k994Gdu7RB/2MTbkF y5IxUy0dSpiwthl6f2I+SFkQlsoYOv1Fh2Yqy1+KU/bBr7BiwZb+qt5Ytwv0ZVWgy1No ikUQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=G3C/S2RJDnbVwZ8pjj8C8eXKoBl64WeGhkpntvigP4E=; b=H7hPose+guneILTxgmIoZusuy2mrclvQHKY9rMIPfxshHlNnKOJHpHH/8paJdq2l0g Hr3DSfBFyfIWRN6w9CbP52a6yMEMBS+x9v5nziq+dbaWdJLfPUaRe5IxcHXkLIS4nB3l 2nRR5Ht0TNHD6e9zL3BephJmXLwQdQ19QEqxESJuH1/VymvLuuya27Dqq3lgPLjSZ3P+ n29gBQMB16h2TB5NK8D2ZxggCv2bpbPGvMgCwPOY6rkqRMpmDcFjH/kmF0nrtpevlzOW 0cG8/Ex5hfiknKaO8Ehx45e8kVGLd835hdIaWMaAJQM/zvdk5zANeyRxDwfQUZ7mLZYa TZeg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Gefu7wV3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u14-20020a056a00124e00b004f775259f2csi2001415pfi.215.2022.03.16.06.36.25; Wed, 16 Mar 2022 06:36:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Gefu7wV3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242148AbiCNM3F (ORCPT + 99 others); Mon, 14 Mar 2022 08:29:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49698 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243768AbiCNMVN (ORCPT ); Mon, 14 Mar 2022 08:21:13 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5375C36E08; Mon, 14 Mar 2022 05:16:54 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id D8A4D608C4; Mon, 14 Mar 2022 12:16:53 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6DD1AC340E9; Mon, 14 Mar 2022 12:16:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1647260213; bh=IpUKCrZjShlWu1MKEVWzyPKyAG6itG7kGVkhIIIIOPA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Gefu7wV3/B9Cuy6FlGUV/AW2RM0hr6BxgPBrZlVLDfpHU05MA0+JzhLQyKMsqFwIi B0WDcH3ssxzM9LUXaAQ9OaXde8scTHfjeNLp1+5i4CkcHlMIewiE/03b17ST/yORAU WeD74D/UuPDOo+N7m1Y4SNfAXF6vjlB1q3lm5ugc= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jann Horn , Miklos Szeredi Subject: [PATCH 5.16 088/121] fuse: fix pipe buffer lifetime for direct_io Date: Mon, 14 Mar 2022 12:54:31 +0100 Message-Id: <20220314112746.575190006@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220314112744.120491875@linuxfoundation.org> References: <20220314112744.120491875@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-8.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Miklos Szeredi commit 0c4bcfdecb1ac0967619ee7ff44871d93c08c909 upstream. In FOPEN_DIRECT_IO mode, fuse_file_write_iter() calls fuse_direct_write_iter(), which normally calls fuse_direct_io(), which then imports the write buffer with fuse_get_user_pages(), which uses iov_iter_get_pages() to grab references to userspace pages instead of actually copying memory. On the filesystem device side, these pages can then either be read to userspace (via fuse_dev_read()), or splice()d over into a pipe using fuse_dev_splice_read() as pipe buffers with &nosteal_pipe_buf_ops. This is wrong because after fuse_dev_do_read() unlocks the FUSE request, the userspace filesystem can mark the request as completed, causing write() to return. At that point, the userspace filesystem should no longer have access to the pipe buffer. Fix by copying pages coming from the user address space to new pipe buffers. Reported-by: Jann Horn Fixes: c3021629a0d8 ("fuse: support splice() reading from fuse device") Cc: Signed-off-by: Miklos Szeredi Signed-off-by: Greg Kroah-Hartman --- fs/fuse/dev.c | 12 +++++++++++- fs/fuse/file.c | 1 + fs/fuse/fuse_i.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -941,7 +941,17 @@ static int fuse_copy_page(struct fuse_co while (count) { if (cs->write && cs->pipebufs && page) { - return fuse_ref_page(cs, page, offset, count); + /* + * Can't control lifetime of pipe buffers, so always + * copy user pages. + */ + if (cs->req->args->user_pages) { + err = fuse_copy_fill(cs); + if (err) + return err; + } else { + return fuse_ref_page(cs, page, offset, count); + } } else if (!cs->len) { if (cs->move_pages && page && offset == 0 && count == PAGE_SIZE) { --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1413,6 +1413,7 @@ static int fuse_get_user_pages(struct fu (PAGE_SIZE - ret) & (PAGE_SIZE - 1); } + ap->args.user_pages = true; if (write) ap->args.in_pages = true; else --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -256,6 +256,7 @@ struct fuse_args { bool nocreds:1; bool in_pages:1; bool out_pages:1; + bool user_pages:1; bool out_argvar:1; bool page_zeroing:1; bool page_replace:1;