]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/linux/linux-5.15-wifi-security-patches-4.patch
linux: Add upstream patches for CVE-2022-4{1674,2719-2722}
[ipfire-2.x.git] / src / patches / linux / linux-5.15-wifi-security-patches-4.patch
1 From bfe29873454f38eb1a511a76144ad1a4848ca176 Mon Sep 17 00:00:00 2001
2 From: Johannes Berg <johannes.berg@intel.com>
3 Date: Fri, 30 Sep 2022 23:44:23 +0200
4 Subject: [PATCH] wifi: cfg80211: fix BSS refcounting bugs
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=utf8
7 Content-Transfer-Encoding: 8bit
8
9 commit 0b7808818cb9df6680f98996b8e9a439fa7bcc2f upstream.
10
11 There are multiple refcounting bugs related to multi-BSSID:
12 - In bss_ref_get(), if the BSS has a hidden_beacon_bss, then
13 the bss pointer is overwritten before checking for the
14 transmitted BSS, which is clearly wrong. Fix this by using
15 the bss_from_pub() macro.
16
17 - In cfg80211_bss_update() we copy the transmitted_bss pointer
18 from tmp into new, but then if we release new, we'll unref
19 it erroneously. We already set the pointer and ref it, but
20 need to NULL it since it was copied from the tmp data.
21
22 - In cfg80211_inform_single_bss_data(), if adding to the non-
23 transmitted list fails, we unlink the BSS and yet still we
24 return it, but this results in returning an entry without
25 a reference. We shouldn't return it anyway if it was broken
26 enough to not get added there.
27
28 This fixes CVE-2022-42720.
29
30 Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
31 Tested-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
32 Fixes: a3584f56de1c ("cfg80211: Properly track transmitting and non-transmitting BSS")
33 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
34 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
35 ---
36 net/wireless/scan.c | 27 ++++++++++++++-------------
37 1 file changed, 14 insertions(+), 13 deletions(-)
38
39 diff --git a/net/wireless/scan.c b/net/wireless/scan.c
40 index 04c9b78b3fec..2e576714e989 100644
41 --- a/net/wireless/scan.c
42 +++ b/net/wireless/scan.c
43 @@ -143,18 +143,12 @@ static inline void bss_ref_get(struct cfg80211_registered_device *rdev,
44 lockdep_assert_held(&rdev->bss_lock);
45
46 bss->refcount++;
47 - if (bss->pub.hidden_beacon_bss) {
48 - bss = container_of(bss->pub.hidden_beacon_bss,
49 - struct cfg80211_internal_bss,
50 - pub);
51 - bss->refcount++;
52 - }
53 - if (bss->pub.transmitted_bss) {
54 - bss = container_of(bss->pub.transmitted_bss,
55 - struct cfg80211_internal_bss,
56 - pub);
57 - bss->refcount++;
58 - }
59 +
60 + if (bss->pub.hidden_beacon_bss)
61 + bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++;
62 +
63 + if (bss->pub.transmitted_bss)
64 + bss_from_pub(bss->pub.transmitted_bss)->refcount++;
65 }
66
67 static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
68 @@ -1743,6 +1737,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
69 new->refcount = 1;
70 INIT_LIST_HEAD(&new->hidden_list);
71 INIT_LIST_HEAD(&new->pub.nontrans_list);
72 + /* we'll set this later if it was non-NULL */
73 + new->pub.transmitted_bss = NULL;
74
75 if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
76 hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
77 @@ -1983,10 +1979,15 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
78 spin_lock_bh(&rdev->bss_lock);
79 if (cfg80211_add_nontrans_list(non_tx_data->tx_bss,
80 &res->pub)) {
81 - if (__cfg80211_unlink_bss(rdev, res))
82 + if (__cfg80211_unlink_bss(rdev, res)) {
83 rdev->bss_generation++;
84 + res = NULL;
85 + }
86 }
87 spin_unlock_bh(&rdev->bss_lock);
88 +
89 + if (!res)
90 + return NULL;
91 }
92
93 trace_cfg80211_return_bss(&res->pub);
94 --
95 2.30.2
96