]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
smb: common: change the data type of num_aces to le16
authorNamjae Jeon <linkinjeon@kernel.org>
Wed, 12 Feb 2025 14:26:09 +0000 (23:26 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Apr 2025 12:39:29 +0000 (14:39 +0200)
[ Upstream commit 62e7dd0a39c2d0d7ff03274c36df971f1b3d2d0d ]

2.4.5 in [MS-DTYP].pdf describe the data type of num_aces as le16.

AceCount (2 bytes): An unsigned 16-bit integer that specifies the count
of the number of ACE records in the ACL.

Change it to le16 and add reserved field to smb_acl struct.

Reported-by: Igor Leite Ladessa <igor-ladessa@hotmail.com>
Tested-by: Igor Leite Ladessa <igor-ladessa@hotmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/smb/client/cifsacl.c
fs/smb/common/smbacl.h
fs/smb/server/smbacl.c
fs/smb/server/smbacl.h

index ebe9a7d7c70e86e95b0698c584334490a2af319a..1f036169fb5820c9c7836c71b35812649cc51563 100644 (file)
@@ -763,7 +763,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
                       struct cifs_fattr *fattr, bool mode_from_special_sid)
 {
        int i;
-       int num_aces = 0;
+       u16 num_aces = 0;
        int acl_size;
        char *acl_base;
        struct smb_ace **ppace;
@@ -785,7 +785,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
 
        cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
                 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
-                le32_to_cpu(pdacl->num_aces));
+                le16_to_cpu(pdacl->num_aces));
 
        /* reset rwx permissions for user/group/other.
           Also, if num_aces is 0 i.e. DACL has no ACEs,
@@ -795,7 +795,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
        acl_base = (char *)pdacl;
        acl_size = sizeof(struct smb_acl);
 
-       num_aces = le32_to_cpu(pdacl->num_aces);
+       num_aces = le16_to_cpu(pdacl->num_aces);
        if (num_aces > 0) {
                umode_t denied_mode = 0;
 
@@ -937,12 +937,12 @@ unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace)
 static void populate_new_aces(char *nacl_base,
                struct smb_sid *pownersid,
                struct smb_sid *pgrpsid,
-               __u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
+               __u64 *pnmode, u16 *pnum_aces, u16 *pnsize,
                bool modefromsid,
                bool posix)
 {
        __u64 nmode;
-       u32 num_aces = 0;
+       u16 num_aces = 0;
        u16 nsize = 0;
        __u64 user_mode;
        __u64 group_mode;
@@ -1050,7 +1050,7 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p
        u16 size = 0;
        struct smb_ace *pntace = NULL;
        char *acl_base = NULL;
-       u32 src_num_aces = 0;
+       u16 src_num_aces = 0;
        u16 nsize = 0;
        struct smb_ace *pnntace = NULL;
        char *nacl_base = NULL;
@@ -1058,7 +1058,7 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p
 
        acl_base = (char *)pdacl;
        size = sizeof(struct smb_acl);
-       src_num_aces = le32_to_cpu(pdacl->num_aces);
+       src_num_aces = le16_to_cpu(pdacl->num_aces);
 
        nacl_base = (char *)pndacl;
        nsize = sizeof(struct smb_acl);
@@ -1090,11 +1090,11 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
        u16 size = 0;
        struct smb_ace *pntace = NULL;
        char *acl_base = NULL;
-       u32 src_num_aces = 0;
+       u16 src_num_aces = 0;
        u16 nsize = 0;
        struct smb_ace *pnntace = NULL;
        char *nacl_base = NULL;
-       u32 num_aces = 0;
+       u16 num_aces = 0;
        bool new_aces_set = false;
 
        /* Assuming that pndacl and pnmode are never NULL */
@@ -1112,7 +1112,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
 
        acl_base = (char *)pdacl;
        size = sizeof(struct smb_acl);
