]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: ath11k: fix NULL pointer dereference in ath11k_hal_srng_access_begin
authorGaole Zhang <gaole.zhang@oss.qualcomm.com>
Tue, 9 Jun 2026 09:06:09 +0000 (17:06 +0800)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Thu, 2 Jul 2026 21:05:01 +0000 (14:05 -0700)
In ATH11K_QMI_EVENT_FW_READY, ATH11K_FLAG_REGISTERED is set
unconditionally even when ath11k_core_qmi_firmware_ready() fails.
This leaves the driver in an inconsistent state where
initialization is considered complete although the firmware ready
handling did not finish successfully. During the subsequent SSR,
the driver enters the restart path based on this incorrect state
and dereferences uninitialized srng members, resulting in a NULL
pointer dereference.

Call trace:
  ath11k_hal_srng_access_begin+0xc/0x60 [ath11k] (P)
  ath11k_ce_cleanup_pipes+0x17c/0x180 [ath11k]
  ath11k_core_restart+0x40/0x168 [ath11k]

Fix this by:
- skipping firmware_ready if ATH11K_FLAG_REGISTERED is already set
- setting ATH11K_FLAG_REGISTERED only when firmware_ready succeeds
- setting ATH11K_FLAG_QMI_FAIL and aborting the FW_READY handling
on error

Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.2.0.c2-00204-QCAMSLSWPLZ-1

Fixes: 6fe62a8cec51c ("wifi: ath11k: Add cold boot calibration support on WCN6750")
Signed-off-by: Gaole Zhang <gaole.zhang@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260609090609.4041009-1-gaole.zhang@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath11k/qmi.c

index 410a7ee076a02654a7c7ffcb548be37fd21a71b8..7dc07339b9579d402b09847376d03bf77e575c73 100644 (file)
@@ -3294,9 +3294,14 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
                        clear_bit(ATH11K_FLAG_CRASH_FLUSH,
                                  &ab->dev_flags);
                        clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
-                       ath11k_core_qmi_firmware_ready(ab);
-                       set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
-
+                       if (!test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
+                               ret = ath11k_core_qmi_firmware_ready(ab);
+                               if (ret) {
+                                       set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
+                                       break;
+                               }
+                               set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
+                       }
                        break;
                case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
                        break;