From patchwork Tue Oct 10 14:29:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Wang Zhaolong X-Patchwork-Id: 1845942 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=XU4Y1KrW; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4S4dVx2GTpz1yq7 for ; Wed, 11 Oct 2023 01:26:16 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:CC :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=K+4Ki0uS5eRuwb6Z8TmvbWmFdZxcqRPzk75wzINnBjk=; b=XU4Y1KrW/NaRgp 9B2NPeQa8PcfC5dmMGdWZz4F2gpcZOj1oNiG+oT7pFIo+tezX5k9pAODiPwOr1/OK4OhciUNAeFr4 t3UpKVQEHyzuBwEcfcMZCAwkrFqwXEA44RDtn5XvfkWJhVNxA/1lOBR00dDjC3ObBgFpsflFmEpey lGoUD0ibubEFCyoF5j43knauQVzBRbHFnT+14JAmKK9rVDy6OqZsd8KMfwP8lTVLCOLhPDoJqNjT7 o9r1hclgxMBFj/NX494hsPnFo1liln3Ois0oCIWaNShYBH5EnKrVQ79qP6go+6Hc6SQY4TfnHDCvG Au4xDybHXZ6pmkuCMgCw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qqDfg-00DYdH-2N; Tue, 10 Oct 2023 14:25:16 +0000 Received: from szxga01-in.huawei.com ([45.249.212.187]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qqDfR-00DYc4-36 for linux-mtd@lists.infradead.org; Tue, 10 Oct 2023 14:25:04 +0000 Received: from dggpemm500009.china.huawei.com (unknown [172.30.72.54]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4S4dMW62kfztTGK; Tue, 10 Oct 2023 22:19:51 +0800 (CST) Received: from huawei.com (10.175.127.227) by dggpemm500009.china.huawei.com (7.185.36.225) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Tue, 10 Oct 2023 22:24:27 +0800 From: ZhaoLong Wang To: , , CC: , , , , , Subject: [PATCH RFC] ubi: gluebi: Fix NULL pointer dereference caused by ftl notifier Date: Tue, 10 Oct 2023 22:29:25 +0800 Message-ID: <20231010142925.545238-1-wangzhaolong1@huawei.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-Originating-IP: [10.175.127.227] X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To dggpemm500009.china.huawei.com (7.185.36.225) X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231010_072502_181749_D46332DD X-CRM114-Status: GOOD ( 11.92 ) X-Spam-Score: -2.3 (--) X-Spam-Report: =?unknown-8bit?q?Spam_detection_software=2C_running_on_the_sy?= =?unknown-8bit?q?stem_=22bombadil=2Einfradead=2Eorg=22=2C?= =?unknown-8bit?q?_has_NOT_identified_this_incoming_email_as_spam=2E__The_ori?= =?unknown-8bit?q?ginal?= =?unknown-8bit?q?_message_has_been_attached_to_this_so_you_can_view_it_or_la?= =?unknown-8bit?q?bel?= =?unknown-8bit?q?_similar_future_email=2E__If_you_have_any_questions=2C_see?= =?unknown-8bit?q?_the_administrator_of_that_system_for_details=2E?= =?unknown-8bit?q?_?= =?unknown-8bit?q?_Content_preview=3A__If_both_flt=2Eko_and_gluebi=2Eko_are_l?= =?unknown-8bit?q?oaded=2C_the_notiier_of_ftl?= =?unknown-8bit?q?_triggers_NULL_pointer_dereference_when_trying_to_visit_=E2?= =?unknown-8bit?q?=80=98gluebi-=3Edesc=E2=80=99?= =?unknown-8bit?q?_in_gluebi=5Fread=28=29=2E_ubi=5Fgluebi=5Finit_ubi=5Fregist?= =?unknown-8bit?q?er=5Fvolume=5Fnotifier_ubi=5Fenumerate=5Fvolumes?= =?unknown-8bit?q?_ubi=5Fnotify=5Fall_gluebi=5Fnotify_nb-=3Enotifier=5Fcall?= =?unknown-8bit?q?=28=29_gluebi=5Fcreate_mtd=5Fdevice=5Fregister?= =?unknown-8bit?q?_mtd=5Fdevice=5Fparse=5Fregister_add=5Fmtd=5Fdevice_blktran?= =?unknown-8bit?q?s=5F_=5B=2E=2E=2E=5D_?= =?unknown-8bit?q?_?= =?unknown-8bit?q?_Content_analysis_details=3A___=28-2=2E3_points=2C_5=2E0_re?= =?unknown-8bit?q?quired=29?= =?unknown-8bit?q?_?= =?unknown-8bit?q?_pts_rule_name______________description?= =?unknown-8bit?q?_----_----------------------_------------------------------?= =?unknown-8bit?q?--------------------?= =?unknown-8bit?q?_-2=2E3_RCVD=5FIN=5FDNSWL=5FMED______RBL=3A_Sender_listed_a?= =?unknown-8bit?q?t_https=3A//www=2Ednswl=2Eorg/=2C?= =?unknown-8bit?q?_medium_trust?= =?unknown-8bit?q?_=5B45=2E249=2E212=2E187_listed_in_list=2Ednswl=2Eorg=5D?= =?unknown-8bit?q?_-0=2E0_SPF=5FPASS_______________SPF=3A_sender_matches_SPF_?= =?unknown-8bit?q?record?= =?unknown-8bit?q?_0=2E0_SPF=5FHELO=5FNONE__________SPF=3A_HELO_does_not_publ?= =?unknown-8bit?q?ish_an_SPF_Record?= =?unknown-8bit?q?_0=2E0_RCVD=5FIN=5FMSPIKE=5FH5______RBL=3A_Excellent_reputa?= =?unknown-8bit?q?tion_=28+5=29?= =?unknown-8bit?q?_=5B45=2E249=2E212=2E187_listed_in_wl=2Emailspike=2Enet=5D?= =?unknown-8bit?q?_0=2E0_RCVD=5FIN=5FMSPIKE=5FWL______Mailspike_good_senders?= X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org If both flt.ko and gluebi.ko are loaded, the notiier of ftl triggers NULL pointer dereference when trying to visit ‘gluebi->desc’ in gluebi_read(). ubi_gluebi_init ubi_register_volume_notifier ubi_enumerate_volumes ubi_notify_all gluebi_notify nb->notifier_call() gluebi_create mtd_device_register mtd_device_parse_register add_mtd_device blktrans_notify_add not->add() ftl_add_mtd tr->add_mtd() scan_header mtd_read mtd_read mtd_read_oob gluebi_read mtd->read() gluebi->desc - NULL Detailed reproduction information available at the link[1], In the normal case, obtain gluebi->desc in the gluebi_get_device(), and accesses gluebi->desc in the gluebi_read(). However, gluebi_get_device() is not executed in advance in the ftl_add_mtd() process, which leads to null pointer dereference. This patch assumes that the gluebi module is not designed to work with the ftl module. In this case, the patch only needs to prevent the ftl notifier operation. Add some correctness check for gluebi->desc in gluebi_read/write/erase(), If the pointer is invalid, the -EINVAL is returned. Link: https://bugzilla.kernel.org/show_bug.cgi?id=217992 [1] Signed-off-by: ZhaoLong Wang --- drivers/mtd/ubi/gluebi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 1b980d15d9fb..189ecc0eacd1 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -157,6 +157,9 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, struct gluebi_device *gluebi; gluebi = container_of(mtd, struct gluebi_device, mtd); + if (IS_ERR_OR_NULL(gluebi->desc)) + return -EINVAL; + lnum = div_u64_rem(from, mtd->erasesize, &offs); bytes_left = len; while (bytes_left) { @@ -197,6 +200,9 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, struct gluebi_device *gluebi; gluebi = container_of(mtd, struct gluebi_device, mtd); + if (IS_ERR_OR_NULL(gluebi->desc)) + return -EINVAL; + lnum = div_u64_rem(to, mtd->erasesize, &offs); if (len % mtd->writesize || offs % mtd->writesize) @@ -242,6 +248,8 @@ static int gluebi_erase(struct mtd_info *mtd, struct erase_info *instr) lnum = mtd_div_by_eb(instr->addr, mtd); count = mtd_div_by_eb(instr->len, mtd); gluebi = container_of(mtd, struct gluebi_device, mtd); + if (IS_ERR_OR_NULL(gluebi->desc)) + return -EINVAL; for (i = 0; i < count - 1; i++) { err = ubi_leb_unmap(gluebi->desc, lnum + i);