Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp4346960pxp; Tue, 15 Mar 2022 19:06:28 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxoL7aiA2GuIFQwWVX/0BQWCtYnljQePXWzucBEHwSG1ZH4oD1Qtk7bPX45wgD0BIVVcJZX X-Received: by 2002:a05:6402:2c6:b0:415:b06c:de71 with SMTP id b6-20020a05640202c600b00415b06cde71mr28095626edx.50.1647396388245; Tue, 15 Mar 2022 19:06:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1647396388; cv=none; d=google.com; s=arc-20160816; b=HJK/B7eQNFCz0S7wCS/URXb2rmbwEhX2hayw3XgGFAxc3M6nVaz/8Es6ePLKstgn+m QSy1hTbs12202Rx9mdapGLiF5Ct+O81VKp29adsjRW5xi3ida+9VCN4E0dTg6XRId1XN R/dWj36kcOXey7MYH9HxZkPw1NyG8I+b8qG2p1F9SjC6Bk8L1V5CcSWXljM+kSf9Xhi4 hCytqD+aCpcoH5fXV9c0L2g7JBtzezPw/AHzTgjBn+uNUkriK7aIL1MW8fYuP7rYxeV1 Aqfrox0KQcZ0FnUvJLSgXwqB2DfPD5GJ3wCPBzArlHaahNQyRoP43ViPimTHJJhJmFNX yH0g== 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=yS2Irw3dijwi9CUpZC4KX686UNumVrfxzrqqYKjC7DE=; b=KtWfPF192rrLSha/6Yb/uFKDP8k3NxKkfunqiG/EO21gVl6x0Z+iE+0MS8jSR3ggcY nP0PEkd1nWWScnyhe+GPRGUDK/CDK2XldL4gCp/wYPTHy4zOMcV5s48+FYwBtNCgPJqy 0jd33q+6Oik1dYHfvzqv+P8+0A+FR4cPjS9bCb37mkov1Mi46/CESQ1orEbTT0MHb0i+ Bou50lDayRswNrxDU8TJLM3vTHhTij9YSRgjiUGKK3ca4KTSTybZD8yk2cjHf7MGI0U0 c/aXY1mH6GTdAnCGcw2NO4gcw8XhUE4nXmQmepAGu2R40QvX2cthsviAYY2PHwSS+Hy+ OaGw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=JOfeJKqd; 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 ka4-20020a170907990400b006cd93b40f4bsi366692ejc.627.2022.03.15.19.05.28; Tue, 15 Mar 2022 19:06:28 -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=JOfeJKqd; 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 S241214AbiCNMXr (ORCPT + 99 others); Mon, 14 Mar 2022 08:23:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241201AbiCNMQN (ORCPT ); Mon, 14 Mar 2022 08:16:13 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B56CD34640; Mon, 14 Mar 2022 05:11:57 -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 5590F61314; Mon, 14 Mar 2022 12:11:57 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5123CC340E9; Mon, 14 Mar 2022 12:11:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1647259916; bh=mo801uHHEfDLZc/7aHW6NVL1hnApRqaiyqkRPNxVjVI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JOfeJKqdXCbzvTMPFIzVxGWBzK89507EoR/9riHfBRA9/4F5mBEIXDn1lepcpNzJy 9+PSO1aXu/X+zrqr42MLs1z5/uD/rh5/4wPs/HEogE7+fwVHCwvQ7OBbW6cKYIjF75 D6TX9aqppVhF5xXN0LCPkSopZTL6zSlQ/oyRJiFg= 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.15 076/110] fuse: fix pipe buffer lifetime for direct_io Date: Mon, 14 Mar 2022 12:54:18 +0100 Message-Id: <20220314112745.155205350@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220314112743.029192918@linuxfoundation.org> References: <20220314112743.029192918@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 @@ -1417,6 +1417,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;