[PATCH] cifs: fix small mempool leak in SMB2_negotiate()

From: Enzo Matsumiya <ematsumiya@suse.de> 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/?i... -------------------------------- 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 <ematsumiya@suse.de> Cc: stable@vger.kernel.org Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com> Conflicts: fs/cifs/smb2pdu.c [The code has been refactored many times, causing context conflicts.] Signed-off-by: Wang Zhaolong <wangzhaolong1@huawei.com> --- 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 @@ -725,38 +725,39 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) " older servers\n"); goto neg_exit; } 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; ses->server->vals = &smb21_values; } } else if (le16_to_cpu(rsp->DialectRevision) != ses->server->vals->protocol_id) { /* 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); if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) @@ -770,15 +771,15 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n"); 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 * server. */ -- 2.34.3
participants (1)
-
Wang Zhaolong