Received: by 2002:a05:6358:f14:b0:e5:3b68:ec04 with SMTP id b20csp3380506rwj; Mon, 19 Dec 2022 17:51:44 -0800 (PST) X-Google-Smtp-Source: AA0mqf4J7j5YvwORwQNy/Xupb7ToZZLdyAKhjS/H5dvGOYfpw8eO0RXQNTghHYx6uOP02DFIQjDk X-Received: by 2002:a05:6402:e97:b0:461:6219:4b16 with SMTP id h23-20020a0564020e9700b0046162194b16mr25693810eda.33.1671501103981; Mon, 19 Dec 2022 17:51:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671501103; cv=none; d=google.com; s=arc-20160816; b=ohUoHaKC6Yilf+fZxrRC/g9WflaGS/vwogvR1eT8C3E+AcaV9a9u6K9z863K6ZdW/X oNv7Kkw500TgUbQGv1NGN3WFl/6a2gXhlDVBFPWTb5BZIkrAdDMbwhgh+DrnfPHi7IsW TFrAEJJrkvRPVGvMuOM30ac/4ByW9OLHB/1NXDQ92byO/bJVELxQfKgYvre/ziJVOOtX s101Vbl4U2EHk5Fl+4zLHMk4EFPRO/dOnf4HBnhwLyn0wKYu68in7sQ82Z2GqFf//V4E DV6dqwzZRyV5wXFPPy5d86R4WbV4pwl07sjqwkPd1e2sn4+v07NH8piaqHKjkmrctmYn /xWQ== 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=3d09prxq54KnjTcHMi0gRm/bHaMO6sNkJD412gjIhb0=; b=maG2DpqWZ8WSvjOlZGqgsr65honksJ+xK81i2dXEgj7LuEhhNhTpRvbsywfNAcsfwo oPhyjcgIAtWqZ7SfQBSdNy0UFX3uKHvqatuupHVNw9ts7Rh4n/3wuvBMqZeU0+3CeTfl e93C7YMHHCMvLfYct8OmzcDqlnc6LjHRZZ+6L3ELwAza4PofMF00deru9Tey5xBIPLoI /uK37BMaQNBZt87igLsWuq6rFuftClKPE0GOur6kTY6BTV6F814VaGuXmtHqyZM6I4OR vhDMxq4lujrYCVb76vb1rTdG8m8WPLd+ZXPem5NQXme+csc9+BFkuf24EbOAImQZkvBi ezGA== 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 v13-20020a056402348d00b0046b7410c015si11055865edc.18.2022.12.19.17.51.27; Mon, 19 Dec 2022 17:51:43 -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 S232432AbiLTB1A (ORCPT + 70 others); Mon, 19 Dec 2022 20:27:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52464 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233255AbiLTBYc (ORCPT ); Mon, 19 Dec 2022 20:24:32 -0500 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BDC2111A1E for ; Mon, 19 Dec 2022 17:22:34 -0800 (PST) Received: from kwepemm600001.china.huawei.com (unknown [172.30.72.53]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4Nbf0z4gmLzRq6v; Tue, 20 Dec 2022 09:21:23 +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; Tue, 20 Dec 2022 09:22:32 +0800 From: Wang Hai To: , , , , CC: , Subject: [PATCH v2] kobject: Fix slab-out-of-bounds in fill_kobj_path() Date: Tue, 20 Dec 2022 09:21:43 +0800 Message-ID: <20221220012143.52141-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: dggems701-chm.china.huawei.com (10.3.19.178) 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. This fixes the problem. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Wang Hai --- v1->v2: Return value type change and some formatting adjustments. lib/kobject.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/kobject.c b/lib/kobject.c index a0b2dbfcfa23..3f97d903266a 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 int 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 -EINVAL; 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 0; } /** @@ -141,13 +145,17 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) char *path; int len; +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); + if (fill_kobj_path(kobj, path, len)) { + kfree(path); + goto retry; + } return path; } -- 2.17.1