Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp8948703rwb; Thu, 24 Nov 2022 06:17:42 -0800 (PST) X-Google-Smtp-Source: AA0mqf5ZoKnY5DFquXUJWod1+y8nd/xU3ZXotsu2oe6d7wBIpK48FzhcDWib63x5FXOqMcoS6hCb X-Received: by 2002:a65:5606:0:b0:477:b96f:1f62 with SMTP id l6-20020a655606000000b00477b96f1f62mr7271356pgs.563.1669299462156; Thu, 24 Nov 2022 06:17:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669299462; cv=none; d=google.com; s=arc-20160816; b=E9rrIsGoL0ZGI/MvXzqWo3xAe8vZs+n0toesQgtDXtPKJdhS2ogUJ8+5bt4em9teqR kbldpmjArxh8XrK5fdvkHiriIDZYRcmwDqWW0sU1TrPu430+VHfm9qDJibVHuyYtyDO7 aSvoJhtWV7sM8lca2Zl68r0b9MBBzeW6sRyjeStzi4JiyHYqWT1dT3n/7gmaQBJG8FSU S41Zl/0Pb5gy1lUpMtXn82CXpLXgcNJXUZXgmOYGmtHGKDEeYL8oD4TB+4HjojoHapC6 39yS+CoTeln2nD/3QhdOxgTV1q+8ZujIMFNrlvub8YyzkxsaQc+HRTdzqns5CaWXJg4O SrQw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:to:from; bh=CookakBweoG+y0Lddjj5HQ+gpKYaUZOBW0DL+4tWAYM=; b=zqFNSzKcUI3PcLk0lgK+mdPwzz7MKskbBLnTNfi2BafmuweMucT08YaLef7PPnMqtt IXGMTSDh9SbXOyIgZwB8KvfHv4dGIrYKyWIHMZI6E5q0nfqax/Hp4vyOOuVxEj673qQm A6+TrLDH8mDRad+AfYKG23ANyQqPghQUINxROMHAEOA5H+F7E0JLGzOvYcnx/V4wezYM k+pHTnbtpUvwRnbK+kSRapk4zYPZBiefw95aFizTMOp/302QQqI3JDkHuuzP4AAwnWii JYZNe2xaJ553XOI6BOv1zGsA+zL4WIaAmZSLdp26+LCuERUeyhwtk/2unogFq7b+GU/i m58Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-wireless-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 g14-20020a056a001a0e00b00565c337c562si1247198pfv.100.2022.11.24.06.17.31; Thu, 24 Nov 2022 06:17:42 -0800 (PST) Received-SPF: pass (google.com: domain of linux-wireless-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-wireless-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-wireless-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 S229921AbiKXOJY (ORCPT + 67 others); Thu, 24 Nov 2022 09:09:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39052 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229630AbiKXOJX (ORCPT ); Thu, 24 Nov 2022 09:09:23 -0500 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B68149099; Thu, 24 Nov 2022 06:09:21 -0800 (PST) Received: from dggpeml500023.china.huawei.com (unknown [172.30.72.53]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4NJ0GP4HGtzmVJ8; Thu, 24 Nov 2022 22:08:45 +0800 (CST) Received: from localhost.localdomain (10.175.101.6) by dggpeml500023.china.huawei.com (7.185.36.114) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Thu, 24 Nov 2022 22:09:18 +0800 From: Zhang Xiaoxu To: , , , , , , , , , Subject: [PATCH wireless] wifi: wilc1000: Fix UAF in wilc_netdev_cleanup() when iterator the RCU list Date: Thu, 24 Nov 2022 23:13:49 +0800 Message-ID: <20221124151349.2386077-1-zhangxiaoxu5@huawei.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) To dggpeml500023.china.huawei.com (7.185.36.114) 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-wireless@vger.kernel.org There is a UAF read when remove the wilc1000_spi module: BUG: KASAN: use-after-free in wilc_netdev_cleanup.cold+0xc4/0xe0 [wilc1000] Read of size 8 at addr ffff888116846900 by task rmmod/386 CPU: 2 PID: 386 Comm: rmmod Tainted: G N 6.1.0-rc6+ #8 Call Trace: dump_stack_lvl+0x68/0x85 print_report+0x16c/0x4a3 kasan_report+0x95/0x190 wilc_netdev_cleanup.cold+0xc4/0xe0 wilc_bus_remove+0x52/0x60 spi_remove+0x46/0x60 device_remove+0x73/0xc0 device_release_driver_internal+0x12d/0x210 driver_detach+0x84/0x100 bus_remove_driver+0x90/0x120 driver_unregister+0x4f/0x80 __x64_sys_delete_module+0x2fc/0x440 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd Since set 'needs_free_netdev=true' when initialize the net device, the net device will be freed when unregister, then use the freed 'vif' to find the next will UAF read. Let's unregister the net device after removed from wilc list to avoid the UAF. Fixes: 8399918f3056 ("staging: wilc1000: use RCU list to maintain vif interfaces list") Signed-off-by: Zhang Xiaoxu --- drivers/net/wireless/microchip/wilc1000/netdev.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c index 9b319a455b96..d6374bfd7650 100644 --- a/drivers/net/wireless/microchip/wilc1000/netdev.c +++ b/drivers/net/wireless/microchip/wilc1000/netdev.c @@ -879,6 +879,7 @@ void wilc_netdev_cleanup(struct wilc *wilc) { struct wilc_vif *vif; int srcu_idx, ifc_cnt = 0; + LIST_HEAD(list_kill); if (!wilc) return; @@ -888,16 +889,14 @@ void wilc_netdev_cleanup(struct wilc *wilc) wilc->firmware = NULL; } + rtnl_lock(); srcu_idx = srcu_read_lock(&wilc->srcu); list_for_each_entry_rcu(vif, &wilc->vif_list, list) { if (vif->ndev) - unregister_netdev(vif->ndev); + unregister_netdevice_queue(vif->ndev, &list_kill); } srcu_read_unlock(&wilc->srcu, srcu_idx); - wilc_wfi_deinit_mon_interface(wilc, false); - destroy_workqueue(wilc->hif_workqueue); - while (ifc_cnt < WILC_NUM_CONCURRENT_IFC) { mutex_lock(&wilc->vif_mutex); if (wilc->vif_num <= 0) { @@ -914,6 +913,12 @@ void wilc_netdev_cleanup(struct wilc *wilc) ifc_cnt++; } + unregister_netdevice_many(&list_kill); + rtnl_unlock(); + + wilc_wfi_deinit_mon_interface(wilc, false); + destroy_workqueue(wilc->hif_workqueue); + wilc_wlan_cfg_deinit(wilc); wlan_deinit_locks(wilc); wiphy_unregister(wilc->wiphy); -- 2.31.1