Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

smb: common: change the data type of num_aces to le16

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>

authored by

Namjae Jeon and committed by
Steve French
62e7dd0a e26e2d2e

+32 -30
+13 -13
fs/smb/client/cifsacl.c
··· 763 763 struct cifs_fattr *fattr, bool mode_from_special_sid) 764 764 { 765 765 int i; 766 - int num_aces = 0; 766 + u16 num_aces = 0; 767 767 int acl_size; 768 768 char *acl_base; 769 769 struct smb_ace **ppace; ··· 785 785 786 786 cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n", 787 787 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), 788 - le32_to_cpu(pdacl->num_aces)); 788 + le16_to_cpu(pdacl->num_aces)); 789 789 790 790 /* reset rwx permissions for user/group/other. 791 791 Also, if num_aces is 0 i.e. DACL has no ACEs, ··· 795 795 acl_base = (char *)pdacl; 796 796 acl_size = sizeof(struct smb_acl); 797 797 798 - num_aces = le32_to_cpu(pdacl->num_aces); 798 + num_aces = le16_to_cpu(pdacl->num_aces); 799 799 if (num_aces > 0) { 800 800 umode_t denied_mode = 0; 801 801 ··· 937 937 static void populate_new_aces(char *nacl_base, 938 938 struct smb_sid *pownersid, 939 939 struct smb_sid *pgrpsid, 940 - __u64 *pnmode, u32 *pnum_aces, u16 *pnsize, 940 + __u64 *pnmode, u16 *pnum_aces, u16 *pnsize, 941 941 bool modefromsid, 942 942 bool posix) 943 943 { 944 944 __u64 nmode; 945 - u32 num_aces = 0; 945 + u16 num_aces = 0; 946 946 u16 nsize = 0; 947 947 __u64 user_mode; 948 948 __u64 group_mode; ··· 1050 1050 u16 size = 0; 1051 1051 struct smb_ace *pntace = NULL; 1052 1052 char *acl_base = NULL; 1053 - u32 src_num_aces = 0; 1053 + u16 src_num_aces = 0; 1054 1054 u16 nsize = 0; 1055 1055 struct smb_ace *pnntace = NULL; 1056 1056 char *nacl_base = NULL; ··· 1058 1058 1059 1059 acl_base = (char *)pdacl; 1060 1060 size = sizeof(struct smb_acl); 1061 - src_num_aces = le32_to_cpu(pdacl->num_aces); 1061 + src_num_aces = le16_to_cpu(pdacl->num_aces); 1062 1062 1063 1063 nacl_base = (char *)pndacl; 1064 1064 nsize = sizeof(struct smb_acl); ··· 1090 1090 u16 size = 0; 1091 1091 struct smb_ace *pntace = NULL; 1092 1092 char *acl_base = NULL; 1093 - u32 src_num_aces = 0; 1093 + u16 src_num_aces = 0; 1094 1094 u16 nsize = 0; 1095 1095 struct smb_ace *pnntace = NULL; 1096 1096 char *nacl_base = NULL; 1097 - u32 num_aces = 0; 1097 + u16 num_aces = 0; 1098 1098 bool new_aces_set = false; 1099 1099 1100 1100 /* Assuming that pndacl and pnmode are never NULL */ ··· 1112 1112 1113 1113 acl_base = (char *)pdacl; 1114 1114 size = sizeof(struct smb_acl); 1115 - src_num_aces = le32_to_cpu(pdacl->num_aces); 1115 + src_num_aces = le16_to_cpu(pdacl->num_aces); 1116 1116 1117 1117 /* Retain old ACEs which we can retain */ 1118 1118 for (i = 0; i < src_num_aces; ++i) { ··· 1158 1158 } 1159 1159 1160 1160 finalize_dacl: 1161 - pndacl->num_aces = cpu_to_le32(num_aces); 1161 + pndacl->num_aces = cpu_to_le16(num_aces); 1162 1162 pndacl->size = cpu_to_le16(nsize); 1163 1163 1164 1164 return 0; ··· 1293 1293 dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION); 1294 1294 1295 1295 ndacl_ptr->size = cpu_to_le16(0); 1296 - ndacl_ptr->num_aces = cpu_to_le32(0); 1296 + ndacl_ptr->num_aces = cpu_to_le16(0); 1297 1297 1298 1298 rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr, 1299 1299 pnmode, mode_from_sid, posix); ··· 1653 1653 dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); 1654 1654 if (mode_from_sid) 1655 1655 nsecdesclen += 1656 - le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace); 1656 + le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace); 1657 1657 else /* cifsacl */ 1658 1658 nsecdesclen += le16_to_cpu(dacl_ptr->size); 1659 1659 }
+2 -1
fs/smb/common/smbacl.h
··· 107 107 struct smb_acl { 108 108 __le16 revision; /* revision level */ 109 109 __le16 size; 110 - __le32 num_aces; 110 + __le16 num_aces; 111 + __le16 reserved; 111 112 } __attribute__((packed)); 112 113 113 114 struct smb_ace {
+16 -15
fs/smb/server/smbacl.c
··· 333 333 pace->e_perm = state->other.allow; 334 334 } 335 335 336 - int init_acl_state(struct posix_acl_state *state, int cnt) 336 + int init_acl_state(struct posix_acl_state *state, u16 cnt) 337 337 { 338 338 int alloc; 339 339 ··· 368 368 struct smb_fattr *fattr) 369 369 { 370 370 int i, ret; 371 - int num_aces = 0; 371 + u16 num_aces = 0; 372 372 unsigned int acl_size; 373 373 char *acl_base; 374 374 struct smb_ace **ppace; ··· 389 389 390 390 ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n", 391 391 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), 392 - le32_to_cpu(pdacl->num_aces)); 392 + le16_to_cpu(pdacl->num_aces)); 393 393 394 394 acl_base = (char *)pdacl; 395 395 acl_size = sizeof(struct smb_acl); 396 396 397 - num_aces = le32_to_cpu(pdacl->num_aces); 397 + num_aces = le16_to_cpu(pdacl->num_aces); 398 398 if (num_aces <= 0) 399 399 return; 400 400 ··· 580 580 581 581 static void set_posix_acl_entries_dacl(struct mnt_idmap *idmap, 582 582 struct smb_ace *pndace, 583 - struct smb_fattr *fattr, u32 *num_aces, 583 + struct smb_fattr *fattr, u16 *num_aces, 584 584 u16 *size, u32 nt_aces_num) 585 585 { 586 586 struct posix_acl_entry *pace; ··· 701 701 struct smb_fattr *fattr) 702 702 { 703 703 struct smb_ace *ntace, *pndace; 704 - int nt_num_aces = le32_to_cpu(nt_dacl->num_aces), num_aces = 0; 704 + u16 nt_num_aces = le16_to_cpu(nt_dacl->num_aces), num_aces = 0; 705 705 unsigned short size = 0; 706 706 int i; 707 707 ··· 728 728 729 729 set_posix_acl_entries_dacl(idmap, pndace, fattr, 730 730 &num_aces, &size, nt_num_aces); 731 - pndacl->num_aces = cpu_to_le32(num_aces); 731 + pndacl->num_aces = cpu_to_le16(num_aces); 732 732 pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size); 733 733 } 734 734 ··· 736 736 struct smb_acl *pndacl, struct smb_fattr *fattr) 737 737 { 738 738 struct smb_ace *pace, *pndace; 739 - u32 num_aces = 0; 739 + u16 num_aces = 0; 740 740 u16 size = 0, ace_size = 0; 741 741 uid_t uid; 742 742 const struct smb_sid *sid; ··· 792 792 fattr->cf_mode, 0007); 793 793 794 794 out: 795 - pndacl->num_aces = cpu_to_le32(num_aces); 795 + pndacl->num_aces = cpu_to_le16(num_aces); 796 796 pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size); 797 797 } 798 798 ··· 1022 1022 struct smb_sid owner_sid, group_sid; 1023 1023 struct dentry *parent = path->dentry->d_parent; 1024 1024 struct mnt_idmap *idmap = mnt_idmap(path->mnt); 1025 - int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0, pdacl_size; 1026 - int rc = 0, num_aces, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size; 1025 + int inherited_flags = 0, flags = 0, i, nt_size = 0, pdacl_size; 1026 + int rc = 0, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size; 1027 + u16 num_aces, ace_cnt = 0; 1027 1028 char *aces_base; 1028 1029 bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode); 1029 1030 ··· 1040 1039 1041 1040 parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset); 1042 1041 acl_len = pntsd_size - dacloffset; 1043 - num_aces = le32_to_cpu(parent_pdacl->num_aces); 1042 + num_aces = le16_to_cpu(parent_pdacl->num_aces); 1044 1043 pntsd_type = le16_to_cpu(parent_pntsd->type); 1045 1044 pdacl_size = le16_to_cpu(parent_pdacl->size); 1046 1045 ··· 1200 1199 pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset)); 1201 1200 pdacl->revision = cpu_to_le16(2); 1202 1201 pdacl->size = cpu_to_le16(sizeof(struct smb_acl) + nt_size); 1203 - pdacl->num_aces = cpu_to_le32(ace_cnt); 1202 + pdacl->num_aces = cpu_to_le16(ace_cnt); 1204 1203 pace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl)); 1205 1204 memcpy(pace, aces_base, nt_size); 1206 1205 pntsd_size += sizeof(struct smb_acl) + nt_size; ··· 1281 1280 1282 1281 ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl)); 1283 1282 aces_size = acl_size - sizeof(struct smb_acl); 1284 - for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) { 1283 + for (i = 0; i < le16_to_cpu(pdacl->num_aces); i++) { 1285 1284 if (offsetof(struct smb_ace, access_req) > aces_size) 1286 1285 break; 1287 1286 ace_size = le16_to_cpu(ace->size); ··· 1302 1301 1303 1302 ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl)); 1304 1303 aces_size = acl_size - sizeof(struct smb_acl); 1305 - for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) { 1304 + for (i = 0; i < le16_to_cpu(pdacl->num_aces); i++) { 1306 1305 if (offsetof(struct smb_ace, access_req) > aces_size) 1307 1306 break; 1308 1307 ace_size = le16_to_cpu(ace->size);
+1 -1
fs/smb/server/smbacl.h
··· 86 86 int build_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd, 87 87 struct smb_ntsd *ppntsd, int ppntsd_size, int addition_info, 88 88 __u32 *secdesclen, struct smb_fattr *fattr); 89 - int init_acl_state(struct posix_acl_state *state, int cnt); 89 + int init_acl_state(struct posix_acl_state *state, u16 cnt); 90 90 void free_acl_state(struct posix_acl_state *state); 91 91 void posix_state_to_acl(struct posix_acl_state *state, 92 92 struct posix_acl_entry *pace);