]> www.infradead.org Git - users/hch/misc.git/commitdiff
cifs: fix incorrect validation for num_aces field of smb_acl
authorNamjae Jeon <linkinjeon@kernel.org>
Wed, 12 Feb 2025 00:37:57 +0000 (09:37 +0900)
committerSteve French <stfrench@microsoft.com>
Mon, 3 Mar 2025 04:50:54 +0000 (22:50 -0600)
parse_dcal() validate num_aces to allocate ace array.

f (num_aces > ULONG_MAX / sizeof(struct smb_ace *))

It is an incorrect validation that we can create an array of size ULONG_MAX.
smb_acl has ->size field to calculate actual number of aces in response buffer
size. Use this to check invalid num_aces.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cifsacl.c

index 7d953208046af710acbd3b4098763bc91e50db3e..64bd68f750f84229ff8cd768576d93a40fb6f700 100644 (file)
@@ -778,7 +778,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
        }
 
        /* validate that we do not go past end of acl */
-       if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
+       if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl) ||
+           end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
                cifs_dbg(VFS, "ACL too small to parse DACL\n");
                return;
        }
@@ -799,8 +800,11 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
        if (num_aces > 0) {
                umode_t denied_mode = 0;
 
-               if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
+               if (num_aces > (le16_to_cpu(pdacl->size) - sizeof(struct smb_acl)) /
+                               (offsetof(struct smb_ace, sid) +
+                                offsetof(struct smb_sid, sub_auth) + sizeof(__le16)))
                        return;
+
                ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *),
                                      GFP_KERNEL);
                if (!ppace)