Message ID | 20250117061737.1921-2-quic_kangyang@quicinc.com |
---|---|
State | New |
Headers | show |
Series | wifi: ath11k: fix data out of sync for channel list for reg update | expand |
On 1/17/25 11:47, Kang Yang wrote: > From: Wen Gong <quic_wgong@quicinc.com> > > Currently when ath11k gets a new channel list, it will be processed > according to the following steps: > 1. update new channel list to cfg80211 and queue reg_work. > 2. cfg80211 handles new channel list during reg_work. > 3. update cfg80211's handled channel list to firmware by > ath11k_reg_update_chan_list(). > > But ath11k will immediately execute step 3 after reg_work is just > queued. Since step 2 is asynchronous, cfg80211 may not have completed > handling the new channel list, which may leading to an out-of-bounds > write error: > BUG: KASAN: slab-out-of-bounds in ath11k_reg_update_chan_list > Call Trace: > ath11k_reg_update_chan_list+0xbfe/0xfe0 [ath11k] > kfree+0x109/0x3a0 > ath11k_regd_update+0x1cf/0x350 [ath11k] > ath11k_regd_update_work+0x14/0x20 [ath11k] > process_one_work+0xe35/0x14c0 > > Should ensure step 2 is completely done before executing step 3. Thus > Wen raised patch[1]. When flag NL80211_REGDOM_SET_BY_DRIVER is set, > cfg80211 will notify ath11k after step 2 is done. > > So enable the flag NL80211_REGDOM_SET_BY_DRIVER then cfg80211 will > notify ath11k after step 2 is done. At this time, there will be no > KASAN bug during the execution of the step 3. > > [1] https://patchwork.kernel.org/project/linux-wireless/patch/20230201065313.27203-1-quic_wgong@quicinc.com/ > > Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 > > Fixes: f45cb6b29cd3 ("wifi: ath11k: avoid deadlock during regulatory update in ath11k_regd_update()") > Signed-off-by: Wen Gong <quic_wgong@quicinc.com> > Signed-off-by: Kang Yang <quic_kangyang@quicinc.com> > --- Reviewed-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index b0f289784dd3..7bfe47ad62a0 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/rtnetlink.h> @@ -55,6 +55,19 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) ath11k_dbg(ar->ab, ATH11K_DBG_REG, "Regulatory Notification received for %s\n", wiphy_name(wiphy)); + if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER) { + ath11k_dbg(ar->ab, ATH11K_DBG_REG, + "driver initiated regd update\n"); + if (ar->state != ATH11K_STATE_ON) + return; + + ret = ath11k_reg_update_chan_list(ar, true); + if (ret) + ath11k_warn(ar->ab, "failed to update channel list: %d\n", ret); + + return; + } + /* Currently supporting only General User Hints. Cell base user * hints to be handled later. * Hints from other sources like Core, Beacons are not expected for @@ -293,12 +306,6 @@ int ath11k_regd_update(struct ath11k *ar) if (ret) goto err; - if (ar->state == ATH11K_STATE_ON) { - ret = ath11k_reg_update_chan_list(ar, true); - if (ret) - goto err; - } - return 0; err: ath11k_warn(ab, "failed to perform regd update : %d\n", ret); @@ -977,6 +984,7 @@ void ath11k_regd_update_work(struct work_struct *work) void ath11k_reg_init(struct ath11k *ar) { ar->hw->wiphy->regulatory_flags = REGULATORY_WIPHY_SELF_MANAGED; + ar->hw->wiphy->flags |= WIPHY_FLAG_NOTIFY_REGDOM_BY_DRIVER; ar->hw->wiphy->reg_notifier = ath11k_reg_notifier; }