]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ksmbd: fix memory leak in parse_lease_state()
authorWang Zhaolong <wangzhaolong1@huawei.com>
Wed, 30 Apr 2025 03:16:23 +0000 (11:16 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 18 May 2025 06:21:21 +0000 (08:21 +0200)
[ Upstream commit eb4447bcce915b43b691123118893fca4f372a8f ]

The previous patch that added bounds check for create lease context
introduced a memory leak. When the bounds check fails, the function
returns NULL without freeing the previously allocated lease_ctx_info
structure.

This patch fixes the issue by adding kfree(lreq) before returning NULL
in both boundary check cases.

Fixes: bab703ed8472 ("ksmbd: add bounds check for create lease context")
Signed-off-by: Wang Zhaolong <wangzhaolong1@huawei.com>
Acked-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/oplock.c

index 2fcfabc35b06beaa50f290397ded234bb61849de..258ed9978b90e7ad36d7ab63d6eb97c1a2e2abdb 100644 (file)
@@ -1536,7 +1536,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req, bool is_dir)
 
                if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
                    sizeof(struct create_lease_v2) - 4)
-                       return NULL;
+                       goto err_out;
 
                memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
                if (is_dir) {
@@ -1557,7 +1557,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req, bool is_dir)
 
                if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
                    sizeof(struct create_lease))
-                       return NULL;
+                       goto err_out;
 
                memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
                lreq->req_state = lc->lcontext.LeaseState;
@@ -1566,6 +1566,9 @@ struct lease_ctx_info *parse_lease_state(void *open_req, bool is_dir)
                lreq->version = 1;
        }
        return lreq;
+err_out:
+       kfree(lreq);
+       return NULL;
 }
 
 /**