362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. From 5d20c6f932f2758078d0454729129c894fe353e7 Mon Sep 17 00:00:00 2001
  2. From: Siddh Raman Pant <[email protected]>
  3. Date: Sat, 20 Aug 2022 01:33:40 +0530
  4. Subject: [PATCH] wifi: mac80211: Fix UAF in ieee80211_scan_rx()
  5. commit 60deb9f10eec5c6a20252ed36238b55d8b614a2c upstream.
  6. ieee80211_scan_rx() tries to access scan_req->flags after a
  7. null check, but a UAF is observed when the scan is completed
  8. and __ieee80211_scan_completed() executes, which then calls
  9. cfg80211_scan_done() leading to the freeing of scan_req.
  10. Since scan_req is rcu_dereference()'d, prevent the racing in
  11. __ieee80211_scan_completed() by ensuring that from mac80211's
  12. POV it is no longer accessed from an RCU read critical section
  13. before we call cfg80211_scan_done().
  14. Cc: [email protected]
  15. Link: https://syzkaller.appspot.com/bug?extid=f9acff9bf08a845f225d
  16. Reported-by: [email protected]
  17. Suggested-by: Johannes Berg <[email protected]>
  18. Signed-off-by: Siddh Raman Pant <[email protected]>
  19. Link: https://lore.kernel.org/r/[email protected]
  20. Signed-off-by: Johannes Berg <[email protected]>
  21. Signed-off-by: Greg Kroah-Hartman <[email protected]>
  22. ---
  23. net/mac80211/scan.c | 11 +++++++----
  24. 1 file changed, 7 insertions(+), 4 deletions(-)
  25. --- a/net/mac80211/scan.c
  26. +++ b/net/mac80211/scan.c
  27. @@ -465,16 +465,19 @@ static void __ieee80211_scan_completed(s
  28. scan_req = rcu_dereference_protected(local->scan_req,
  29. lockdep_is_held(&local->mtx));
  30. - if (scan_req != local->int_scan_req) {
  31. - local->scan_info.aborted = aborted;
  32. - cfg80211_scan_done(scan_req, &local->scan_info);
  33. - }
  34. RCU_INIT_POINTER(local->scan_req, NULL);
  35. RCU_INIT_POINTER(local->scan_sdata, NULL);
  36. local->scanning = 0;
  37. local->scan_chandef.chan = NULL;
  38. + synchronize_rcu();
  39. +
  40. + if (scan_req != local->int_scan_req) {
  41. + local->scan_info.aborted = aborted;
  42. + cfg80211_scan_done(scan_req, &local->scan_info);
  43. + }
  44. +
  45. /* Set power back to normal operating levels. */
  46. ieee80211_hw_config(local, 0);