* FAILED: patch "[PATCH] ksmbd: validate minimum PDU size for transform requests" failed to apply to 6.6-stable tree
@ 2026-07-29 13:55 gregkh
2026-08-09 1:21 ` [PATCH 6.6.y 1/7] smb: move smb_version_values to common/smbglob.h Sasha Levin
0 siblings, 1 reply; 8+ messages in thread
From: gregkh @ 2026-07-29 13:55 UTC (permalink / raw)
To: linkinjeon, stfrench; +Cc: stable
The patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x cfc0b8e5080aec87700774e8568765eaa4b7b92b
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026072925-unloaded-borough-0d66@gregkh' --subject-prefix 'PATCH 6.6.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From cfc0b8e5080aec87700774e8568765eaa4b7b92b Mon Sep 17 00:00:00 2001
From: Namjae Jeon <linkinjeon@kernel.org>
Date: Sat, 4 Jul 2026 11:30:27 +0900
Subject: [PATCH] ksmbd: validate minimum PDU size for transform requests
The receive path applies the minimum SMB2 PDU size check only when
ProtocolId is SMB2_PROTO_NUMBER. A packet carrying
SMB2_TRANSFORM_PROTO_NUM bypasses the check even when the negotiated
dialect does not provide transform handling.
On an SMB 2.1 connection, a short transform packet therefore reaches
init_smb2_rsp_hdr(), which interprets the request as a full SMB2 header
and reads beyond the request allocation. The copied fields can then be
returned to the unauthenticated client.
Compression transforms are converted to ordinary SMB2 messages before
protocol validation. After that conversion, validate ordinary SMB2
requests against SMB2_MIN_SUPPORTED_PDU_SIZE and require encryption
transform requests to contain both a transform header and an SMB2
header. This rejects truncated requests before work allocation.
Fixes: 368ba06881c3 ("ksmbd: check the validation of pdu_size in ksmbd_conn_handler_loop")
Cc: stable@vger.kernel.org
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-31063
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c
index 9e8fdb39e5a2..dee8e4aced99 100644
--- a/fs/smb/server/connection.c
+++ b/fs/smb/server/connection.c
@@ -441,6 +441,8 @@ bool ksmbd_conn_alive(struct ksmbd_conn *conn)
/* "+2" for BCC field (ByteCount, 2 bytes) */
#define SMB1_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb_hdr) + 2)
#define SMB2_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb2_pdu))
+#define SMB2_TRANSFORM_MIN_SUPPORTED_PDU_SIZE \
+ (sizeof(struct smb2_transform_hdr) + sizeof(struct smb2_hdr))
/**
* ksmbd_conn_handler_loop() - session thread to listen on new smb requests
@@ -455,6 +457,7 @@ int ksmbd_conn_handler_loop(void *p)
struct ksmbd_conn *conn = (struct ksmbd_conn *)p;
struct ksmbd_transport *t = conn->transport;
unsigned int pdu_size, max_allowed_pdu_size, max_req;
+ __le32 proto;
char hdr_buf[4] = {0,};
int size;
@@ -546,11 +549,14 @@ int ksmbd_conn_handler_loop(void *p)
if (!ksmbd_smb_request(conn))
break;
- if (((struct smb2_hdr *)smb_get_msg(conn->request_buf))->ProtocolId ==
- SMB2_PROTO_NUMBER) {
- if (pdu_size < SMB2_MIN_SUPPORTED_PDU_SIZE)
- break;
- }
+ proto = *(__le32 *)smb_get_msg(conn->request_buf);
+ if (proto == SMB2_PROTO_NUMBER &&
+ pdu_size < SMB2_MIN_SUPPORTED_PDU_SIZE)
+ break;
+
+ if (proto == SMB2_TRANSFORM_PROTO_NUM &&
+ pdu_size < SMB2_TRANSFORM_MIN_SUPPORTED_PDU_SIZE)
+ break;
if (!default_conn_ops.process_fn) {
pr_err("No connection request callback\n");
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6.6.y 1/7] smb: move smb_version_values to common/smbglob.h
2026-07-29 13:55 FAILED: patch "[PATCH] ksmbd: validate minimum PDU size for transform requests" failed to apply to 6.6-stable tree gregkh
@ 2026-08-09 1:21 ` Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 2/7] smb: move get_rfc1002_len() " Sasha Levin
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Sasha Levin @ 2026-08-09 1:21 UTC (permalink / raw)
To: stable; +Cc: ZhangGuoDong, ChenXiaoSong, Namjae Jeon, Steve French,
Sasha Levin
From: ZhangGuoDong <zhangguodong@kylinos.cn>
[ Upstream commit 34cf191bb6a349dc88ec2c4f6355fe006ac669e0 ]
Merge the struct members of the server and the client:
- req_capabilities: from client
- header_preamble_size: from client
- cap_unicode: from client
- capabilities: from server, rename to req_capabilities
- max_read_size: from server
- max_write_size: from server
- max_trans_size: from server
- max_credits: from server
- create_durable_size: from server
- create_durable_v2_size: from server
- create_mxac_size: from server
- create_disk_id_size: from server
- create_posix_size: from server
Then move duplicate definitions to common header file.
Co-developed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: ZhangGuoDong <zhangguodong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: cfc0b8e5080a ("ksmbd: validate minimum PDU size for transform requests")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifsglob.h | 21 ---------------------
fs/smb/common/cifsglob.h | 31 +++++++++++++++++++++++++++++++
fs/smb/server/smb2misc.c | 2 +-
fs/smb/server/smb2ops.c | 32 ++++++++++++++++----------------
fs/smb/server/smb2pdu.c | 10 +++++-----
fs/smb/server/smb_common.h | 29 -----------------------------
6 files changed, 53 insertions(+), 72 deletions(-)
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 97f70d437a7eb..2c34ac9c57f8c 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -606,27 +606,6 @@ struct smb_version_operations {
const char *symname);
};
-struct smb_version_values {
- char *version_string;
- __u16 protocol_id;
- __u32 req_capabilities;
- __u32 large_lock_type;
- __u32 exclusive_lock_type;
- __u32 shared_lock_type;
- __u32 unlock_lock_type;
- size_t header_preamble_size;
- size_t header_size;
- size_t max_header_size;
- size_t read_rsp_size;
- __le16 lock_cmd;
- unsigned int cap_unix;
- unsigned int cap_nt_find;
- unsigned int cap_large_files;
- __u16 signing_enabled;
- __u16 signing_required;
- size_t create_lease_size;
-};
-
#define HEADER_SIZE(server) (server->vals->header_size)
#define MAX_HEADER_SIZE(server) (server->vals->max_header_size)
#define HEADER_PREAMBLE_SIZE(server) (server->vals->header_preamble_size)
diff --git a/fs/smb/common/cifsglob.h b/fs/smb/common/cifsglob.h
index 00fd215e3eb54..eda5e666a7617 100644
--- a/fs/smb/common/cifsglob.h
+++ b/fs/smb/common/cifsglob.h
@@ -9,6 +9,37 @@
#ifndef _COMMON_CIFS_GLOB_H
#define _COMMON_CIFS_GLOB_H
+struct smb_version_values {
+ char *version_string;
+ __u16 protocol_id;
+ __le16 lock_cmd;
+ __u32 req_capabilities;
+ __u32 max_read_size;
+ __u32 max_write_size;
+ __u32 max_trans_size;
+ __u32 max_credits;
+ __u32 large_lock_type;
+ __u32 exclusive_lock_type;
+ __u32 shared_lock_type;
+ __u32 unlock_lock_type;
+ size_t header_preamble_size;
+ size_t header_size;
+ size_t max_header_size;
+ size_t read_rsp_size;
+ unsigned int cap_unix;
+ unsigned int cap_nt_find;
+ unsigned int cap_large_files;
+ unsigned int cap_unicode;
+ __u16 signing_enabled;
+ __u16 signing_required;
+ size_t create_lease_size;
+ size_t create_durable_size;
+ size_t create_durable_v2_size;
+ size_t create_mxac_size;
+ size_t create_disk_id_size;
+ size_t create_posix_size;
+};
+
static inline void inc_rfc1001_len(void *buf, int count)
{
be32_add_cpu((__be32 *)buf, count);
diff --git a/fs/smb/server/smb2misc.c b/fs/smb/server/smb2misc.c
index ffbddf00d24e9..6a4f1b8a0b13c 100644
--- a/fs/smb/server/smb2misc.c
+++ b/fs/smb/server/smb2misc.c
@@ -465,7 +465,7 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
}
validate_credit:
- if ((work->conn->vals->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) &&
+ if ((work->conn->vals->req_capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) &&
smb2_validate_credit_charge(work->conn, hdr))
return 1;
diff --git a/fs/smb/server/smb2ops.c b/fs/smb/server/smb2ops.c
index 606aa3c5189a2..bcf05caa2304d 100644
--- a/fs/smb/server/smb2ops.c
+++ b/fs/smb/server/smb2ops.c
@@ -15,7 +15,7 @@
static struct smb_version_values smb21_server_values = {
.version_string = SMB21_VERSION_STRING,
.protocol_id = SMB21_PROT_ID,
- .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
+ .req_capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
.max_read_size = SMB21_DEFAULT_IOSIZE,
.max_write_size = SMB21_DEFAULT_IOSIZE,
.max_trans_size = SMB21_DEFAULT_IOSIZE,
@@ -41,7 +41,7 @@ static struct smb_version_values smb21_server_values = {
static struct smb_version_values smb30_server_values = {
.version_string = SMB30_VERSION_STRING,
.protocol_id = SMB30_PROT_ID,
- .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
+ .req_capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
.max_read_size = SMB3_DEFAULT_IOSIZE,
.max_write_size = SMB3_DEFAULT_IOSIZE,
.max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
@@ -68,7 +68,7 @@ static struct smb_version_values smb30_server_values = {
static struct smb_version_values smb302_server_values = {
.version_string = SMB302_VERSION_STRING,
.protocol_id = SMB302_PROT_ID,
- .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
+ .req_capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
.max_read_size = SMB3_DEFAULT_IOSIZE,
.max_write_size = SMB3_DEFAULT_IOSIZE,
.max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
@@ -95,7 +95,7 @@ static struct smb_version_values smb302_server_values = {
static struct smb_version_values smb311_server_values = {
.version_string = SMB311_VERSION_STRING,
.protocol_id = SMB311_PROT_ID,
- .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
+ .req_capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
.max_read_size = SMB3_DEFAULT_IOSIZE,
.max_write_size = SMB3_DEFAULT_IOSIZE,
.max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
@@ -204,7 +204,7 @@ void init_smb2_1_server(struct ksmbd_conn *conn)
conn->signing_algorithm = SIGNING_ALG_HMAC_SHA256_LE;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_LEASING;
}
/**
@@ -221,20 +221,20 @@ void init_smb3_0_server(struct ksmbd_conn *conn)
conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_LEASING |
SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION &&
conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
(!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
}
/**
@@ -251,19 +251,19 @@ void init_smb3_02_server(struct ksmbd_conn *conn)
conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_LEASING |
SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
(!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES;
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES;
}
/**
@@ -280,14 +280,14 @@ int init_smb3_11_server(struct ksmbd_conn *conn)
conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_LEASING |
SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES;
+ conn->vals->req_capabilities |= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES;
INIT_LIST_HEAD(&conn->preauth_sess_table);
return 0;
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 41bc4b06fad08..bc779472cffde 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -284,7 +284,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work)
/* Not setting conn guid rsp->ServerGUID, as it
* not used by client for identifying connection
*/
- rsp->Capabilities = cpu_to_le32(conn->vals->capabilities);
+ rsp->Capabilities = cpu_to_le32(conn->vals->req_capabilities);
/* Default Max Message Size till SMB2.0, 64K*/
rsp->MaxTransactSize = cpu_to_le32(conn->vals->max_trans_size);
rsp->MaxReadSize = cpu_to_le32(conn->vals->max_read_size);
@@ -963,7 +963,7 @@ bool smb3_encryption_negotiated(struct ksmbd_conn *conn)
* SMB 3.0 and 3.0.2 dialects use the SMB2_GLOBAL_CAP_ENCRYPTION flag.
* SMB 3.1.1 uses the cipher_type field.
*/
- return (conn->vals->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) ||
+ return (conn->vals->req_capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) ||
conn->cipher_type;
}
@@ -1216,7 +1216,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
rc = -EINVAL;
goto err_out;
}
- rsp->Capabilities = cpu_to_le32(conn->vals->capabilities);
+ rsp->Capabilities = cpu_to_le32(conn->vals->req_capabilities);
/* For stats */
conn->connection_type = conn->dialect;
@@ -3480,7 +3480,7 @@ int smb2_open(struct ksmbd_work *work)
share_ret = ksmbd_smb_check_shared_mode(fp->filp, fp);
if (!test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_OPLOCKS) ||
(req_op_level == SMB2_OPLOCK_LEVEL_LEASE &&
- !(conn->vals->capabilities & SMB2_GLOBAL_CAP_LEASING))) {
+ !(conn->vals->req_capabilities & SMB2_GLOBAL_CAP_LEASING))) {
if (share_ret < 0 && !S_ISDIR(file_inode(fp->filp)->i_mode)) {
rc = share_ret;
goto err_out1;
@@ -8081,7 +8081,7 @@ static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn,
goto err_out;
}
- neg_rsp->Capabilities = cpu_to_le32(conn->vals->capabilities);
+ neg_rsp->Capabilities = cpu_to_le32(conn->vals->req_capabilities);
memset(neg_rsp->Guid, 0, SMB2_CLIENT_GUID_SIZE);
neg_rsp->SecurityMode = cpu_to_le16(conn->srv_sec_mode);
neg_rsp->Dialect = cpu_to_le16(conn->dialect);
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index 3f274af060dab..a364bf319a46d 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -336,35 +336,6 @@ struct file_id_full_dir_info {
char FileName[];
} __packed; /* level 0x105 FF rsp data */
-struct smb_version_values {
- char *version_string;
- __u16 protocol_id;
- __le16 lock_cmd;
- __u32 capabilities;
- __u32 max_read_size;
- __u32 max_write_size;
- __u32 max_trans_size;
- __u32 max_credits;
- __u32 large_lock_type;
- __u32 exclusive_lock_type;
- __u32 shared_lock_type;
- __u32 unlock_lock_type;
- size_t header_size;
- size_t max_header_size;
- size_t read_rsp_size;
- unsigned int cap_unix;
- unsigned int cap_nt_find;
- unsigned int cap_large_files;
- __u16 signing_enabled;
- __u16 signing_required;
- size_t create_lease_size;
- size_t create_durable_size;
- size_t create_durable_v2_size;
- size_t create_mxac_size;
- size_t create_disk_id_size;
- size_t create_posix_size;
-};
-
struct filesystem_posix_info {
/* For undefined recommended transfer size return -1 in that field */
__le32 OptimalTransferSize; /* bsize on some os, iosize on other os */
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6.6.y 2/7] smb: move get_rfc1002_len() to common/smbglob.h
2026-08-09 1:21 ` [PATCH 6.6.y 1/7] smb: move smb_version_values to common/smbglob.h Sasha Levin
@ 2026-08-09 1:21 ` Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 3/7] smb/server: rename include guard in smb_common.h Sasha Levin
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-08-09 1:21 UTC (permalink / raw)
To: stable; +Cc: ZhangGuoDong, ChenXiaoSong, Namjae Jeon, Steve French,
Sasha Levin
From: ZhangGuoDong <zhangguodong@kylinos.cn>
[ Upstream commit 36c31540cf5279262bfd148d8537cd04866499f2 ]
Rename get_rfc1002_length() to get_rfc1002_len(), then move duplicate
definitions to common header file.
Co-developed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: ZhangGuoDong <zhangguodong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: cfc0b8e5080a ("ksmbd: validate minimum PDU size for transform requests")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifsglob.h | 6 ------
fs/smb/client/cifssmb.c | 6 +++---
fs/smb/client/connect.c | 2 +-
fs/smb/client/transport.c | 8 ++++----
fs/smb/common/cifsglob.h | 5 +++++
fs/smb/server/smb_common.h | 5 -----
6 files changed, 13 insertions(+), 19 deletions(-)
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 2c34ac9c57f8c..a4e0618c58efc 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -643,12 +643,6 @@ struct cifs_mnt_data {
int flags;
};
-static inline unsigned int
-get_rfc1002_length(void *buf)
-{
- return be32_to_cpu(*((__be32 *)buf)) & 0xffffff;
-}
-
struct TCP_Server_Info {
struct list_head tcp_ses_list;
struct list_head smb_ses_list;
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 91f4e50af1e94..f83a30004a6b4 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -595,7 +595,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
iov[0].iov_len = 4;
iov[0].iov_base = smb;
- iov[1].iov_len = get_rfc1002_length(smb);
+ iov[1].iov_len = get_rfc1002_len(smb);
iov[1].iov_base = (char *)smb + 4;
rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
@@ -1363,7 +1363,7 @@ cifs_async_readv(struct cifs_readdata *rdata)
rdata->iov[0].iov_base = smb;
rdata->iov[0].iov_len = 4;
rdata->iov[1].iov_base = (char *)smb + 4;
- rdata->iov[1].iov_len = get_rfc1002_length(smb);
+ rdata->iov[1].iov_len = get_rfc1002_len(smb);
kref_get(&rdata->refcount);
rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
@@ -1703,7 +1703,7 @@ cifs_async_writev(struct cifs_writedata *wdata,
/* 4 for RFC1001 length + 1 for BCC */
iov[0].iov_len = 4;
iov[0].iov_base = smb;
- iov[1].iov_len = get_rfc1002_length(smb) + 1;
+ iov[1].iov_len = get_rfc1002_len(smb) + 1;
iov[1].iov_base = (char *)smb + 4;
rqst.rq_iov = iov;
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index fe5d21f174c47..68a000956d957 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1230,7 +1230,7 @@ cifs_demultiplex_thread(void *p)
* The right amount was read from socket - 4 bytes,
* so we can now interpret the length field.
*/
- pdu_length = get_rfc1002_length(buf);
+ pdu_length = get_rfc1002_len(buf);
cifs_dbg(FYI, "RFC1002 header 0x%x\n", pdu_length);
if (!is_smb_response(server, buf[0]))
diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index 1eb25603b6e83..a47242a0f5c6d 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -882,7 +882,7 @@ SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
int resp_buf_type;
iov[0].iov_base = in_buf;
- iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
+ iov[0].iov_len = get_rfc1002_len(in_buf) + 4;
flags |= CIFS_NO_RSP_BUF;
rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov);
cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc);
@@ -942,7 +942,7 @@ int
cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
bool log_error)
{
- unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
+ unsigned int len = get_rfc1002_len(mid->resp_buf) + 4;
dump_smb(mid->resp_buf, min_t(u32, 92, len));
@@ -1462,7 +1462,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
goto out;
}
- *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
+ *pbytes_returned = get_rfc1002_len(midQ->resp_buf);
memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
rc = cifs_check_receive(midQ, server, 0);
out:
@@ -1647,7 +1647,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
goto out;
}
- *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
+ *pbytes_returned = get_rfc1002_len(midQ->resp_buf);
memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
rc = cifs_check_receive(midQ, server, 0);
out:
diff --git a/fs/smb/common/cifsglob.h b/fs/smb/common/cifsglob.h
index eda5e666a7617..371160fec1cdf 100644
--- a/fs/smb/common/cifsglob.h
+++ b/fs/smb/common/cifsglob.h
@@ -40,6 +40,11 @@ struct smb_version_values {
size_t create_posix_size;
};
+static inline unsigned int get_rfc1002_len(void *buf)
+{
+ return be32_to_cpu(*((__be32 *)buf)) & 0xffffff;
+}
+
static inline void inc_rfc1001_len(void *buf, int count)
{
be32_add_cpu((__be32 *)buf, count);
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index a364bf319a46d..612139bdc91b0 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -421,9 +421,4 @@ unsigned int ksmbd_server_side_copy_max_chunk_size(void);
unsigned int ksmbd_server_side_copy_max_total_size(void);
bool is_asterisk(char *p);
__le32 smb_map_generic_desired_access(__le32 daccess);
-
-static inline unsigned int get_rfc1002_len(void *buf)
-{
- return be32_to_cpu(*((__be32 *)buf)) & 0xffffff;
-}
#endif /* __SMB_COMMON_H__ */
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6.6.y 3/7] smb/server: rename include guard in smb_common.h
2026-08-09 1:21 ` [PATCH 6.6.y 1/7] smb: move smb_version_values to common/smbglob.h Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 2/7] smb: move get_rfc1002_len() " Sasha Levin
@ 2026-08-09 1:21 ` Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 4/7] ksmbd: rename smb2_get_msg to smb_get_msg Sasha Levin
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-08-09 1:21 UTC (permalink / raw)
To: stable; +Cc: ChenXiaoSong, Namjae Jeon, Steve French, Sasha Levin
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
[ Upstream commit 01ab0d1640e379f0a0d6602250b33ff2b45e9560 ]
Make the include guard more descriptive to avoid conflicts with include
guards that may be used in the future.
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: cfc0b8e5080a ("ksmbd: validate minimum PDU size for transform requests")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb_common.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index 612139bdc91b0..26f8c268ece99 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -3,8 +3,8 @@
* Copyright (C) 2018 Samsung Electronics Co., Ltd.
*/
-#ifndef __SMB_COMMON_H__
-#define __SMB_COMMON_H__
+#ifndef __SMB_SERVER_COMMON_H__
+#define __SMB_SERVER_COMMON_H__
#include <linux/kernel.h>
@@ -421,4 +421,4 @@ unsigned int ksmbd_server_side_copy_max_chunk_size(void);
unsigned int ksmbd_server_side_copy_max_total_size(void);
bool is_asterisk(char *p);
__le32 smb_map_generic_desired_access(__le32 daccess);
-#endif /* __SMB_COMMON_H__ */
+#endif /* __SMB_SERVER_COMMON_H__ */
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6.6.y 4/7] ksmbd: rename smb2_get_msg to smb_get_msg
2026-08-09 1:21 ` [PATCH 6.6.y 1/7] smb: move smb_version_values to common/smbglob.h Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 2/7] smb: move get_rfc1002_len() " Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 3/7] smb/server: rename include guard in smb_common.h Sasha Levin
@ 2026-08-09 1:21 ` Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 5/7] smb/server: fix minimum SMB1 PDU size Sasha Levin
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-08-09 1:21 UTC (permalink / raw)
To: stable; +Cc: Namjae Jeon, Steve French, Sasha Levin
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 0b444cfd8b74ebce421ccd96eac9c495e536c92e ]
With the removal of the RFC1002 length field from the SMB header,
smb2_get_msg is now used to get the smb1 request from the request buffer.
Since this function is no longer exclusive to smb2 and now supports smb1
as well, This patch rename it to smb_get_msg to better reflect its usage.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: cfc0b8e5080a ("ksmbd: validate minimum PDU size for transform requests")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/auth.c | 4 +--
fs/smb/server/connection.c | 2 +-
fs/smb/server/oplock.c | 8 ++---
fs/smb/server/smb2pdu.c | 70 +++++++++++++++++++-------------------
fs/smb/server/smb2pdu.h | 9 -----
fs/smb/server/smb_common.c | 6 ++--
fs/smb/server/smb_common.h | 9 +++++
7 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c
index 825cc03692754..bb8332caa9a71 100644
--- a/fs/smb/server/auth.c
+++ b/fs/smb/server/auth.c
@@ -920,7 +920,7 @@ int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
__u8 *pi_hash)
{
int rc;
- struct smb2_hdr *rcv_hdr = smb2_get_msg(buf);
+ struct smb2_hdr *rcv_hdr = smb_get_msg(buf);
char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
int msg_size = get_rfc1002_len(buf);
struct ksmbd_crypto_ctx *ctx = NULL;
@@ -1107,7 +1107,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
unsigned int nvec, int enc)
{
struct ksmbd_conn *conn = work->conn;
- struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
+ struct smb2_transform_hdr *tr_hdr = smb_get_msg(iov[0].iov_base);
unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
int rc;
DECLARE_CRYPTO_WAIT(wait);
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c
index cdc1edeefeb33..82bad1745a507 100644
--- a/fs/smb/server/connection.c
+++ b/fs/smb/server/connection.c
@@ -475,7 +475,7 @@ int ksmbd_conn_handler_loop(void *p)
if (!ksmbd_smb_request(conn))
break;
- if (((struct smb2_hdr *)smb2_get_msg(conn->request_buf))->ProtocolId ==
+ if (((struct smb2_hdr *)smb_get_msg(conn->request_buf))->ProtocolId ==
SMB2_PROTO_NUMBER) {
if (pdu_size < SMB2_MIN_SUPPORTED_HEADER_SIZE)
break;
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
index 109bb71d06adf..6f595756c41fd 100644
--- a/fs/smb/server/oplock.c
+++ b/fs/smb/server/oplock.c
@@ -663,7 +663,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
goto out;
}
- rsp_hdr = smb2_get_msg(work->response_buf);
+ rsp_hdr = smb_get_msg(work->response_buf);
memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER;
rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE;
@@ -677,7 +677,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
rsp_hdr->SessionId = 0;
memset(rsp_hdr->Signature, 0, 16);
- rsp = smb2_get_msg(work->response_buf);
+ rsp = smb_get_msg(work->response_buf);
rsp->StructureSize = cpu_to_le16(24);
if (!br_info->open_trunc &&
@@ -776,7 +776,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
goto out;
}
- rsp_hdr = smb2_get_msg(work->response_buf);
+ rsp_hdr = smb_get_msg(work->response_buf);
memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER;
rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE;
@@ -790,7 +790,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
rsp_hdr->SessionId = 0;
memset(rsp_hdr->Signature, 0, 16);
- rsp = smb2_get_msg(work->response_buf);
+ rsp = smb_get_msg(work->response_buf);
rsp->StructureSize = cpu_to_le16(44);
rsp->Epoch = br_info->epoch;
rsp->Flags = 0;
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index bc779472cffde..35994fb28bbb5 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -47,8 +47,8 @@ static void __wbuf(struct ksmbd_work *work, void **req, void **rsp)
*req = ksmbd_req_buf_next(work);
*rsp = ksmbd_resp_buf_next(work);
} else {
- *req = smb2_get_msg(work->request_buf);
- *rsp = smb2_get_msg(work->response_buf);
+ *req = smb_get_msg(work->request_buf);
+ *rsp = smb_get_msg(work->response_buf);
}
}
@@ -148,7 +148,7 @@ void smb2_set_err_rsp(struct ksmbd_work *work)
if (work->next_smb2_rcv_hdr_off)
err_rsp = ksmbd_resp_buf_next(work);
else
- err_rsp = smb2_get_msg(work->response_buf);
+ err_rsp = smb_get_msg(work->response_buf);
if (err_rsp->hdr.Status != STATUS_STOPPED_ON_SYMLINK) {
int err;
@@ -174,7 +174,7 @@ void smb2_set_err_rsp(struct ksmbd_work *work)
*/
bool is_smb2_neg_cmd(struct ksmbd_work *work)
{
- struct smb2_hdr *hdr = smb2_get_msg(work->request_buf);
+ struct smb2_hdr *hdr = smb_get_msg(work->request_buf);
/* is it SMB2 header ? */
if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
@@ -198,7 +198,7 @@ bool is_smb2_neg_cmd(struct ksmbd_work *work)
*/
bool is_smb2_rsp(struct ksmbd_work *work)
{
- struct smb2_hdr *hdr = smb2_get_msg(work->response_buf);
+ struct smb2_hdr *hdr = smb_get_msg(work->response_buf);
/* is it SMB2 header ? */
if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
@@ -224,7 +224,7 @@ u16 get_smb2_cmd_val(struct ksmbd_work *work)
if (work->next_smb2_rcv_hdr_off)
rcv_hdr = ksmbd_req_buf_next(work);
else
- rcv_hdr = smb2_get_msg(work->request_buf);
+ rcv_hdr = smb_get_msg(work->request_buf);
return le16_to_cpu(rcv_hdr->Command);
}
@@ -237,7 +237,7 @@ void set_smb2_rsp_status(struct ksmbd_work *work, __le32 err)
{
struct smb2_hdr *rsp_hdr;
- rsp_hdr = smb2_get_msg(work->response_buf);
+ rsp_hdr = smb_get_msg(work->response_buf);
rsp_hdr->Status = err;
work->iov_idx = 0;
@@ -260,7 +260,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work)
struct ksmbd_conn *conn = work->conn;
int err;
- rsp_hdr = smb2_get_msg(work->response_buf);
+ rsp_hdr = smb_get_msg(work->response_buf);
memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER;
rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE;
@@ -274,7 +274,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work)
rsp_hdr->SessionId = 0;
memset(rsp_hdr->Signature, 0, 16);
- rsp = smb2_get_msg(work->response_buf);
+ rsp = smb_get_msg(work->response_buf);
WARN_ON(ksmbd_conn_good(conn));
@@ -448,7 +448,7 @@ static void init_chained_smb2_rsp(struct ksmbd_work *work)
*/
bool is_chained_smb2_message(struct ksmbd_work *work)
{
- struct smb2_hdr *hdr = smb2_get_msg(work->request_buf);
+ struct smb2_hdr *hdr = smb_get_msg(work->request_buf);
unsigned int len, next_cmd;
if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
@@ -499,8 +499,8 @@ bool is_chained_smb2_message(struct ksmbd_work *work)
*/
int init_smb2_rsp_hdr(struct ksmbd_work *work)
{
- struct smb2_hdr *rsp_hdr = smb2_get_msg(work->response_buf);
- struct smb2_hdr *rcv_hdr = smb2_get_msg(work->request_buf);
+ struct smb2_hdr *rsp_hdr = smb_get_msg(work->response_buf);
+ struct smb2_hdr *rcv_hdr = smb_get_msg(work->request_buf);
memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
rsp_hdr->ProtocolId = rcv_hdr->ProtocolId;
@@ -529,7 +529,7 @@ int init_smb2_rsp_hdr(struct ksmbd_work *work)
*/
int smb2_allocate_rsp_buf(struct ksmbd_work *work)
{
- struct smb2_hdr *hdr = smb2_get_msg(work->request_buf);
+ struct smb2_hdr *hdr = smb_get_msg(work->request_buf);
size_t small_sz = MAX_CIFS_SMALL_BUFFER_SIZE;
size_t large_sz = small_sz + work->conn->vals->max_trans_size;
size_t sz = small_sz;
@@ -545,7 +545,7 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work)
offsetof(struct smb2_query_info_req, OutputBufferLength))
return -EINVAL;
- req = smb2_get_msg(work->request_buf);
+ req = smb_get_msg(work->request_buf);
if ((req->InfoType == SMB2_O_INFO_FILE &&
(req->FileInfoClass == FILE_FULL_EA_INFORMATION ||
req->FileInfoClass == FILE_ALL_INFORMATION)) ||
@@ -719,10 +719,10 @@ void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status)
}
in_work->conn = work->conn;
- memcpy(smb2_get_msg(in_work->response_buf), ksmbd_resp_buf_next(work),
+ memcpy(smb_get_msg(in_work->response_buf), ksmbd_resp_buf_next(work),
__SMB2_HEADER_STRUCTURE_SIZE);
- rsp_hdr = smb2_get_msg(in_work->response_buf);
+ rsp_hdr = smb_get_msg(in_work->response_buf);
rsp_hdr->Flags |= SMB2_FLAGS_ASYNC_COMMAND;
rsp_hdr->Id.AsyncId = cpu_to_le64(work->async_id);
smb2_set_err_rsp(in_work);
@@ -1100,8 +1100,8 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
int smb2_handle_negotiate(struct ksmbd_work *work)
{
struct ksmbd_conn *conn = work->conn;
- struct smb2_negotiate_req *req = smb2_get_msg(work->request_buf);
- struct smb2_negotiate_rsp *rsp = smb2_get_msg(work->response_buf);
+ struct smb2_negotiate_req *req = smb_get_msg(work->request_buf);
+ struct smb2_negotiate_rsp *rsp = smb_get_msg(work->response_buf);
int rc = 0;
unsigned int smb2_buf_len, smb2_neg_size, neg_ctxt_len = 0;
__le32 status;
@@ -6048,7 +6048,7 @@ int smb2_close(struct ksmbd_work *work)
*/
int smb2_echo(struct ksmbd_work *work)
{
- struct smb2_echo_rsp *rsp = smb2_get_msg(work->response_buf);
+ struct smb2_echo_rsp *rsp = smb_get_msg(work->response_buf);
if (work->next_smb2_rcv_hdr_off)
rsp = ksmbd_resp_buf_next(work);
@@ -6614,8 +6614,8 @@ int smb2_set_info(struct ksmbd_work *work)
pid = work->compound_pfid;
}
} else {
- req = smb2_get_msg(work->request_buf);
- rsp = smb2_get_msg(work->response_buf);
+ req = smb_get_msg(work->request_buf);
+ rsp = smb_get_msg(work->response_buf);
}
if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
@@ -6841,8 +6841,8 @@ int smb2_read(struct ksmbd_work *work)
pid = work->compound_pfid;
}
} else {
- req = smb2_get_msg(work->request_buf);
- rsp = smb2_get_msg(work->response_buf);
+ req = smb_get_msg(work->request_buf);
+ rsp = smb_get_msg(work->response_buf);
}
if (!has_file_id(id)) {
@@ -7260,7 +7260,7 @@ int smb2_flush(struct ksmbd_work *work)
int smb2_cancel(struct ksmbd_work *work)
{
struct ksmbd_conn *conn = work->conn;
- struct smb2_hdr *hdr = smb2_get_msg(work->request_buf);
+ struct smb2_hdr *hdr = smb_get_msg(work->request_buf);
struct smb2_hdr *chdr;
struct ksmbd_work *iter;
struct list_head *command_list;
@@ -7277,7 +7277,7 @@ int smb2_cancel(struct ksmbd_work *work)
spin_lock(&conn->request_lock);
list_for_each_entry(iter, command_list,
async_request_entry) {
- chdr = smb2_get_msg(iter->request_buf);
+ chdr = smb_get_msg(iter->request_buf);
if (iter->async_id !=
le64_to_cpu(hdr->Id.AsyncId))
@@ -7309,7 +7309,7 @@ int smb2_cancel(struct ksmbd_work *work)
spin_lock(&conn->request_lock);
list_for_each_entry(iter, command_list, request_entry) {
- chdr = smb2_get_msg(iter->request_buf);
+ chdr = smb_get_msg(iter->request_buf);
if (chdr->MessageId != hdr->MessageId ||
iter == work)
@@ -8265,8 +8265,8 @@ int smb2_ioctl(struct ksmbd_work *work)
id = work->compound_fid;
}
} else {
- req = smb2_get_msg(work->request_buf);
- rsp = smb2_get_msg(work->response_buf);
+ req = smb_get_msg(work->request_buf);
+ rsp = smb_get_msg(work->response_buf);
}
if (!has_file_id(id))
@@ -8948,7 +8948,7 @@ int smb2_notify(struct ksmbd_work *work)
*/
bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command)
{
- struct smb2_hdr *rcv_hdr2 = smb2_get_msg(work->request_buf);
+ struct smb2_hdr *rcv_hdr2 = smb_get_msg(work->request_buf);
if ((rcv_hdr2->Flags & SMB2_FLAGS_SIGNED) &&
command != SMB2_NEGOTIATE_HE &&
@@ -8973,7 +8973,7 @@ int smb2_check_sign_req(struct ksmbd_work *work)
struct kvec iov[1];
size_t len;
- hdr = smb2_get_msg(work->request_buf);
+ hdr = smb_get_msg(work->request_buf);
if (work->next_smb2_rcv_hdr_off)
hdr = ksmbd_req_buf_next(work);
@@ -9048,7 +9048,7 @@ int smb3_check_sign_req(struct ksmbd_work *work)
struct kvec iov[1];
size_t len;
- hdr = smb2_get_msg(work->request_buf);
+ hdr = smb_get_msg(work->request_buf);
if (work->next_smb2_rcv_hdr_off)
hdr = ksmbd_req_buf_next(work);
@@ -9184,7 +9184,7 @@ void smb3_preauth_hash_rsp(struct ksmbd_work *work)
static void fill_transform_hdr(void *tr_buf, char *old_buf, __le16 cipher_type)
{
struct smb2_transform_hdr *tr_hdr = tr_buf + 4;
- struct smb2_hdr *hdr = smb2_get_msg(old_buf);
+ struct smb2_hdr *hdr = smb_get_msg(old_buf);
unsigned int orig_len = get_rfc1002_len(old_buf);
/* tr_buf must be cleared by the caller */
@@ -9223,7 +9223,7 @@ int smb3_encrypt_resp(struct ksmbd_work *work)
bool smb3_is_transform_hdr(void *buf)
{
- struct smb2_transform_hdr *trhdr = smb2_get_msg(buf);
+ struct smb2_transform_hdr *trhdr = smb_get_msg(buf);
return trhdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM;
}
@@ -9235,7 +9235,7 @@ int smb3_decrypt_req(struct ksmbd_work *work)
unsigned int pdu_length = get_rfc1002_len(buf);
struct kvec iov[2];
int buf_data_size = pdu_length - sizeof(struct smb2_transform_hdr);
- struct smb2_transform_hdr *tr_hdr = smb2_get_msg(buf);
+ struct smb2_transform_hdr *tr_hdr = smb_get_msg(buf);
int rc = 0;
if (pdu_length < sizeof(struct smb2_transform_hdr) ||
@@ -9276,7 +9276,7 @@ bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work)
{
struct ksmbd_conn *conn = work->conn;
struct ksmbd_session *sess = work->sess;
- struct smb2_hdr *rsp = smb2_get_msg(work->response_buf);
+ struct smb2_hdr *rsp = smb_get_msg(work->response_buf);
if (conn->dialect < SMB30_PROT_ID)
return false;
diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h
index ad02d0a376025..dd1c25279d4a0 100644
--- a/fs/smb/server/smb2pdu.h
+++ b/fs/smb/server/smb2pdu.h
@@ -496,15 +496,6 @@ int smb2_ioctl(struct ksmbd_work *work);
int smb2_oplock_break(struct ksmbd_work *work);
int smb2_notify(struct ksmbd_work *ksmbd_work);
-/*
- * Get the body of the smb2 message excluding the 4 byte rfc1002 headers
- * from request/response buffer.
- */
-static inline void *smb2_get_msg(void *buf)
-{
- return buf + 4;
-}
-
#define POSIX_TYPE_FILE 0
#define POSIX_TYPE_DIR 1
#define POSIX_TYPE_SYMLINK 2
diff --git a/fs/smb/server/smb_common.c b/fs/smb/server/smb_common.c
index c64d1fc34d6bf..7e8a845abfe62 100644
--- a/fs/smb/server/smb_common.c
+++ b/fs/smb/server/smb_common.c
@@ -163,7 +163,7 @@ bool ksmbd_smb_request(struct ksmbd_conn *conn)
if (conn->request_buf[0] != 0)
return false;
- proto = (__le32 *)smb2_get_msg(conn->request_buf);
+ proto = (__le32 *)smb_get_msg(conn->request_buf);
if (*proto == SMB2_COMPRESSION_TRANSFORM_ID) {
pr_err_ratelimited("smb2 compression not support yet");
return false;
@@ -259,14 +259,14 @@ int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count)
static int ksmbd_negotiate_smb_dialect(void *buf)
{
int smb_buf_length = get_rfc1002_len(buf);
- __le32 proto = ((struct smb2_hdr *)smb2_get_msg(buf))->ProtocolId;
+ __le32 proto = ((struct smb2_hdr *)smb_get_msg(buf))->ProtocolId;
if (proto == SMB2_PROTO_NUMBER) {
struct smb2_negotiate_req *req;
int smb2_neg_size =
offsetof(struct smb2_negotiate_req, Dialects);
- req = (struct smb2_negotiate_req *)smb2_get_msg(buf);
+ req = (struct smb2_negotiate_req *)smb_get_msg(buf);
if (smb2_neg_size > smb_buf_length)
goto err_out;
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index 26f8c268ece99..8693b5f5b4ac2 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -421,4 +421,13 @@ unsigned int ksmbd_server_side_copy_max_chunk_size(void);
unsigned int ksmbd_server_side_copy_max_total_size(void);
bool is_asterisk(char *p);
__le32 smb_map_generic_desired_access(__le32 daccess);
+
+/*
+ * Get the body of the smb message excluding the 4 byte rfc1002 headers
+ * from request/response buffer.
+ */
+static inline void *smb_get_msg(void *buf)
+{
+ return buf + 4;
+}
#endif /* __SMB_SERVER_COMMON_H__ */
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6.6.y 5/7] smb/server: fix minimum SMB1 PDU size
2026-08-09 1:21 ` [PATCH 6.6.y 1/7] smb: move smb_version_values to common/smbglob.h Sasha Levin
` (2 preceding siblings ...)
2026-08-09 1:21 ` [PATCH 6.6.y 4/7] ksmbd: rename smb2_get_msg to smb_get_msg Sasha Levin
@ 2026-08-09 1:21 ` Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 6/7] smb/server: fix minimum SMB2 " Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 7/7] ksmbd: validate minimum PDU size for transform requests Sasha Levin
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-08-09 1:21 UTC (permalink / raw)
To: stable; +Cc: ChenXiaoSong, David Howells, Namjae Jeon, Steve French,
Sasha Levin
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
[ Upstream commit 3b9c30eb8f5aaad4a54cdfa470b74c0467cc71e8 ]
Since the RFC1002 header has been removed from `struct smb_hdr`,
the minimum SMB1 PDU size should be updated as well.
Fixes: 83bfbd0bb902 ("cifs: Remove the RFC1002 header from smb_hdr")
Suggested-by: David Howells <dhowells@redhat.com>
Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: David Howells <dhowells@redhat.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: cfc0b8e5080a ("ksmbd: validate minimum PDU size for transform requests")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/connection.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c
index 82bad1745a507..a1cd1e0076599 100644
--- a/fs/smb/server/connection.c
+++ b/fs/smb/server/connection.c
@@ -376,7 +376,8 @@ bool ksmbd_conn_alive(struct ksmbd_conn *conn)
return true;
}
-#define SMB1_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb_hdr))
+/* "+2" for BCC field (ByteCount, 2 bytes) */
+#define SMB1_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb_hdr) + 2)
#define SMB2_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb2_hdr) + 4)
/**
@@ -444,7 +445,7 @@ int ksmbd_conn_handler_loop(void *p)
if (pdu_size > MAX_STREAM_PROT_LEN)
break;
- if (pdu_size < SMB1_MIN_SUPPORTED_HEADER_SIZE)
+ if (pdu_size < SMB1_MIN_SUPPORTED_PDU_SIZE)
break;
/* 4 for rfc1002 length field */
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6.6.y 6/7] smb/server: fix minimum SMB2 PDU size
2026-08-09 1:21 ` [PATCH 6.6.y 1/7] smb: move smb_version_values to common/smbglob.h Sasha Levin
` (3 preceding siblings ...)
2026-08-09 1:21 ` [PATCH 6.6.y 5/7] smb/server: fix minimum SMB1 PDU size Sasha Levin
@ 2026-08-09 1:21 ` Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 7/7] ksmbd: validate minimum PDU size for transform requests Sasha Levin
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-08-09 1:21 UTC (permalink / raw)
To: stable; +Cc: ChenXiaoSong, David Howells, Namjae Jeon, Steve French,
Sasha Levin
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
[ Upstream commit 4c7d8eb9a79ae5400eac19c4f6f0815bff674452 ]
The minimum SMB2 PDU size should be updated to the size of
`struct smb2_pdu` (that is, the size of `struct smb2_hdr` + 2).
Suggested-by: David Howells <dhowells@redhat.com>
Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: David Howells <dhowells@redhat.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: cfc0b8e5080a ("ksmbd: validate minimum PDU size for transform requests")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/connection.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c
index a1cd1e0076599..b7f83c8d39762 100644
--- a/fs/smb/server/connection.c
+++ b/fs/smb/server/connection.c
@@ -378,7 +378,7 @@ bool ksmbd_conn_alive(struct ksmbd_conn *conn)
/* "+2" for BCC field (ByteCount, 2 bytes) */
#define SMB1_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb_hdr) + 2)
-#define SMB2_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb2_hdr) + 4)
+#define SMB2_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb2_pdu))
/**
* ksmbd_conn_handler_loop() - session thread to listen on new smb requests
@@ -478,7 +478,7 @@ int ksmbd_conn_handler_loop(void *p)
if (((struct smb2_hdr *)smb_get_msg(conn->request_buf))->ProtocolId ==
SMB2_PROTO_NUMBER) {
- if (pdu_size < SMB2_MIN_SUPPORTED_HEADER_SIZE)
+ if (pdu_size < SMB2_MIN_SUPPORTED_PDU_SIZE)
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6.6.y 7/7] ksmbd: validate minimum PDU size for transform requests
2026-08-09 1:21 ` [PATCH 6.6.y 1/7] smb: move smb_version_values to common/smbglob.h Sasha Levin
` (4 preceding siblings ...)
2026-08-09 1:21 ` [PATCH 6.6.y 6/7] smb/server: fix minimum SMB2 " Sasha Levin
@ 2026-08-09 1:21 ` Sasha Levin
5 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2026-08-09 1:21 UTC (permalink / raw)
To: stable; +Cc: Namjae Jeon, zdi-disclosures, Steve French, Sasha Levin
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit cfc0b8e5080aec87700774e8568765eaa4b7b92b ]
The receive path applies the minimum SMB2 PDU size check only when
ProtocolId is SMB2_PROTO_NUMBER. A packet carrying
SMB2_TRANSFORM_PROTO_NUM bypasses the check even when the negotiated
dialect does not provide transform handling.
On an SMB 2.1 connection, a short transform packet therefore reaches
init_smb2_rsp_hdr(), which interprets the request as a full SMB2 header
and reads beyond the request allocation. The copied fields can then be
returned to the unauthenticated client.
Compression transforms are converted to ordinary SMB2 messages before
protocol validation. After that conversion, validate ordinary SMB2
requests against SMB2_MIN_SUPPORTED_PDU_SIZE and require encryption
transform requests to contain both a transform header and an SMB2
header. This rejects truncated requests before work allocation.
Fixes: 368ba06881c3 ("ksmbd: check the validation of pdu_size in ksmbd_conn_handler_loop")
Cc: stable@vger.kernel.org
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-31063
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/connection.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c
index b7f83c8d39762..8a19058efc3f7 100644
--- a/fs/smb/server/connection.c
+++ b/fs/smb/server/connection.c
@@ -379,6 +379,8 @@ bool ksmbd_conn_alive(struct ksmbd_conn *conn)
/* "+2" for BCC field (ByteCount, 2 bytes) */
#define SMB1_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb_hdr) + 2)
#define SMB2_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb2_pdu))
+#define SMB2_TRANSFORM_MIN_SUPPORTED_PDU_SIZE \
+ (sizeof(struct smb2_transform_hdr) + sizeof(struct smb2_hdr))
/**
* ksmbd_conn_handler_loop() - session thread to listen on new smb requests
@@ -393,6 +395,7 @@ int ksmbd_conn_handler_loop(void *p)
struct ksmbd_conn *conn = (struct ksmbd_conn *)p;
struct ksmbd_transport *t = conn->transport;
unsigned int pdu_size, max_allowed_pdu_size, max_req;
+ __le32 proto;
char hdr_buf[4] = {0,};
int size;
@@ -476,11 +479,14 @@ int ksmbd_conn_handler_loop(void *p)
if (!ksmbd_smb_request(conn))
break;
- if (((struct smb2_hdr *)smb_get_msg(conn->request_buf))->ProtocolId ==
- SMB2_PROTO_NUMBER) {
- if (pdu_size < SMB2_MIN_SUPPORTED_PDU_SIZE)
- break;
- }
+ proto = *(__le32 *)smb_get_msg(conn->request_buf);
+ if (proto == SMB2_PROTO_NUMBER &&
+ pdu_size < SMB2_MIN_SUPPORTED_PDU_SIZE)
+ break;
+
+ if (proto == SMB2_TRANSFORM_PROTO_NUM &&
+ pdu_size < SMB2_TRANSFORM_MIN_SUPPORTED_PDU_SIZE)
+ break;
if (!default_conn_ops.process_fn) {
pr_err("No connection request callback\n");
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-08-09 1:22 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-29 13:55 FAILED: patch "[PATCH] ksmbd: validate minimum PDU size for transform requests" failed to apply to 6.6-stable tree gregkh
2026-08-09 1:21 ` [PATCH 6.6.y 1/7] smb: move smb_version_values to common/smbglob.h Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 2/7] smb: move get_rfc1002_len() " Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 3/7] smb/server: rename include guard in smb_common.h Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 4/7] ksmbd: rename smb2_get_msg to smb_get_msg Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 5/7] smb/server: fix minimum SMB1 PDU size Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 6/7] smb/server: fix minimum SMB2 " Sasha Levin
2026-08-09 1:21 ` [PATCH 6.6.y 7/7] ksmbd: validate minimum PDU size for transform requests Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).