Skip to content

Commit 1593ddb

Browse files
namjaejeongregkh
authored andcommitted
smb: common: change the data type of num_aces to le16
[ Upstream commit 62e7dd0 ] 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> Stable-dep-of: d07b26f ("ksmbd: require minimum ACE size in smb_check_perm_dacl()") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 795dddb commit 1593ddb

4 files changed

Lines changed: 32 additions & 30 deletions

File tree

fs/smb/client/cifsacl.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
763763
struct cifs_fattr *fattr, bool mode_from_special_sid)
764764
{
765765
int i;
766-
int num_aces = 0;
766+
u16 num_aces = 0;
767767
int acl_size;
768768
char *acl_base;
769769
struct smb_ace **ppace;
@@ -786,7 +786,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
786786

787787
cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
788788
le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
789-
le32_to_cpu(pdacl->num_aces));
789+
le16_to_cpu(pdacl->num_aces));
790790

791791
/* reset rwx permissions for user/group/other.
792792
Also, if num_aces is 0 i.e. DACL has no ACEs,
@@ -796,7 +796,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
796796
acl_base = (char *)pdacl;
797797
acl_size = sizeof(struct smb_acl);
798798

799-
num_aces = le32_to_cpu(pdacl->num_aces);
799+
num_aces = le16_to_cpu(pdacl->num_aces);
800800
if (num_aces > 0) {
801801
umode_t denied_mode = 0;
802802

@@ -957,12 +957,12 @@ unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace)
957957
static void populate_new_aces(char *nacl_base,
958958
struct smb_sid *pownersid,
959959
struct smb_sid *pgrpsid,
960-
__u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
960+
__u64 *pnmode, u16 *pnum_aces, u16 *pnsize,
961961
bool modefromsid,
962962
bool posix)
963963
{
964964
__u64 nmode;
965-
u32 num_aces = 0;
965+
u16 num_aces = 0;
966966
u16 nsize = 0;
967967
__u64 user_mode;
968968
__u64 group_mode;
@@ -1070,15 +1070,15 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p
10701070
u16 size = 0;
10711071
struct smb_ace *pntace = NULL;
10721072
char *acl_base = NULL;
1073-
u32 src_num_aces = 0;
1073+
u16 src_num_aces = 0;
10741074
u16 nsize = 0;
10751075
struct smb_ace *pnntace = NULL;
10761076
char *nacl_base = NULL;
10771077
u16 ace_size = 0;
10781078

10791079
acl_base = (char *)pdacl;
10801080
size = sizeof(struct smb_acl);
1081-
src_num_aces = le32_to_cpu(pdacl->num_aces);
1081+
src_num_aces = le16_to_cpu(pdacl->num_aces);
10821082

10831083
nacl_base = (char *)pndacl;
10841084
nsize = sizeof(struct smb_acl);
@@ -1110,11 +1110,11 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
11101110
u16 size = 0;
11111111
struct smb_ace *pntace = NULL;
11121112
char *acl_base = NULL;
1113-
u32 src_num_aces = 0;
1113+
u16 src_num_aces = 0;
11141114
u16 nsize = 0;
11151115
struct smb_ace *pnntace = NULL;
11161116
char *nacl_base = NULL;
1117-
u32 num_aces = 0;
1117+
u16 num_aces = 0;
11181118
bool new_aces_set = false;
11191119

11201120
/* Assuming that pndacl and pnmode are never NULL */
@@ -1132,7 +1132,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
11321132

11331133
acl_base = (char *)pdacl;
11341134
size = sizeof(struct smb_acl);
1135-
src_num_aces = le32_to_cpu(pdacl->num_aces);
1135+
src_num_aces = le16_to_cpu(pdacl->num_aces);
11361136

11371137
/* Retain old ACEs which we can retain */
11381138
for (i = 0; i < src_num_aces; ++i) {
@@ -1178,7 +1178,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
11781178
}
11791179

11801180
finalize_dacl:
1181-
pndacl->num_aces = cpu_to_le32(num_aces);
1181+
pndacl->num_aces = cpu_to_le16(num_aces);
11821182
pndacl->size = cpu_to_le16(nsize);
11831183

11841184
return 0;
@@ -1335,7 +1335,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
13351335
dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
13361336

13371337
ndacl_ptr->size = cpu_to_le16(0);
1338-
ndacl_ptr->num_aces = cpu_to_le32(0);
1338+
ndacl_ptr->num_aces = cpu_to_le16(0);
13391339

13401340
rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
13411341
pnmode, mode_from_sid, posix);
@@ -1699,7 +1699,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
16991699
dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
17001700
if (mode_from_sid)
17011701
nsecdesclen +=
1702-
le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
1702+
le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
17031703
else /* cifsacl */
17041704
nsecdesclen += le16_to_cpu(dacl_ptr->size);
17051705
}

