From: Greg Kroah-Hartman Date: Fri, 17 Jul 2026 07:40:23 +0000 (+0200) Subject: 6.1-stable patches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3f3036c0380073fb706236e487972e5de4ba7dd1;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: smb-client-reject-overlapping-data-areas-in-smb2-responses.patch --- diff --git a/queue-6.1/smb-client-reject-overlapping-data-areas-in-smb2-responses.patch b/queue-6.1/smb-client-reject-overlapping-data-areas-in-smb2-responses.patch new file mode 100644 index 0000000000..99320234f5 --- /dev/null +++ b/queue-6.1/smb-client-reject-overlapping-data-areas-in-smb2-responses.patch @@ -0,0 +1,116 @@ +From 8986c932905ea508d66da421eb2eb6e676ace1fe Mon Sep 17 00:00:00 2001 +From: Shoichiro Miyamoto +Date: Sat, 11 Jul 2026 22:33:26 +0900 +Subject: smb: client: reject overlapping data areas in SMB2 responses + +From: Shoichiro Miyamoto + +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 +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -18,7 +18,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) +@@ -146,6 +147,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 = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server; +@@ -230,7 +232,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 */ +@@ -414,14 +421,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; +@@ -430,6 +438,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. +@@ -452,7 +465,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; + } +@@ -467,7 +483,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 */