From: Paulo Alcantara pc@manguebit.com
mainline inclusion from mainline-v6.7-rc7 commit 567320c46a60a3c39b69aa1df802d753817a3f86 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8MXXY CVE: CVE-2023-6610
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
Validate SMB message with ->check_message() before calling ->calc_smb_size().
This fixes CVE-2023-6610.
Reported-by: j51569436@gmail.com Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218219 Cc; stable@vger.kernel.org Signed-off-by: Paulo Alcantara pc@manguebit.com Signed-off-by: Steve French stfrench@microsoft.com
Conflicts: fs/cifs/smb2ops.c fs/cifs/smb2misc.c
Signed-off-by: ZhaoLong Wang wangzhaolong1@huawei.com --- fs/cifs/smb2misc.c | 30 +++++++++++++++--------------- fs/cifs/smb2ops.c | 6 ++++-- 2 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index be3df90bb2bc..49686086a333 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c @@ -174,6 +174,21 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr) }
mid = le64_to_cpu(shdr->MessageId); + if (check_smb2_hdr(shdr, mid)) + return 1; + + if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) { + cifs_dbg(VFS, "Invalid structure size %u\n", + le16_to_cpu(shdr->StructureSize)); + return 1; + } + + command = le16_to_cpu(shdr->Command); + if (command >= NUMBER_OF_SMB2_COMMANDS) { + cifs_dbg(VFS, "Invalid SMB2 command %d\n", command); + return 1; + } + if (len < pdu_size) { if ((len >= hdr_size) && (shdr->Status != 0)) { @@ -194,21 +209,6 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr) return 1; }
- if (check_smb2_hdr(shdr, mid)) - return 1; - - if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) { - cifs_dbg(VFS, "Invalid structure size %u\n", - le16_to_cpu(shdr->StructureSize)); - return 1; - } - - command = le16_to_cpu(shdr->Command); - if (command >= NUMBER_OF_SMB2_COMMANDS) { - cifs_dbg(VFS, "Invalid SMB2 command %d\n", command); - return 1; - } - if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) { if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 || pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) { diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 015b7b37edee..b86f559751fd 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -314,8 +314,10 @@ smb2_dump_detail(void *buf, struct TCP_Server_Info *server) cifs_server_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n", shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId, shdr->ProcessId); - cifs_server_dbg(VFS, "smb buf %p len %u\n", buf, - server->ops->calc_smb_size(buf, server)); + if (!server->ops->check_message(buf, server->total_read, server)) { + cifs_server_dbg(VFS, "smb buf %p len %u\n", buf, + server->ops->calc_smb_size(buf, server)); + } #endif }