-       src_num_aces = le32_to_cpu(pdacl->num_aces);
+       src_num_aces = le16_to_cpu(pdacl->num_aces);
 
        /* Retain old ACEs which we can retain */
        for (i = 0; i < src_num_aces; ++i) {
@@ -1158,7 +1158,7 @@ next_ace:
        }
 
 finalize_dacl:
-       pndacl->num_aces = cpu_to_le32(num_aces);
+       pndacl->num_aces = cpu_to_le16(num_aces);
        pndacl->size = cpu_to_le16(nsize);
 
        return 0;
@@ -1293,7 +1293,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
                        dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
 
                ndacl_ptr->size = cpu_to_le16(0);
-               ndacl_ptr->num_aces = cpu_to_le32(0);
+               ndacl_ptr->num_aces = cpu_to_le16(0);
 
                rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
                                    pnmode, mode_from_sid, posix);
@@ -1651,7 +1651,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
                        dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
                        if (mode_from_sid)
                                nsecdesclen +=
-                                       le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
+                                       le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
                        else /* cifsacl */
                                nsecdesclen += le16_to_cpu(dacl_ptr->size);
                }
index 6a60698fc6f0f4678adca7266cfe9bb2c8fd1c9e..a624ec9e4a14437fd31759495efe7506c7d30c2a 100644 (file)
@@ -107,7 +107,8 @@ struct smb_sid {
 struct smb_acl {
        __le16 revision; /* revision level */
        __le16 size;
-       __le32 num_aces;
+       __le16 num_aces;
+       __le16 reserved;
 } __attribute__((packed));
 
 struct smb_ace {
index 109036e2227ca1173fad8d02418585c54a228499..5e6ffb821f6fd7fc488842e870f62e8d0f35678f 100644 (file)
@@ -333,7 +333,7 @@ void posix_state_to_acl(struct posix_acl_state *state,
        pace->e_perm = state->other.allow;
 }
 
-int init_acl_state(struct posix_acl_state *state, int cnt)
+int init_acl_state(struct posix_acl_state *state, u16 cnt)
 {
        int alloc;
 
@@ -368,7 +368,7 @@ static void parse_dacl(struct mnt_idmap *idmap,
                       struct smb_fattr *fattr)
 {
        int i, ret;
-       int num_aces = 0;
+       u16 num_aces = 0;
        unsigned int acl_size;
        char *acl_base;
        struct smb_ace **ppace;
@@ -389,12 +389,12 @@ static void parse_dacl(struct mnt_idmap *idmap,
 
        ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n",
                    le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
-                   le32_to_cpu(pdacl->num_aces));
+                   le16_to_cpu(pdacl->num_aces));
 
        acl_base = (char *)pdacl;
        acl_size = sizeof(struct smb_acl);
 
-       num_aces = le32_to_cpu(pdacl->num_aces);
+       num_aces = le16_to_cpu(pdacl->num_aces);
        if (num_aces <= 0)
                return;
 
@@ -583,7 +583,7 @@ static void parse_dacl(struct mnt_idmap *idmap,
 
 static void set_posix_acl_entries_dacl(struct mnt_idmap *idmap,
                                       struct smb_ace *pndace,
-                                      struct smb_fattr *fattr, u32 *num_aces,
+                                      struct smb_fattr *fattr, u16 *num_aces,
                                       u16 *size, u32 nt_aces_num)
 {
        struct posix_acl_entry *pace;
@@ -704,7 +704,7 @@ static void set_ntacl_dacl(struct mnt_idmap *idmap,
                           struct smb_fattr *fattr)
 {
        struct smb_ace *ntace, *pndace;
-       int nt_num_aces = le32_to_cpu(nt_dacl->num_aces), num_aces = 0;
+       u16 nt_num_aces = le16_to_cpu(nt_dacl->num_aces), num_aces = 0;
        unsigned short size = 0;
        int i;
 
@@ -731,7 +731,7 @@ static void set_ntacl_dacl(struct mnt_idmap *idmap,
 
        set_posix_acl_entries_dacl(idmap, pndace, fattr,
                                   &num_aces, &size, nt_num_aces);
-       pndacl->num_aces = cpu_to_le32(num_aces);
+       pndacl->num_aces = cpu_to_le16(num_aces);
        pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
 }
 
@@ -739,7 +739,7 @@ static void set_mode_dacl(struct mnt_idmap *idmap,
                          struct smb_acl *pndacl, struct smb_fattr *fattr)
 {
        struct smb_ace *pace, *pndace;
-       u32 num_aces = 0;
+       u16 num_aces = 0;
        u16 size = 0, ace_size = 0;
        uid_t uid;
        const struct smb_sid *sid;
@@ -795,7 +795,7 @@ static void set_mode_dacl(struct mnt_idmap *idmap,
                                 fattr->cf_mode, 0007);
 
 out:
-       pndacl->num_aces = cpu_to_le32(num_aces);
+       pndacl->num_aces = cpu_to_le16(num_aces);
        pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
 }
 
@@ -1025,8 +1025,9 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
        struct smb_sid owner_sid, group_sid;
        struct dentry *parent = path->dentry->d_parent;
        struct mnt_idmap *idmap = mnt_idmap(path->mnt);
-       int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0, pdacl_size;
-       int rc = 0, num_aces, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size;
+       int inherited_flags = 0, flags = 0, i, nt_size = 0, pdacl_size;
+       int rc = 0, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size;
+       u16 num_aces, ace_cnt = 0;
        char *aces_base;
        bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
 
@@ -1042,7 +1043,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
 
        parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset);
        acl_len = pntsd_size - dacloffset;
-       num_aces = le32_to_cpu(parent_pdacl->num_aces);
+       num_aces = le16_to_cpu(parent_pdacl->num_aces);
        pntsd_type = le16_to_cpu(parent_pntsd->type);
        pdacl_size = le16_to_cpu(parent_pdacl->size);
 
@@ -1201,7 +1202,7 @@ pass:
                        pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
                        pdacl->revision = cpu_to_le16(2);
                        pdacl->size = cpu_to_le16(sizeof(struct smb_acl) + nt_size);
-                       pdacl->num_aces = cpu_to_le32(ace_cnt);
+                       pdacl->num_aces = cpu_to_le16(ace_cnt);
                        pace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
                        memcpy(pace, aces_base, nt_size);
                        pntsd_size += sizeof(struct smb_acl) + nt_size;
@@ -1282,7 +1283,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
 
                ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
                aces_size = acl_size - sizeof(struct smb_acl);
-               for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
+               for (i = 0; i < le16_to_cpu(pdacl->num_aces); i++) {
                        if (offsetof(struct smb_ace, access_req) > aces_size)
                                break;
                        ace_size = le16_to_cpu(ace->size);
@@ -1303,7 +1304,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
 
        ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
        aces_size = acl_size - sizeof(struct smb_acl);
-       for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
+       for (i = 0; i < le16_to_cpu(pdacl->num_aces); i++) {
                if (offsetof(struct smb_ace, access_req) > aces_size)
                        break;
                ace_size = le16_to_cpu(ace->size);
index 24ce576fc2924bf0ad1f914ab87dc3b14f56aa17..355adaee39b871df4c8865a1fd5e1e600aa3e73c 100644 (file)
@@ -86,7 +86,7 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
 int build_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
                   struct smb_ntsd *ppntsd, int ppntsd_size, int addition_info,
                   __u32 *secdesclen, struct smb_fattr *fattr);
-int init_acl_state(struct posix_acl_state *state, int cnt);
+int init_acl_state(struct posix_acl_state *state, u16 cnt);
 void free_acl_state(struct posix_acl_state *state);
 void posix_state_to_acl(struct posix_acl_state *state,
                        struct posix_acl_entry *pace);