From 1f0fb0c9ae0a94b595bcd523722aa7543cd86c8f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 14 Oct 2024 10:50:23 +0200 Subject: [PATCH] 5.4-stable patches added patches: cdc-ncm-avoid-overflow-in-sanity-checking.patch resource-fix-region_intersects-vs-add_memory_driver_managed.patch wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch --- ...cm-avoid-overflow-in-sanity-checking.patch | 53 ++++++ ...ersects-vs-add_memory_driver_managed.patch | 175 ++++++++++++++++++ queue-5.4/series | 3 + ...sdata-can-be-null-during-ampdu-start.patch | 116 ++++++++++++ 4 files changed, 347 insertions(+) create mode 100644 queue-5.4/cdc-ncm-avoid-overflow-in-sanity-checking.patch create mode 100644 queue-5.4/resource-fix-region_intersects-vs-add_memory_driver_managed.patch create mode 100644 queue-5.4/wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch diff --git a/queue-5.4/cdc-ncm-avoid-overflow-in-sanity-checking.patch b/queue-5.4/cdc-ncm-avoid-overflow-in-sanity-checking.patch new file mode 100644 index 00000000000..ea2961e16b9 --- /dev/null +++ b/queue-5.4/cdc-ncm-avoid-overflow-in-sanity-checking.patch @@ -0,0 +1,53 @@ +From 8d2b1a1ec9f559d30b724877da4ce592edc41fdc Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Tue, 15 Feb 2022 11:35:47 +0100 +Subject: CDC-NCM: avoid overflow in sanity checking + +From: Oliver Neukum + +commit 8d2b1a1ec9f559d30b724877da4ce592edc41fdc upstream. + +A broken device may give an extreme offset like 0xFFF0 +and a reasonable length for a fragment. In the sanity +check as formulated now, this will create an integer +overflow, defeating the sanity check. Both offset +and offset + len need to be checked in such a manner +that no overflow can occur. +And those quantities should be unsigned. + +Signed-off-by: Oliver Neukum +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: David S. Miller +Signed-off-by: Bruno VERNAY +Signed-off-by: Hugo SIMELIERE +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/cdc_ncm.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/usb/cdc_ncm.c ++++ b/drivers/net/usb/cdc_ncm.c +@@ -1707,10 +1707,10 @@ int cdc_ncm_rx_fixup(struct usbnet *dev, + { + struct sk_buff *skb; + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; +- int len; ++ unsigned int len; + int nframes; + int x; +- int offset; ++ unsigned int offset; + union { + struct usb_cdc_ncm_ndp16 *ndp16; + struct usb_cdc_ncm_ndp32 *ndp32; +@@ -1782,8 +1782,8 @@ next_ndp: + break; + } + +- /* sanity checking */ +- if (((offset + len) > skb_in->len) || ++ /* sanity checking - watch out for integer wrap*/ ++ if ((offset > skb_in->len) || (len > skb_in->len - offset) || + (len > ctx->rx_max) || (len < ETH_HLEN)) { + netif_dbg(dev, rx_err, dev->net, + "invalid frame detected (ignored) offset[%u]=%u, length=%u, skb=%p\n", diff --git a/queue-5.4/resource-fix-region_intersects-vs-add_memory_driver_managed.patch b/queue-5.4/resource-fix-region_intersects-vs-add_memory_driver_managed.patch new file mode 100644 index 00000000000..c862210ace5 --- /dev/null +++ b/queue-5.4/resource-fix-region_intersects-vs-add_memory_driver_managed.patch @@ -0,0 +1,175 @@ +From b4afe4183ec77f230851ea139d91e5cf2644c68b Mon Sep 17 00:00:00 2001 +From: Huang Ying +Date: Fri, 6 Sep 2024 11:07:11 +0800 +Subject: resource: fix region_intersects() vs add_memory_driver_managed() + +From: Huang Ying + +commit b4afe4183ec77f230851ea139d91e5cf2644c68b upstream. + +On a system with CXL memory, the resource tree (/proc/iomem) related to +CXL memory may look like something as follows. + +490000000-50fffffff : CXL Window 0 + 490000000-50fffffff : region0 + 490000000-50fffffff : dax0.0 + 490000000-50fffffff : System RAM (kmem) + +Because drivers/dax/kmem.c calls add_memory_driver_managed() during +onlining CXL memory, which makes "System RAM (kmem)" a descendant of "CXL +Window X". This confuses region_intersects(), which expects all "System +RAM" resources to be at the top level of iomem_resource. This can lead to +bugs. + +For example, when the following command line is executed to write some +memory in CXL memory range via /dev/mem, + + $ dd if=data of=/dev/mem bs=$((1 << 10)) seek=$((0x490000000 >> 10)) count=1 + dd: error writing '/dev/mem': Bad address + 1+0 records in + 0+0 records out + 0 bytes copied, 0.0283507 s, 0.0 kB/s + +the command fails as expected. However, the error code is wrong. It +should be "Operation not permitted" instead of "Bad address". More +seriously, the /dev/mem permission checking in devmem_is_allowed() passes +incorrectly. Although the accessing is prevented later because ioremap() +isn't allowed to map system RAM, it is a potential security issue. During +command executing, the following warning is reported in the kernel log for +calling ioremap() on system RAM. + + ioremap on RAM at 0x0000000490000000 - 0x0000000490000fff + WARNING: CPU: 2 PID: 416 at arch/x86/mm/ioremap.c:216 __ioremap_caller.constprop.0+0x131/0x35d + Call Trace: + memremap+0xcb/0x184 + xlate_dev_mem_ptr+0x25/0x2f + write_mem+0x94/0xfb + vfs_write+0x128/0x26d + ksys_write+0xac/0xfe + do_syscall_64+0x9a/0xfd + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + +The details of command execution process are as follows. In the above +resource tree, "System RAM" is a descendant of "CXL Window 0" instead of a +top level resource. So, region_intersects() will report no System RAM +resources in the CXL memory region incorrectly, because it only checks the +top level resources. Consequently, devmem_is_allowed() will return 1 +(allow access via /dev/mem) for CXL memory region incorrectly. +Fortunately, ioremap() doesn't allow to map System RAM and reject the +access. + +So, region_intersects() needs to be fixed to work correctly with the +resource tree with "System RAM" not at top level as above. To fix it, if +we found a unmatched resource in the top level, we will continue to search +matched resources in its descendant resources. So, we will not miss any +matched resources in resource tree anymore. + +In the new implementation, an example resource tree + +|------------- "CXL Window 0" ------------| +|-- "System RAM" --| + +will behave similar as the following fake resource tree for +region_intersects(, IORESOURCE_SYSTEM_RAM, ), + +|-- "System RAM" --||-- "CXL Window 0a" --| + +Where "CXL Window 0a" is part of the original "CXL Window 0" that +isn't covered by "System RAM". + +Link: https://lkml.kernel.org/r/20240906030713.204292-2-ying.huang@intel.com +Fixes: c221c0b0308f ("device-dax: "Hotplug" persistent memory for use like normal RAM") +Signed-off-by: "Huang, Ying" +Cc: Dan Williams +Cc: David Hildenbrand +Cc: Davidlohr Bueso +Cc: Jonathan Cameron +Cc: Dave Jiang +Cc: Alison Schofield +Cc: Vishal Verma +Cc: Ira Weiny +Cc: Alistair Popple +Cc: Andy Shevchenko +Cc: Bjorn Helgaas +Cc: Baoquan He +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + kernel/resource.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 50 insertions(+), 8 deletions(-) + +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -536,21 +536,63 @@ EXPORT_SYMBOL_GPL(page_is_ram); + int region_intersects(resource_size_t start, size_t size, unsigned long flags, + unsigned long desc) + { +- struct resource res; ++ resource_size_t ostart, oend; + int type = 0; int other = 0; +- struct resource *p; ++ struct resource *p, *dp; ++ bool is_type, covered; ++ struct resource res; + + res.start = start; + res.end = start + size - 1; + + read_lock(&resource_lock); + for (p = iomem_resource.child; p ; p = p->sibling) { +- bool is_type = (((p->flags & flags) == flags) && +- ((desc == IORES_DESC_NONE) || +- (desc == p->desc))); +- +- if (resource_overlaps(p, &res)) +- is_type ? type++ : other++; ++ if (!resource_overlaps(p, &res)) ++ continue; ++ is_type = (p->flags & flags) == flags && ++ (desc == IORES_DESC_NONE || desc == p->desc); ++ if (is_type) { ++ type++; ++ continue; ++ } ++ /* ++ * Continue to search in descendant resources as if the ++ * matched descendant resources cover some ranges of 'p'. ++ * ++ * |------------- "CXL Window 0" ------------| ++ * |-- "System RAM" --| ++ * ++ * will behave similar as the following fake resource ++ * tree when searching "System RAM". ++ * ++ * |-- "System RAM" --||-- "CXL Window 0a" --| ++ */ ++ covered = false; ++ ostart = max(res.start, p->start); ++ oend = min(res.end, p->end); ++ for (dp = p->child; dp; dp = next_resource(dp, false)) { ++ if (!resource_overlaps(dp, &res)) ++ continue; ++ is_type = (dp->flags & flags) == flags && ++ (desc == IORES_DESC_NONE || desc == dp->desc); ++ if (is_type) { ++ type++; ++ /* ++ * Range from 'ostart' to 'dp->start' ++ * isn't covered by matched resource. ++ */ ++ if (dp->start > ostart) ++ break; ++ if (dp->end >= oend) { ++ covered = true; ++ break; ++ } ++ /* Remove covered range */ ++ ostart = max(ostart, dp->end + 1); ++ } ++ } ++ if (!covered) ++ other++; + } + read_unlock(&resource_lock); + diff --git a/queue-5.4/series b/queue-5.4/series index c2202b20760..9349a9dcb39 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -346,3 +346,6 @@ locking-lockdep-fix-bad-recursion-pattern.patch locking-lockdep-rework-lockdep_lock.patch locking-lockdep-avoid-potential-access-of-invalid-me.patch lockdep-fix-deadlock-issue-between-lockdep-and-rcu.patch +resource-fix-region_intersects-vs-add_memory_driver_managed.patch +cdc-ncm-avoid-overflow-in-sanity-checking.patch +wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch diff --git a/queue-5.4/wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch b/queue-5.4/wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch new file mode 100644 index 00000000000..16dc3107577 --- /dev/null +++ b/queue-5.4/wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch @@ -0,0 +1,116 @@ +From 69403bad97aa0162e3d7911b27e25abe774093df Mon Sep 17 00:00:00 2001 +From: Alexander Wetzel +Date: Fri, 30 Dec 2022 13:18:50 +0100 +Subject: wifi: mac80211: sdata can be NULL during AMPDU start + +From: Alexander Wetzel + +commit 69403bad97aa0162e3d7911b27e25abe774093df upstream. + +ieee80211_tx_ba_session_handle_start() may get NULL for sdata when a +deauthentication is ongoing. + +Here a trace triggering the race with the hostapd test +multi_ap_fronthaul_on_ap: + +(gdb) list *drv_ampdu_action+0x46 +0x8b16 is in drv_ampdu_action (net/mac80211/driver-ops.c:396). +391 int ret = -EOPNOTSUPP; +392 +393 might_sleep(); +394 +395 sdata = get_bss_sdata(sdata); +396 if (!check_sdata_in_driver(sdata)) +397 return -EIO; +398 +399 trace_drv_ampdu_action(local, sdata, params); +400 + +wlan0: moving STA 02:00:00:00:03:00 to state 3 +wlan0: associated +wlan0: deauthenticating from 02:00:00:00:03:00 by local choice (Reason: 3=DEAUTH_LEAVING) +wlan3.sta1: Open BA session requested for 02:00:00:00:00:00 tid 0 +wlan3.sta1: dropped frame to 02:00:00:00:00:00 (unauthorized port) +wlan0: moving STA 02:00:00:00:03:00 to state 2 +wlan0: moving STA 02:00:00:00:03:00 to state 1 +wlan0: Removed STA 02:00:00:00:03:00 +wlan0: Destroyed STA 02:00:00:00:03:00 +BUG: unable to handle page fault for address: fffffffffffffb48 +PGD 11814067 P4D 11814067 PUD 11816067 PMD 0 +Oops: 0000 [#1] PREEMPT SMP PTI +CPU: 2 PID: 133397 Comm: kworker/u16:1 Tainted: G W 6.1.0-rc8-wt+ #59 +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.0-20220807_005459-localhost 04/01/2014 +Workqueue: phy3 ieee80211_ba_session_work [mac80211] +RIP: 0010:drv_ampdu_action+0x46/0x280 [mac80211] +Code: 53 48 89 f3 be 89 01 00 00 e8 d6 43 bf ef e8 21 46 81 f0 83 bb a0 1b 00 00 04 75 0e 48 8b 9b 28 0d 00 00 48 81 eb 10 0e 00 00 <8b> 93 58 09 00 00 f6 c2 20 0f 84 3b 01 00 00 8b 05 dd 1c 0f 00 85 +RSP: 0018:ffffc900025ebd20 EFLAGS: 00010287 +RAX: 0000000000000000 RBX: fffffffffffff1f0 RCX: ffff888102228240 +RDX: 0000000080000000 RSI: ffffffff918c5de0 RDI: ffff888102228b40 +RBP: ffffc900025ebd40 R08: 0000000000000001 R09: 0000000000000001 +R10: 0000000000000001 R11: 0000000000000000 R12: ffff888118c18ec0 +R13: 0000000000000000 R14: ffffc900025ebd60 R15: ffff888018b7efb8 +FS: 0000000000000000(0000) GS:ffff88817a600000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: fffffffffffffb48 CR3: 0000000105228006 CR4: 0000000000170ee0 +Call Trace: + + ieee80211_tx_ba_session_handle_start+0xd0/0x190 [mac80211] + ieee80211_ba_session_work+0xff/0x2e0 [mac80211] + process_one_work+0x29f/0x620 + worker_thread+0x4d/0x3d0 + ? process_one_work+0x620/0x620 + kthread+0xfb/0x120 + ? kthread_complete_and_exit+0x20/0x20 + ret_from_fork+0x22/0x30 + + +Signed-off-by: Alexander Wetzel +Link: https://lore.kernel.org/r/20221230121850.218810-2-alexander@wetzel-home.de +Cc: stable@vger.kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Bruno VERNAY +Signed-off-by: Hugo SIMELIERE +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/agg-tx.c | 6 +++++- + net/mac80211/driver-ops.c | 3 +++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- a/net/mac80211/agg-tx.c ++++ b/net/mac80211/agg-tx.c +@@ -489,7 +489,7 @@ void ieee80211_tx_ba_session_handle_star + { + struct tid_ampdu_tx *tid_tx; + struct ieee80211_local *local = sta->local; +- struct ieee80211_sub_if_data *sdata = sta->sdata; ++ struct ieee80211_sub_if_data *sdata; + struct ieee80211_ampdu_params params = { + .sta = &sta->sta, + .action = IEEE80211_AMPDU_TX_START, +@@ -519,10 +519,14 @@ void ieee80211_tx_ba_session_handle_star + */ + synchronize_net(); + ++ sdata = sta->sdata; + params.ssn = sta->tid_seq[tid] >> 4; + ret = drv_ampdu_action(local, sdata, ¶ms); + tid_tx->ssn = params.ssn; + if (ret) { ++ if (!sdata) ++ return; ++ + ht_dbg(sdata, + "BA request denied - HW unavailable for %pM tid %d\n", + sta->sta.addr, tid); +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -331,6 +331,9 @@ int drv_ampdu_action(struct ieee80211_lo + + might_sleep(); + ++ if (!sdata) ++ return -EIO; ++ + sdata = get_bss_sdata(sdata); + if (!check_sdata_in_driver(sdata)) + return -EIO; -- 2.47.2