]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
smb: client: fix buffer leaks in SMB1 read and write
authorDawei Feng <dawei.feng@seu.edu.cn>
Sun, 28 Jun 2026 06:59:09 +0000 (14:59 +0800)
committerSteve French <stfrench@microsoft.com>
Sun, 26 Jul 2026 22:40:20 +0000 (17:40 -0500)
CIFSSMBRead(), CIFSSMBWrite() and CIFSSMBWrite2() allocate a request
buffer before checking whether tcon->ses->server is NULL. If that
defensive check ever fails, the helper returns -ECONNABORTED without
releasing the request buffer.

Fix these leaks by releasing the allocated request buffer before
returning from these error paths. Use cifs_small_buf_release() for the
buffers allocated by small_smb_init() and cifs_buf_release() for the
buffer allocated by smb_init().

The bug was first flagged by an experimental analysis tool we are
developing for kernel memory-management bugs while analyzing
v6.13-rc1. The tool is still under development and is not yet publicly
available. Manual inspection confirms that the bug is still
present in v7.1.1.

An x86_64 allyesconfig build showed no new warnings.

Runtime validation used a temporary fault-injection hook to force
tcon->ses->server to NULL after request-buffer initialization. On the
unfixed kernel, the harness observed two leaked small request buffers and
one leaked large request buffer, with directed kmemleak dumps confirming
the CIFS buffer allocation stacks. After the fix, no CIFS request-buffer
deltas remained.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cifssmb.c

index 40162d5554eaccbc95fd8649027b48ae66758313..1f77512252e77253a6d844bbfe52c3b84b1546cf 100644 (file)
@@ -1681,8 +1681,10 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
 
        /* tcon and ses pointer are checked in smb_init */
-       if (tcon->ses->server == NULL)
+       if (!tcon->ses->server) {
+               cifs_small_buf_release(pSMB);
                return -ECONNABORTED;
+       }
 
        pSMB->AndXCommand = 0xFF;       /* none */
        pSMB->Fid = netfid;
@@ -1796,8 +1798,10 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
 
        /* tcon and ses pointer are checked in smb_init */
-       if (tcon->ses->server == NULL)
+       if (!tcon->ses->server) {
+               cifs_buf_release(pSMB);
                return -ECONNABORTED;
+       }
 
        pSMB->AndXCommand = 0xFF;       /* none */
        pSMB->Fid = netfid;
@@ -2077,8 +2081,10 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
 
        /* tcon and ses pointer are checked in smb_init */
-       if (tcon->ses->server == NULL)
+       if (!tcon->ses->server) {
+               cifs_small_buf_release(pSMB);
                return -ECONNABORTED;
+       }
 
        pSMB->AndXCommand = 0xFF;       /* none */
        pSMB->Fid = netfid;