Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp643528ybz; Wed, 22 Apr 2020 05:22:08 -0700 (PDT) X-Google-Smtp-Source: APiQypLlRTVD9gwvwSbpITjs7ije+C1q7HDcdbKlyyyRXtvkNgQe2+r6rGKDweUSvXUfwaPEjscM X-Received: by 2002:a17:906:d291:: with SMTP id ay17mr26139180ejb.183.1587558128538; Wed, 22 Apr 2020 05:22:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587558128; cv=none; d=google.com; s=arc-20160816; b=RjUsnCCCXaSG/eobs6o9dMa2zDS85oYYiizQU28YmtQUgEQ6w0T2wTb6o7y1mLJj0e PWsg+SLjxPzTfzww06gi30+23aLc08kWYaKoMvlV0IoGE3T0m0W9dtUMbRjqCRtZVmPN BtR0zzKbAHfpcvX5Z9nFC/5b6r7Gu1iKJ+KJNnuKdahDfl//fsGkGRFGtuPUrQnowoUL ndg/unRH6lhRsqzR0ScGzLKDSBhmCWGjEyhbjzlwBqo+PBGN/rjw0BRs1RL1aiTdxVyE VaZh7PPnjk1GlHajvVCgBSI3J/GjnyIyE4+lAY9EIOZTGkOHYntqRvweGn/9irVMbi1B hG5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=vcGupc0w1OpR0UgbjI2UXdhR7i6mDTANJQQoOiMRVQk=; b=RQtXSkS4/w9jwgq7IUQIkvFRYEfNrZg58B7fCstZxkEnxZGl7/OeAgqwJ7rmU5AseF /kjv8/Cp++AMp7Nvj6CMJfFlf13WBMnTnThpgxaQb3eNhAsRj5U5spOWZ+akN2i5nExw K92iQJ9LKCy3F4brJMPLW6EoO3/B5tgS5mQIDCC5uQgvsAEIisgPiFt0vV7Dkp324Phe /YMAUZn6xtHUmch+l0oshcVozKGwCRYXnGONJuPPTda19eSkvoDbl9qNI1AECIawNrt4 siIqq/lTYpSCXL6xkUMShdUXIMDXUIRsRgYiLS3I3G2QjomWytBZvv+ivr8dAEKGFCvY t40A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=RRas+j1x; 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 i3si2420778edy.312.2020.04.22.05.21.45; Wed, 22 Apr 2020 05:22:08 -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=@kernel.org header.s=default header.b=RRas+j1x; 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 S1730450AbgDVK1f (ORCPT + 99 others); Wed, 22 Apr 2020 06:27:35 -0400 Received: from mail.kernel.org ([198.145.29.99]:36510 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730431AbgDVK11 (ORCPT ); Wed, 22 Apr 2020 06:27:27 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (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 5704720784; Wed, 22 Apr 2020 10:27:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1587551246; bh=YLXBwgw3/Lm1c+qH8DOQy+FDCzjJEKmau8CPH+MDC5E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RRas+j1xWW9Z0ESdMm2hnems7LBQ9WGzyFg09Hjr9oZArzVJtiet0Kv1U4VE6xMvB O6IBXbojVjFP0pPs2rkkMi4DicKsdAXPPw6T3mY7/DRI2Sqwf03CTxu8amEqrkWg6O 0826RJ1JQtnlHBxgtVRnBirTleWfbbYytvrezClo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Chao Yu , Jaegeuk Kim , Sasha Levin Subject: [PATCH 5.6 118/166] f2fs: fix NULL pointer dereference in f2fs_verity_work() Date: Wed, 22 Apr 2020 11:57:25 +0200 Message-Id: <20200422095101.310801277@linuxfoundation.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200422095047.669225321@linuxfoundation.org> References: <20200422095047.669225321@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Chao Yu [ Upstream commit 79bbefb19f1359fb2cbd144d5a054649e7e583be ] If both compression and fsverity feature is on, generic/572 will report below NULL pointer dereference bug. BUG: kernel NULL pointer dereference, address: 0000000000000018 RIP: 0010:f2fs_verity_work+0x60/0x90 [f2fs] #PF: supervisor read access in kernel mode Workqueue: fsverity_read_queue f2fs_verity_work [f2fs] RIP: 0010:f2fs_verity_work+0x60/0x90 [f2fs] Call Trace: process_one_work+0x16c/0x3f0 worker_thread+0x4c/0x440 ? rescuer_thread+0x350/0x350 kthread+0xf8/0x130 ? kthread_unpark+0x70/0x70 ret_from_fork+0x35/0x40 There are two issue in f2fs_verity_work(): - it needs to traverse and verify all pages in bio. - if pages in bio belong to non-compressed cluster, accessing decompress IO context stored in page private will cause NULL pointer dereference. Fix them. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/compress.c | 2 ++ fs/f2fs/data.c | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 1a86e483b0907..eb84c13c1182c 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -476,6 +476,8 @@ void f2fs_decompress_pages(struct bio *bio, struct page *page, bool verity) out_vunmap_rbuf: vunmap(dic->rbuf); out_free_dic: + if (verity) + refcount_add(dic->nr_cpages - 1, &dic->ref); if (!verity) f2fs_decompress_end_io(dic->rpages, dic->cluster_size, ret, false); diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index b27b721079116..34990866cfe96 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -191,12 +191,37 @@ static void f2fs_verify_pages(struct page **rpages, unsigned int cluster_size) static void f2fs_verify_bio(struct bio *bio) { - struct page *page = bio_first_page_all(bio); - struct decompress_io_ctx *dic = - (struct decompress_io_ctx *)page_private(page); + struct bio_vec *bv; + struct bvec_iter_all iter_all; + + bio_for_each_segment_all(bv, bio, iter_all) { + struct page *page = bv->bv_page; + struct decompress_io_ctx *dic; + + dic = (struct decompress_io_ctx *)page_private(page); + + if (dic) { + if (refcount_dec_not_one(&dic->ref)) + continue; + f2fs_verify_pages(dic->rpages, + dic->cluster_size); + f2fs_free_dic(dic); + continue; + } + + if (bio->bi_status || PageError(page)) + goto clear_uptodate; - f2fs_verify_pages(dic->rpages, dic->cluster_size); - f2fs_free_dic(dic); + if (fsverity_verify_page(page)) { + SetPageUptodate(page); + goto unlock; + } +clear_uptodate: + ClearPageUptodate(page); + ClearPageError(page); +unlock: + unlock_page(page); + } } #endif -- 2.20.1