Received: by 2002:a05:6358:f14:b0:e5:3b68:ec04 with SMTP id b20csp2709006rwj; Mon, 19 Dec 2022 07:58:24 -0800 (PST) X-Google-Smtp-Source: AA0mqf5iyvP4YZy1xG711+V/drqNfstAuiYKIzC7+umjMSzFlF2BnhLmK/KBitUiahyAeqVbm1Ob X-Received: by 2002:a05:6a20:9c9b:b0:a7:a3cf:ddce with SMTP id mj27-20020a056a209c9b00b000a7a3cfddcemr52727813pzb.21.1671465504481; Mon, 19 Dec 2022 07:58:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671465504; cv=none; d=google.com; s=arc-20160816; b=a3VXqYDwt/w+66HfVqALehUzEl+vvEWaZMUM7FqjK24qVapShfHdTW9Lr8bLQINWzO cj121c3DjLU32UZPlCqbu01e30ocLiIFsNvLx6KxiZbN9NvxzvNNOPAgjbVul/SbCsYV 70AAQInGd8IOC0HbBijzmqZqCwpfWkq9BvvAQmkQYFxBnCQ7hWrZuC6vh1uIhDwAwNp3 697JMTzWV7zZ8PtpHavAZBKDPK9k4GlGOh6Ze9D3vP1CE8u5P8DUfM1pVWLAEE/kyamA G7MAoghLpc/QMp+MmIfaPePjsr0qqIf4K9WGHwRH4YB5lmwY+0DGCI8bsn7gR9fY2tmm mqlQ== 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; bh=ZgoRS4ulxUbc2guiIGqRRpQ/j4h3e/vCr4T3NIe6mJg=; b=GMH2RTmt37/VAfhvFVxbngC773TiK8LxOR/Rjzh09Gyq1+XR5wzBKq6WdcUVjL/HJd 1TCGqr1qW68F1CpaWmWjC+TMk2t6DKXtkp+hmazWmgfN64l8frYZD8tIHuE+Ywgx7o9k eRtbZ6B2B8J2n2Vpw3MPC5mHclNzwZ1RRfa4FsH4ifrpL288ulSQF+IQEIWXbbcSewji MsOaSft9FjjToQD9vgQvHlU4Ecl3u6MUVGJF2xRuN2Mdk4xOEzENWEeD9e81A8aRfcVW UH06/BG205zjbXPhXuGR+K5v+qF1pE94GNuYfI7XphYeJMnwgcrZUSw1qlPANhRmkrTg W1hg== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id i3-20020a635843000000b004776a50bd21si11929897pgm.579.2022.12.19.07.58.15; Mon, 19 Dec 2022 07:58:24 -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; 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=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232329AbiLSOl6 (ORCPT + 71 others); Mon, 19 Dec 2022 09:41:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44728 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231811AbiLSOl4 (ORCPT ); Mon, 19 Dec 2022 09:41:56 -0500 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9CD48198 for ; Mon, 19 Dec 2022 06:41:53 -0800 (PST) Received: from kwepemm600001.china.huawei.com (unknown [172.30.72.55]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4NbMnl0g9GzRq56; Mon, 19 Dec 2022 22:40:43 +0800 (CST) Received: from huawei.com (10.175.113.133) by kwepemm600001.china.huawei.com (7.193.23.3) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.34; Mon, 19 Dec 2022 22:41:51 +0800 From: Wang Hai To: , , , CC: , Subject: [PATCH] kobject: Fix slab-out-of-bounds in fill_kobj_path() Date: Mon, 19 Dec 2022 22:41:03 +0800 Message-ID: <20221219144103.34789-1-wanghai38@huawei.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.175.113.133] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm600001.china.huawei.com (7.193.23.3) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS 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: X-Mailing-List: linux-kernel@vger.kernel.org In kobject_get_path(), if kobj->name is changed between calls get_kobj_path_length() and fill_kobj_path() and the length becomes longer, then fill_kobj_path() will have an out-of-bounds bug. The actual current problem occurs when the ixgbe probe. In ixgbe_mii_bus_init(), if the length of netdev->dev.kobj.name length becomes longer, out-of-bounds will occur. cpu0 cpu1 ixgbe_probe register_netdev(netdev) netdev_register_kobject device_add kobject_uevent // Sending ADD events systemd-udevd // rename netdev dev_change_name device_rename kobject_rename | ixgbe_mii_bus_init | mdiobus_register | __mdiobus_register | device_register | device_add | kobject_uevent | kobject_get_path | len = get_kobj_path_length // old name | path = kzalloc(len, gfp_mask); | kobj->name = name; /* name length becomes * longer */ fill_kobj_path /* kobj path length is * longer than path, * resulting in out of * bounds when filling path */ This is the kasan report: ================================================================== BUG: KASAN: slab-out-of-bounds in fill_kobj_path+0x50/0xc0 Write of size 7 at addr ff1100090573d1fd by task kworker/28:1/673 Workqueue: events work_for_cpu_fn Call Trace: dump_stack_lvl+0x34/0x48 print_address_description.constprop.0+0x86/0x1e7 print_report+0x36/0x4f kasan_report+0xad/0x130 kasan_check_range+0x35/0x1c0 memcpy+0x39/0x60 fill_kobj_path+0x50/0xc0 kobject_get_path+0x5a/0xc0 kobject_uevent_env+0x140/0x460 device_add+0x5c7/0x910 __mdiobus_register+0x14e/0x490 ixgbe_probe.cold+0x441/0x574 [ixgbe] local_pci_probe+0x78/0xc0 work_for_cpu_fn+0x26/0x40 process_one_work+0x3b6/0x6a0 worker_thread+0x368/0x520 kthread+0x165/0x1a0 ret_from_fork+0x1f/0x30 This reproducer triggers that bug: while: do rmmod ixgbe sleep 0.5 modprobe ixgbe sleep 0.5 When calling fill_kobj_path() to fill path, if the name length of kobj becomes longer, return failure and retry. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Wang Hai --- lib/kobject.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/kobject.c b/lib/kobject.c index a0b2dbfcfa23..d129f437b200 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -112,7 +112,7 @@ static int get_kobj_path_length(struct kobject *kobj) return length; } -static void fill_kobj_path(struct kobject *kobj, char *path, int length) +static bool fill_kobj_path(struct kobject *kobj, char *path, int length) { struct kobject *parent; @@ -121,12 +121,16 @@ 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) + return false; memcpy(path + length, kobject_name(parent), cur); *(path + --length) = '/'; } pr_debug("kobject: '%s' (%p): %s: path = '%s'\n", kobject_name(kobj), kobj, __func__, path); + + return true; } /** @@ -140,14 +144,20 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) { char *path; int len; + bool ret; +retry: len = get_kobj_path_length(kobj); if (len == 0) return NULL; path = kzalloc(len, gfp_mask); if (!path) return NULL; - fill_kobj_path(kobj, path, len); + ret = fill_kobj_path(kobj, path, len); + if (!ret) { + kfree(path); + goto retry; + } return path; } -- 2.17.1