]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Oct 2024 08:50:23 +0000 (10:50 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Oct 2024 08:50:23 +0000 (10:50 +0200)
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

queue-5.4/cdc-ncm-avoid-overflow-in-sanity-checking.patch [new file with mode: 0644]
queue-5.4/resource-fix-region_intersects-vs-add_memory_driver_managed.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch [new file with mode: 0644]

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 (file)
index 0000000..ea2961e
--- /dev/null
@@ -0,0 +1,53 @@
+From 8d2b1a1ec9f559d30b724877da4ce592edc41fdc Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Tue, 15 Feb 2022 11:35:47 +0100
+Subject: CDC-NCM: avoid overflow in sanity checking
+
+From: Oliver Neukum <oneukum@suse.com>
+
+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 <oneukum@suse.com>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Bruno VERNAY <bruno.vernay@se.com>
+Signed-off-by: Hugo SIMELIERE <hsimeliere.opensource@witekio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..c862210
--- /dev/null
@@ -0,0 +1,175 @@
+From b4afe4183ec77f230851ea139d91e5cf2644c68b Mon Sep 17 00:00:00 2001
+From: Huang Ying <ying.huang@intel.com>
+Date: Fri, 6 Sep 2024 11:07:11 +0800
+Subject: resource: fix region_intersects() vs add_memory_driver_managed()
+
+From: Huang Ying <ying.huang@intel.com>
+
+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" <ying.huang@intel.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: Jonathan Cameron <jonathan.cameron@huawei.com>
+Cc: Dave Jiang <dave.jiang@intel.com>
+Cc: Alison Schofield <alison.schofield@intel.com>
+Cc: Vishal Verma <vishal.l.verma@intel.com>
+Cc: Ira Weiny <ira.weiny@intel.com>
+Cc: Alistair Popple <apopple@nvidia.com>
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Baoquan He <bhe@redhat.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
index c2202b20760511e35e7897ce5a87e04defeee78c..9349a9dcb393a14980d536fdf671d1f7257c608b 100644 (file)
@@ -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 (file)
index 0000000..16dc310
--- /dev/null
@@ -0,0 +1,116 @@
+From 69403bad97aa0162e3d7911b27e25abe774093df Mon Sep 17 00:00:00 2001
+From: Alexander Wetzel <alexander@wetzel-home.de>
+Date: Fri, 30 Dec 2022 13:18:50 +0100
+Subject: wifi: mac80211: sdata can be NULL during AMPDU start
+
+From: Alexander Wetzel <alexander@wetzel-home.de>
+
+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:
+ <TASK>
+ 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
+ </TASK>
+
+Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
+Link: https://lore.kernel.org/r/20221230121850.218810-2-alexander@wetzel-home.de
+Cc: stable@vger.kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Bruno VERNAY <bruno.vernay@se.com>
+Signed-off-by: Hugo SIMELIERE <hsimeliere.opensource@witekio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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, &params);
+       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;