Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp821183pxb; Tue, 3 Nov 2020 13:30:13 -0800 (PST) X-Google-Smtp-Source: ABdhPJxcUx6iEwfBhdlw3G+3AbHEKo2h2ZxHiJhQ3g8INB8RW4r4SqXt67uHq7Ij85C+366I8m7L X-Received: by 2002:a50:f98c:: with SMTP id q12mr22935480edn.277.1604439013512; Tue, 03 Nov 2020 13:30:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604439013; cv=none; d=google.com; s=arc-20160816; b=QgDblGSfleW2JBPIFk6pfDKTMidFKs/+0dmyPnWD4UuMfvMS8wcUvDPiMwUCEwKidm jlJ+d0NHpNmLfbzmpimW03Gnx9oDan1kwsOQB8AUKdVme8AQq4xPYV0QixUQwVgHYtOj 87TpTD7HCe7ePmQuMnCYUb/IrkEH+MJGdDUMB8zcpnXGYIkm/iaQ96jbSCYEZzVZ+4oD jVo7nD03SuUEfzVEFjj6p/iXIGSFH+aa2VhDm0RUOzJUQRAzTcOk2Llzw7XBNdSbcSNi jQyPxTneb2AKozHrNXf/3nYAGBieu2vxynkbRdwe1wFKRdwN/mGplJCQrdtM+xX88zrX M2rg== 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=a4mK/9G+FaRB3LS7HW7NL6t/H7pyBzsdrl7u1t68BbM=; b=lBs7KyZBlO0UA/fII6IhYXYaKxhBIDaCD/LFxDQwID7FAMC77JsL2ymo0+Gr4c9Xgx hTfXXQKew4AcpX3BtUfy6tI6xyFBqBm9qlTfQX5+jMBIcwlXJwZK3hnwNOZB5HKZZ9xY Li40qWgdLl5WgtDzkGP+zs8VoJFHEuB4j26xkaFblpWmP19WykrnE8jRAyfLqGZOE53M 5/gcH3LIKW9/qQ1k3SohPNihtO15i+fe5aTm/xArmN1TzockhXj5NfaFsW8jSL9lz9/V F6iltgED3c3dFThAm9kuafpFONLfA6p9wcKDoL6LLR9Yzpq9avNFXxOfZnnE+3t/IQ83 2OoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=13Q3gmUM; 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=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g9si15085120edn.361.2020.11.03.13.29.50; Tue, 03 Nov 2020 13:30:13 -0800 (PST) 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=@kernel.org header.s=default header.b=13Q3gmUM; 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=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730853AbgKCVBu (ORCPT + 99 others); Tue, 3 Nov 2020 16:01:50 -0500 Received: from mail.kernel.org ([198.145.29.99]:38516 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733134AbgKCVBq (ORCPT ); Tue, 3 Nov 2020 16:01:46 -0500 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 026ED22456; Tue, 3 Nov 2020 21:01:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1604437305; bh=5C3lABk1US5/ojJTyTXhtD5XBoq+Zbzei8yotia0AyY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=13Q3gmUMs6ZVM/n1MR+eKhleowFP3SqzkaBCdxUum8Zmwvmb/jExVktO4DWnKeULz q0i1XjcmEwxmhF2Udm1UcgMNQGVdJ5oFnWe0fw6VSXQqspqw4itzlPD5BxvncYWx+v +uGO/QCfSoskUUf7FusBC03vf8B8kcKiFP33hj9I= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Pradeep P V K , Miklos Szeredi Subject: [PATCH 4.19 020/191] fuse: fix page dereference after free Date: Tue, 3 Nov 2020 21:35:12 +0100 Message-Id: <20201103203235.293300598@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201103203232.656475008@linuxfoundation.org> References: <20201103203232.656475008@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Miklos Szeredi commit d78092e4937de9ce55edcb4ee4c5e3c707be0190 upstream. After unlock_request() pages from the ap->pages[] array may be put (e.g. by aborting the connection) and the pages can be freed. Prevent use after free by grabbing a reference to the page before calling unlock_request(). The original patch was created by Pradeep P V K. Reported-by: Pradeep P V K Cc: Signed-off-by: Miklos Szeredi Signed-off-by: Greg Kroah-Hartman --- fs/fuse/dev.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -853,15 +853,16 @@ static int fuse_try_move_page(struct fus struct page *newpage; struct pipe_buffer *buf = cs->pipebufs; + get_page(oldpage); err = unlock_request(cs->req); if (err) - return err; + goto out_put_old; fuse_copy_finish(cs); err = pipe_buf_confirm(cs->pipe, buf); if (err) - return err; + goto out_put_old; BUG_ON(!cs->nr_segs); cs->currbuf = buf; @@ -901,7 +902,7 @@ static int fuse_try_move_page(struct fus err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL); if (err) { unlock_page(newpage); - return err; + goto out_put_old; } get_page(newpage); @@ -920,14 +921,19 @@ static int fuse_try_move_page(struct fus if (err) { unlock_page(newpage); put_page(newpage); - return err; + goto out_put_old; } unlock_page(oldpage); + /* Drop ref for ap->pages[] array */ put_page(oldpage); cs->len = 0; - return 0; + err = 0; +out_put_old: + /* Drop ref obtained in this function */ + put_page(oldpage); + return err; out_fallback_unlock: unlock_page(newpage); @@ -936,10 +942,10 @@ out_fallback: cs->offset = buf->offset; err = lock_request(cs->req); - if (err) - return err; + if (!err) + err = 1; - return 1; + goto out_put_old; } static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page, @@ -951,14 +957,16 @@ static int fuse_ref_page(struct fuse_cop if (cs->nr_segs == cs->pipe->buffers) return -EIO; + get_page(page); err = unlock_request(cs->req); - if (err) + if (err) { + put_page(page); return err; + } fuse_copy_finish(cs); buf = cs->pipebufs; - get_page(page); buf->page = page; buf->offset = offset; buf->len = count;