]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ksmbd: Fix acl.sd_buf memory leak and invalid sd_size error handling
authorQiang Liu <liuqiang@kylinos.cn>
Wed, 24 Jun 2026 01:13:19 +0000 (09:13 +0800)
committerSteve French <stfrench@microsoft.com>
Wed, 1 Jul 2026 02:29:45 +0000 (21:29 -0500)
1. When ndr_decode_v4_ntacl() fails, the code jumped to free_n_data
   which only freed n.data, skipping kfree(acl.sd_buf) and leaking
   the buffer. Zero-initialize struct xattr_ntacl acl, reorder error
   labels to out_free to release acl.sd_buf on all error paths.

2. if (acl.sd_size < sizeof(struct smb_ntsd)) is true, original code
   returned success without freeing sd_buf and left stale *pntsd.
   Set rc = -EINVAL before jumping to out_free to return error code and
   free buffer.

Signed-off-by: Qiang Liu <liuqiang@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/server/vfs.c

index 8e38c748d15bcd9515bc0d6a761afd04d6790cb7..6528412eac2db50ba5c993558476b46ac4870ac8 100644 (file)
@@ -1504,7 +1504,7 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
        struct ndr n;
        struct inode *inode = d_inode(dentry);
        struct ndr acl_ndr = {0};
-       struct xattr_ntacl acl;
+       struct xattr_ntacl acl = {0};
        struct xattr_smb_acl *smb_acl = NULL, *def_smb_acl = NULL;
        __u8 cmp_hash[XATTR_SD_HASH_SIZE] = {0};
 
@@ -1515,7 +1515,7 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
        n.length = rc;
        rc = ndr_decode_v4_ntacl(&n, &acl);
        if (rc)
-               goto free_n_data;
+               goto out_free;
 
        smb_acl = ksmbd_vfs_make_xattr_posix_acl(idmap, inode,
                                                 ACL_TYPE_ACCESS);
@@ -1541,6 +1541,7 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
        *pntsd = acl.sd_buf;
        if (acl.sd_size < sizeof(struct smb_ntsd)) {
                pr_err("sd size is invalid\n");
+               rc = -EINVAL;
                goto out_free;
        }
 
@@ -1560,8 +1561,6 @@ out_free:
                kfree(acl.sd_buf);
                *pntsd = NULL;
        }
-
-free_n_data:
        kfree(n.data);
        return rc;
 }