From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-co1nam03on0096.outbound.protection.outlook.com ([104.47.40.96]:44736 "EHLO NAM03-CO1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727824AbeH3WMW (ORCPT ); Thu, 30 Aug 2018 18:12:22 -0400 From: Sasha Levin To: "stable@vger.kernel.org" CC: Qu Wenruo , David Sterba , Sasha Levin Subject: [PATCH AUTOSEL 4.18 110/113] btrfs: check-integrity: Fix NULL pointer dereference for degraded mount Date: Thu, 30 Aug 2018 18:08:39 +0000 Message-ID: <20180830180714.36167-44-alexander.levin@microsoft.com> References: <20180830180714.36167-1-alexander.levin@microsoft.com> In-Reply-To: <20180830180714.36167-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Qu Wenruo [ Upstream commit 9912bbf6440ba0555e91d3306520da01872c7c1d ] Commit f8f84b2dfda5 ("btrfs: index check-integrity state hash by a dev_t") changed how btrfsic indexes device state. Now we need to access device->bdev->bd_dev, while for degraded mount it's completely possible to have device->bdev as NULL, thus it will trigger a NULL pointer dereference at mount time. Fix it by checking if the device is degraded before accessing device->bdev->bd_dev. There are a lot of other places accessing device->bdev->bd_dev, however the other call sites have either checked device->bdev, or the device->bdev is passed from btrfsic_map_block(), so it won't cause harm. Fixes: f8f84b2dfda5 ("btrfs: index check-integrity state hash by a dev_t") Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/check-integrity.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index a3fdb4fe967d..daf45472bef9 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -1539,7 +1539,12 @@ static int btrfsic_map_block(struct btrfsic_state *s= tate, u64 bytenr, u32 len, } =20 device =3D multi->stripes[0].dev; - block_ctx_out->dev =3D btrfsic_dev_state_lookup(device->bdev->bd_dev); + if (test_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state) || + !device->bdev || !device->name) + block_ctx_out->dev =3D NULL; + else + block_ctx_out->dev =3D btrfsic_dev_state_lookup( + device->bdev->bd_dev); block_ctx_out->dev_bytenr =3D multi->stripes[0].physical; block_ctx_out->start =3D bytenr; block_ctx_out->len =3D len; --=20 2.17.1