]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Jul 2026 07:41:05 +0000 (09:41 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Jul 2026 07:41:05 +0000 (09:41 +0200)
added patches:
smb-client-reject-overlapping-data-areas-in-smb2-responses.patch

queue-7.1/smb-client-reject-overlapping-data-areas-in-smb2-responses.patch [new file with mode: 0644]

diff --git a/queue-7.1/smb-client-reject-overlapping-data-areas-in-smb2-responses.patch b/queue-7.1/smb-client-reject-overlapping-data-areas-in-smb2-responses.patch
new file mode 100644 (file)
index 0000000..980a4cc
--- /dev/null
@@ -0,0 +1,116 @@
+From 8986c932905ea508d66da421eb2eb6e676ace1fe Mon Sep 17 00:00:00 2001
+From: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>
+Date: Sat, 11 Jul 2026 22:33:26 +0900
+Subject: smb: client: reject overlapping data areas in SMB2 responses
+
+From: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>
+
+commit 8986c932905ea508d66da421eb2eb6e676ace1fe upstream.
+
+Commit 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to
+responses without data area") restricted the implied bcc[0] length
+exception to responses without a data area. However, the overlap
+handling in __smb2_calc_size() clears data_length, which can make an
+invalid response appear to have no data area and so qualify for the
+exception.
+
+Track data area overlap separately and reject such responses before
+applying the length compatibility exceptions.
+
+Fixes: 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to responses without data area")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/smb2misc.c |   34 +++++++++++++++++++++++++---------
+ 1 file changed, 25 insertions(+), 9 deletions(-)
+
+--- a/fs/smb/client/smb2misc.c
++++ b/fs/smb/client/smb2misc.c
+@@ -19,7 +19,8 @@
+ #include "nterr.h"
+ #include "cached_dir.h"
+-static unsigned int __smb2_calc_size(void *buf, bool *have_data);
++static unsigned int __smb2_calc_size(void *buf, bool *have_data,
++                                   bool *data_area_overlap);
+ static int
+ check_smb2_hdr(struct smb2_hdr *shdr, __u64 mid)
+@@ -148,6 +149,7 @@ smb2_check_message(char *buf, unsigned i
+       __u32 calc_len; /* calculated length */
+       __u64 mid;
+       bool have_data;
++      bool data_area_overlap;
+       /* If server is a channel, select the primary channel */
+       pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
+@@ -232,7 +234,12 @@ smb2_check_message(char *buf, unsigned i
+       }
+       have_data = false;
+-      calc_len = __smb2_calc_size(buf, &have_data);
++      data_area_overlap = false;
++      calc_len = __smb2_calc_size(buf, &have_data, &data_area_overlap);
++
++      /* Reject responses whose data area overlaps the fixed area. */
++      if (data_area_overlap)
++              return 1;
+       /* For SMB2_IOCTL, OutputOffset and OutputLength are optional, so might
+        * be 0, and not a real miscalculation */
+@@ -416,14 +423,15 @@ smb2_get_data_area_len(int *off, int *le
+ }
+ /*
+- * Calculate the size of the SMB message based on the fixed header
+- * portion, the number of word parameters and the data portion of the message.
+- * If have_data is non-NULL, it is set to true when a non-empty data area was
+- * found (data_length > 0), allowing callers to distinguish the implied bcc[0]
+- * case (no data area) from an overreported data length.
++ * Calculate the size of the SMB message based on the fixed header, fixed
++ * parameter area, and variable data area.
++ *
++ * If have_data is not NULL, it is set when a non-empty data area is found.
++ * If data_area_overlap is not NULL, it is set when the data area overlaps
++ * the fixed area.
+  */
+ static unsigned int
+-__smb2_calc_size(void *buf, bool *have_data)
++__smb2_calc_size(void *buf, bool *have_data, bool *data_area_overlap)
+ {
+       struct smb2_pdu *pdu = buf;
+       struct smb2_hdr *shdr = &pdu->hdr;
+@@ -432,6 +440,11 @@ __smb2_calc_size(void *buf, bool *have_d
+       /* Structure Size has already been checked to make sure it is 64 */
+       int len = le16_to_cpu(shdr->StructureSize);
++      if (have_data)
++              *have_data = false;
++      if (data_area_overlap)
++              *data_area_overlap = false;
++
+       /*
+        * StructureSize2, ie length of fixed parameter area has already
+        * been checked to make sure it is the correct length.
+@@ -454,7 +467,10 @@ __smb2_calc_size(void *buf, bool *have_d
+               if (offset + 1 < len) {
+                       cifs_dbg(VFS, "data area offset %d overlaps SMB2 header %d\n",
+                                offset + 1, len);
++                      if (data_area_overlap)
++                              *data_area_overlap = true;
+                       data_length = 0;
++                      goto calc_size_exit;
+               } else {
+                       len = offset + data_length;
+               }
+@@ -469,7 +485,7 @@ calc_size_exit:
+ unsigned int
+ smb2_calc_size(void *buf)
+ {
+-      return __smb2_calc_size(buf, NULL);
++      return __smb2_calc_size(buf, NULL, NULL);
+ }
+ /* Note: caller must free return buffer */