fs/smb/common/smbacl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ struct smb_sid {
107107
struct smb_acl {
108108
__le16 revision; /* revision level */
109109
__le16 size;
110-
__le32 num_aces;
110+
__le16 num_aces;
111+
__le16 reserved;
111112
} __attribute__((packed));
112113

113114
struct smb_ace {

fs/smb/server/smbacl.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ void posix_state_to_acl(struct posix_acl_state *state,
338338
pace->e_perm = state->other.allow;
339339
}
340340

341-
int init_acl_state(struct posix_acl_state *state, int cnt)
341+
int init_acl_state(struct posix_acl_state *state, u16 cnt)
342342
{
343343
int alloc;
344344

@@ -373,7 +373,7 @@ static void parse_dacl(struct mnt_idmap *idmap,
373373
struct smb_fattr *fattr)
374374
{
375375
int i, ret;
376-
int num_aces = 0;
376+
u16 num_aces = 0;
377377
unsigned int acl_size;
378378
char *acl_base;
379379
struct smb_ace **ppace;
@@ -394,12 +394,12 @@ static void parse_dacl(struct mnt_idmap *idmap,
394394

395395
ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n",
396396
le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
397-
le32_to_cpu(pdacl->num_aces));
397+
le16_to_cpu(pdacl->num_aces));
398398

399399
acl_base = (char *)pdacl;
400400
acl_size = sizeof(struct smb_acl);
401401

402-
num_aces = le32_to_cpu(pdacl->num_aces);
402+
num_aces = le16_to_cpu(pdacl->num_aces);
403403
if (num_aces <= 0)
404404
return;
405405

@@ -589,7 +589,7 @@ static void parse_dacl(struct mnt_idmap *idmap,
589589

590590
static void set_posix_acl_entries_dacl(struct mnt_idmap *idmap,
591591
struct smb_ace *pndace,
592-
struct smb_fattr *fattr, u32 *num_aces,
592+
struct smb_fattr *fattr, u16 *num_aces,
593593
u16 *size, u32 nt_aces_num)
594594
{
595595
struct posix_acl_entry *pace;
@@ -717,7 +717,7 @@ static void set_ntacl_dacl(struct mnt_idmap *idmap,
717717
struct smb_fattr *fattr)
718718
{
719719
struct smb_ace *ntace, *pndace;
720-
int nt_num_aces = le32_to_cpu(nt_dacl->num_aces), num_aces = 0;
720+
u16 nt_num_aces = le16_to_cpu(nt_dacl->num_aces), num_aces = 0;
721721
unsigned short size = 0;
722722
int i;
723723

@@ -745,15 +745,15 @@ static void set_ntacl_dacl(struct mnt_idmap *idmap,
745745

746746
set_posix_acl_entries_dacl(idmap, pndace, fattr,
747747
&num_aces, &size, nt_num_aces);
748-
pndacl->num_aces = cpu_to_le32(num_aces);
748+
pndacl->num_aces = cpu_to_le16(num_aces);
749749
pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
750750
}
751751

752752
static void set_mode_dacl(struct mnt_idmap *idmap,
753753
struct smb_acl *pndacl, struct smb_fattr *fattr)
754754
{
755755
struct smb_ace *pace, *pndace;
756-
u32 num_aces = 0;
756+
u16 num_aces = 0;
757757
u16 size = 0, ace_size = 0;
758758
uid_t uid;
759759
const struct smb_sid *sid;
@@ -809,7 +809,7 @@ static void set_mode_dacl(struct mnt_idmap *idmap,
809809
fattr->cf_mode, 0007);
810810

811811
out:
812-
pndacl->num_aces = cpu_to_le32(num_aces);
812+
pndacl->num_aces = cpu_to_le16(num_aces);
813813
pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
814814
}
815815

@@ -1039,8 +1039,9 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
10391039
struct smb_sid owner_sid, group_sid;
10401040
struct dentry *parent = path->dentry->d_parent;
10411041
struct mnt_idmap *idmap = mnt_idmap(path->mnt);
1042-
int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0, pdacl_size;
1043-
int rc = 0, num_aces, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size;
1042+
int inherited_flags = 0, flags = 0, i, nt_size = 0, pdacl_size;
1043+
int rc = 0, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size;
1044+
u16 num_aces, ace_cnt = 0;
10441045
char *aces_base;
10451046
bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
10461047

@@ -1056,7 +1057,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
10561057

10571058
parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset);
10581059
acl_len = pntsd_size - dacloffset;
1059-
num_aces = le32_to_cpu(parent_pdacl->num_aces);
1060+
num_aces = le16_to_cpu(parent_pdacl->num_aces);
10601061
pntsd_type = le16_to_cpu(parent_pntsd->type);
10611062
pdacl_size = le16_to_cpu(parent_pdacl->size);
10621063

@@ -1215,7 +1216,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
12151216
pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
12161217
pdacl->revision = cpu_to_le16(2);
12171218
pdacl->size = cpu_to_le16(sizeof(struct smb_acl) + nt_size);
1218-
pdacl->num_aces = cpu_to_le32(ace_cnt);
1219+
pdacl->num_aces = cpu_to_le16(ace_cnt);
12191220
pace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
12201221
memcpy(pace, aces_base, nt_size);
12211222
pntsd_size += sizeof(struct smb_acl) + nt_size;
@@ -1296,7 +1297,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
12961297

12971298
ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
12981299
aces_size = acl_size - sizeof(struct smb_acl);
1299-
for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1300+
for (i = 0; i < le16_to_cpu(pdacl->num_aces); i++) {
13001301
if (offsetof(struct smb_ace, access_req) > aces_size)
13011302
break;
13021303
ace_size = le16_to_cpu(ace->size);
@@ -1317,7 +1318,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
13171318

13181319
ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
13191320
aces_size = acl_size - sizeof(struct smb_acl);
1320-
for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1321+
for (i = 0; i < le16_to_cpu(pdacl->num_aces); i++) {
13211322
if (offsetof(struct smb_ace, access_req) > aces_size)
13221323
break;
13231324
ace_size = le16_to_cpu(ace->size);

fs/smb/server/smbacl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
8686
int build_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
8787
struct smb_ntsd *ppntsd, int ppntsd_size, int addition_info,
8888
__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);
9090
void free_acl_state(struct posix_acl_state *state);
9191
void posix_state_to_acl(struct posix_acl_state *state,
9292
struct posix_acl_entry *pace);

0 commit comments

Comments
 (0)