From af1d315ed3c2b3572e77a4b6654eecd16f097794 Mon Sep 17 00:00:00 2001 From: Enzo Matsumiya Date: Fri, 27 Jun 2025 19:36:40 +0800 Subject: [PATCH] cifs: fix small mempool leak in SMB2_negotiate() mainline inclusion from mainline-v6.0-rc4 commit 27893dfc1285f80f80f46b3b8c95f5d15d2e66d0 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ICG9II CVE: CVE-2022-49938 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=27893dfc1285f80f80f46b3b8c95f5d15d2e66d0 -------------------------------- In some cases of failure (dialect mismatches) in SMB2_negotiate(), after the request is sent, the checks would return -EIO when they should be rather setting rc = -EIO and jumping to neg_exit to free the response buffer from mempool. Signed-off-by: Enzo Matsumiya Cc: stable@vger.kernel.org Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French Conflicts: fs/cifs/smb2pdu.c [The code has been refactored many times, causing context conflicts.] Signed-off-by: Wang Zhaolong --- fs/cifs/smb2pdu.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index e8304a44d9d8..9890674df444 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -727,23 +727,24 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) } else if (rc != 0) goto neg_exit; + rc = -EIO; if (strcmp(ses->server->vals->version_string, SMB3ANY_VERSION_STRING) == 0) { if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) { cifs_dbg(VFS, "SMB2 dialect returned but not requested\n"); - return -EIO; + goto neg_exit; } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { cifs_dbg(VFS, "SMB2.1 dialect returned but not requested\n"); - return -EIO; + goto neg_exit; } } else if (strcmp(ses->server->vals->version_string, SMBDEFAULT_VERSION_STRING) == 0) { if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) { cifs_dbg(VFS, "SMB2 dialect returned but not requested\n"); - return -EIO; + goto neg_exit; } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { /* ops set to 3.0 by default for default so update */ ses->server->ops = &smb21_operations; @@ -754,7 +755,7 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) /* if requested single dialect ensure returned dialect matched */ cifs_dbg(VFS, "Illegal 0x%x dialect returned: not requested\n", le16_to_cpu(rsp->DialectRevision)); - return -EIO; + goto neg_exit; } cifs_dbg(FYI, "mode 0x%x\n", rsp->SecurityMode); @@ -772,11 +773,11 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) else { cifs_dbg(VFS, "Illegal dialect returned by server 0x%x\n", le16_to_cpu(rsp->DialectRevision)); - rc = -EIO; goto neg_exit; } server->dialect = le16_to_cpu(rsp->DialectRevision); + rc = 0; /* * Keep a copy of the hash after negprot. This hash will be * the starting hash value for all sessions made from this -- Gitee