Message ID | 20221216031320.2634-1-alice.chao@mediatek.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e747:0:0:0:0:0 with SMTP id c7csp744693wrn; Thu, 15 Dec 2022 19:18:41 -0800 (PST) X-Google-Smtp-Source: AA0mqf410VqBFBnN8z5ANBhUAwLnslkFaZk40GkoKMci+GjTJQaHDO//6XnzZNsfeuEyc7KCqnSo X-Received: by 2002:a17:903:240d:b0:187:4920:3a76 with SMTP id e13-20020a170903240d00b0018749203a76mr33600621plo.34.1671160721094; Thu, 15 Dec 2022 19:18:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671160721; cv=none; d=google.com; s=arc-20160816; b=gzNAIDR9w2x6ypOc44Bb0Fn2OtE6Duk5B3YLOdto0js9AjyCb5o7yt6uP5vr5Ps/en HrW106vRe1lECxlGw5gcIHUi0BgHrYJoOcf41Ld6OYFCJzxi2SaClAPoT3UQqzfImw4H c2DryCkF7D5lkvPUyMEkxp09/UPNq5+Hk91lm5PvGFyWOotbuR7qxeKUo01i0aCF403K ZHT+vXNAgOXgPzaW12ksZeFPRocHeVeFmjOh5xx7FZjJVS67RzVHSAiwFRUdB1z2qKAv HTjYnsydAtLSleJVSJ0hq2Z6Bah/ETpaHkGeWklEtJRKcHAZcqe84WYmQ9EtTGCeutnf gofQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:subject:cc:to:from :dkim-signature; bh=F+2XiVV/hxebtLq5aHTxlzUZ5HkY+iv5QheRMxy1dWI=; b=uoekCzIrEA6HafqgDqzvIIeHCWFfrUHvI/+UD6rY8IbBLGvYePoKhIr4L1yEifSHMt xibc8IKcOpgqXneeXNJXKQynfO1Sj+7iubDAn4mP4tZYOaB+GfinOXPwm8A1CKuG6fye u441KQxH4ikf9XbbljKkioda4VTBC9jyVzEiIsApYRT3uQ6/18DGTlSdPEEV8SDbScTT g9jHGa9dnWlxvZN0ryHGmsPe+/ZDLTtKyI44ZbfoA8tK28GP2rl4L6X5ZaftIbUeCPw5 9APuFW1Nt0F6soOkYNVHX0tkD2mjdqOdn7V+OSIbPjwFDCK9TZChQD9tEB8uDeBCJSVk Pfqg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@mediatek.com header.s=dk header.b=aqce60Wp; 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=QUARANTINE sp=QUARANTINE dis=NONE) header.from=mediatek.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x21-20020a170902ea9500b00189d0fa14desi1005417plb.620.2022.12.15.19.18.27; Thu, 15 Dec 2022 19:18:41 -0800 (PST) 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=@mediatek.com header.s=dk header.b=aqce60Wp; 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=QUARANTINE sp=QUARANTINE dis=NONE) header.from=mediatek.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230101AbiLPDQA (ORCPT <rfc822;jeantsuru.cumc.mandola@gmail.com> + 99 others); Thu, 15 Dec 2022 22:16:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229979AbiLPDPP (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 15 Dec 2022 22:15:15 -0500 Received: from mailgw01.mediatek.com (unknown [60.244.123.138]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82C706C70C for <linux-kernel@vger.kernel.org>; Thu, 15 Dec 2022 19:14:14 -0800 (PST) X-UUID: fc73e221f67c4dc3a45f384dffe76cdf-20221216 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=F+2XiVV/hxebtLq5aHTxlzUZ5HkY+iv5QheRMxy1dWI=; b=aqce60Wp1yYtaA3hJsAn/RbepSC0FC0Pf2dopxilP2Dl5dIZ8MtLvlM/RXEohI0EzEVcsEOmu4NcnaS1yOQoLuX+LOzOyeC+4ZfwL1/de3MZkiDce5wImyn1Z9EXhEoQj12IpKnpEsyegh2Q7TrYTk2iYzzO9NTTew7OIF8LYFY=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.14,REQID:908eb929-55b0-43b1-8b0a-5e91248137da,IP:0,U RL:0,TC:0,Content:0,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION: release,TS:0 X-CID-META: VersionHash:dcaaed0,CLOUDID:4c40cbaf-9f02-4d44-9c44-6e4bb4e4f412,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:1,EDM:-3,IP:nil,U RL:0,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0 X-UUID: fc73e221f67c4dc3a45f384dffe76cdf-20221216 Received: from mtkmbs11n1.mediatek.inc [(172.21.101.185)] by mailgw01.mediatek.com (envelope-from <alice.chao@mediatek.com>) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 1576592472; Fri, 16 Dec 2022 11:14:06 +0800 Received: from mtkmbs13n2.mediatek.inc (172.21.101.108) by mtkmbs10n2.mediatek.inc (172.21.101.183) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.792.3; Fri, 16 Dec 2022 11:14:05 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.792.15 via Frontend Transport; Fri, 16 Dec 2022 11:14:05 +0800 From: Alice Chao <alice.chao@mediatek.com> To: <gregkh@linuxfoundation.org>, <rafael@kernel.org>, <matthias.bgg@gmail.com>, <linux-kernel@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org>, <linux-mediatek@lists.infradead.org> CC: <stanley.chu@mediatek.com>, <peter.wang@mediatek.com>, <chun-hung.wu@mediatek.com>, <alice.chao@mediatek.com>, <powen.kao@mediatek.com>, <naomi.chu@mediatek.com>, <cc.chou@mediatek.com>, <chaotian.jing@mediatek.com>, <jiajie.hao@mediatek.com>, <qilin.tan@mediatek.com>, <lin.gui@mediatek.com>, <yanxu.wei@mediatek.com>, <tun-yu.yu@mediatek.com>, <eddie.huang@mediatek.com>, <wsd_upstream@mediatek.com> Subject: [PATCH 1/1] scsi: Add length check to prevent invalid memory access Date: Fri, 16 Dec 2022 11:13:22 +0800 Message-ID: <20221216031320.2634-1-alice.chao@mediatek.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 Content-Type: text/plain X-MTK: N X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS, SPF_PASS,UNPARSEABLE_RELAY 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: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1752339024224657429?= X-GMAIL-MSGID: =?utf-8?q?1752339024224657429?= |
Series |
[1/1] scsi: Add length check to prevent invalid memory access
|
|
Commit Message
Alice Chao
Dec. 16, 2022, 3:13 a.m. UTC
Device reset thread uses kobject_uevent_env() to get kobj.parent(kobj.p)
, and it races with device init thread which calls device_add() to add
kobj.parent before kobject_uevent_env().
Device init call: Device reset call:
scsi_probe_and_add_lun() scsi_evt_thread()
scsi_add_lun() scsi_evt_emit()
scsi_sysfs_add_sdev() kobject_uevent_env() //get kobj.parent
scsi_target_add() kobject_get_path()
len = get_kobj_path_length ()
//len=1 because parent hasn't created yet
device_add() // add kobj.parent
kobject_uevent_env()
kobject_get_path() path = kzalloc()
fill_kobj_path() fill_kobj_path()
// --length; length -= cur is a negative value
memcpy(path + length, kobject_name(parent), cur);
// slab OOB!
Above backtrace describes the problem, device reset thread will get wrong
kobj.parent when device init thread didn't add kobj/parent yet. When this
racing happened, it triggers the a KASAN dump on the final iteration:
BUG: KASAN: slab-out-of-bounds in kobject_get_path+0xf8/0x1b8
Write of size 11 at addr ffffff80d6bb94f5 by task kworker/3:1/58
<snip>
Call trace:
__kasan_report+0x124/0x1c8
kasan_report+0x54/0x84
kasan_check_range+0x200/0x208
memcpy+0xb8/0xf0
kobject_get_path+0xf8/0x1b8
kobject_uevent_env+0x228/0xa88
scsi_evt_thread+0x2d0/0x5b0
process_one_work+0x570/0xf94
worker_thread+0x7cc/0xf80
kthread+0x2c4/0x388
These two jobs are scheduled asynchronously, we can't guaranteed that
kobj.parent will be created in device init thread before device reset
thread calls kobject_get_path().
To prevent length -= cur from being a negative value, we add length
check in fill_kobj_path() to prevent invalid memory access.
Signed-off-by: Alice Chao <alice.chao@mediatek.com>
---
lib/kobject.c | 4 ++++
1 file changed, 4 insertions(+)
Comments
On Fri, Dec 16, 2022 at 11:13:22AM +0800, Alice Chao wrote: > Device reset thread uses kobject_uevent_env() to get kobj.parent(kobj.p) > , and it races with device init thread which calls device_add() to add > kobj.parent before kobject_uevent_env(). Note, "scsi" in the subject line is wrong, this should be "kobject", right? > > Device init call: Device reset call: > scsi_probe_and_add_lun() scsi_evt_thread() Shouldn't the scsi layer be protecting these from happening at the same time? Or some other bus lock? > scsi_add_lun() scsi_evt_emit() > scsi_sysfs_add_sdev() kobject_uevent_env() //get kobj.parent > scsi_target_add() kobject_get_path() > len = get_kobj_path_length () > //len=1 because parent hasn't created yet Wait, how can the parent be gone if it has not been added yet? A parent should always be present, a device can not be there if it did not have a parent already. > device_add() // add kobj.parent > kobject_uevent_env() > kobject_get_path() path = kzalloc() > fill_kobj_path() fill_kobj_path() > // --length; length -= cur is a negative value > memcpy(path + length, kobject_name(parent), cur); > // slab OOB! > > Above backtrace describes the problem, device reset thread will get wrong > kobj.parent when device init thread didn't add kobj/parent yet. When this > racing happened, it triggers the a KASAN dump on the final iteration: > > BUG: KASAN: slab-out-of-bounds in kobject_get_path+0xf8/0x1b8 > Write of size 11 at addr ffffff80d6bb94f5 by task kworker/3:1/58 > <snip> > > Call trace: > __kasan_report+0x124/0x1c8 > kasan_report+0x54/0x84 > kasan_check_range+0x200/0x208 > memcpy+0xb8/0xf0 > kobject_get_path+0xf8/0x1b8 > kobject_uevent_env+0x228/0xa88 > scsi_evt_thread+0x2d0/0x5b0 > process_one_work+0x570/0xf94 > worker_thread+0x7cc/0xf80 > kthread+0x2c4/0x388 > > These two jobs are scheduled asynchronously, we can't guaranteed that > kobj.parent will be created in device init thread before device reset > thread calls kobject_get_path(). Again, a parent should always be there, how is that happening? > To prevent length -= cur from being a negative value, we add length > check in fill_kobj_path() to prevent invalid memory access. > > Signed-off-by: Alice Chao <alice.chao@mediatek.com> > --- > lib/kobject.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/lib/kobject.c b/lib/kobject.c > index af1f5f2954d4..3cccb8e88d4e 100644 > --- a/lib/kobject.c > +++ b/lib/kobject.c > @@ -121,6 +121,10 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length) > int cur = strlen(kobject_name(parent)); > /* back up enough to print this name with '/' */ > length -= cur; > + > + if (length <= 0) > + break; Shouldn't you just check for cur == 0 here instead? But again, how can we have a parent with no name? thanks, greg k-h
diff --git a/lib/kobject.c b/lib/kobject.c index af1f5f2954d4..3cccb8e88d4e 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -121,6 +121,10 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length) int cur = strlen(kobject_name(parent)); /* back up enough to print this name with '/' */ length -= cur; + + if (length <= 0) + break; + memcpy(path + length, kobject_name(parent), cur); *(path + --length) = '/'; }