Skip to content

Commit ea64370

Browse files
Ronnie Sahlbergsmfrench
authored andcommitted
cifs: refactor create_sd_buf() and and avoid corrupting the buffer
When mounting with "idsfromsid" mount option, Azure corrupted the owner SIDs due to excessive padding caused by placing the owner fields at the end of the security descriptor on create. Placing owners at the front of the security descriptor (rather than the end) is also safer, as the number of ACEs (that follow it) are variable. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Suggested-by: Rohith Surabattula <rohiths@microsoft.com> CC: Stable <stable@vger.kernel.org> # v5.8 Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 59463eb commit ea64370

2 files changed

Lines changed: 38 additions & 35 deletions

File tree

fs/cifs/smb2pdu.c

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2272,17 +2272,15 @@ static struct crt_sd_ctxt *
22722272
create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
22732273
{
22742274
struct crt_sd_ctxt *buf;
2275-
struct cifs_ace *pace;
2276-
unsigned int sdlen, acelen;
2275+
__u8 *ptr, *aclptr;
2276+
unsigned int acelen, acl_size, ace_count;
22772277
unsigned int owner_offset = 0;
22782278
unsigned int group_offset = 0;
2279+
struct smb3_acl acl;
22792280

2280-
*len = roundup(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 2), 8);
2281+
*len = roundup(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 4), 8);
22812282

22822283
if (set_owner) {
2283-
/* offset fields are from beginning of security descriptor not of create context */
2284-
owner_offset = sizeof(struct smb3_acl) + (sizeof(struct cifs_ace) * 2);
2285-
22862284
/* sizeof(struct owner_group_sids) is already multiple of 8 so no need to round */
22872285
*len += sizeof(struct owner_group_sids);
22882286
}
@@ -2291,26 +2289,22 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
22912289
if (buf == NULL)
22922290
return buf;
22932291

2292+
ptr = (__u8 *)&buf[1];
22942293
if (set_owner) {
2294+
/* offset fields are from beginning of security descriptor not of create context */
2295+
owner_offset = ptr - (__u8 *)&buf->sd;
22952296
buf->sd.OffsetOwner = cpu_to_le32(owner_offset);
2296-
group_offset = owner_offset + sizeof(struct owner_sid);
2297+
group_offset = owner_offset + offsetof(struct owner_group_sids, group);
22972298
buf->sd.OffsetGroup = cpu_to_le32(group_offset);
2299+
2300+
setup_owner_group_sids(ptr);
2301+
ptr += sizeof(struct owner_group_sids);
22982302
} else {
22992303
buf->sd.OffsetOwner = 0;
23002304
buf->sd.OffsetGroup = 0;
23012305
}
23022306

2303-
sdlen = sizeof(struct smb3_sd) + sizeof(struct smb3_acl) +
2304-
2 * sizeof(struct cifs_ace);
2305-
if (set_owner) {
2306-
sdlen += sizeof(struct owner_group_sids);
2307-
setup_owner_group_sids(owner_offset + sizeof(struct create_context) + 8 /* name */
2308-
+ (char *)buf);
2309-
}
2310-
2311-
buf->ccontext.DataOffset = cpu_to_le16(offsetof
2312-
(struct crt_sd_ctxt, sd));
2313-
buf->ccontext.DataLength = cpu_to_le32(sdlen);
2307+
buf->ccontext.DataOffset = cpu_to_le16(offsetof(struct crt_sd_ctxt, sd));
23142308
buf->ccontext.NameOffset = cpu_to_le16(offsetof(struct crt_sd_ctxt, Name));
23152309
buf->ccontext.NameLength = cpu_to_le16(4);
23162310
/* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */
@@ -2319,35 +2313,46 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
23192313
buf->Name[2] = 'c';
23202314
buf->Name[3] = 'D';
23212315
buf->sd.Revision = 1; /* Must be one see MS-DTYP 2.4.6 */
2316+
23222317
/*
23232318
* ACL is "self relative" ie ACL is stored in contiguous block of memory
23242319
* and "DP" ie the DACL is present
23252320
*/
23262321
buf->sd.Control = cpu_to_le16(ACL_CONTROL_SR | ACL_CONTROL_DP);
23272322

23282323
/* offset owner, group and Sbz1 and SACL are all zero */
2329-
buf->sd.OffsetDacl = cpu_to_le32(sizeof(struct smb3_sd));
2330-
buf->acl.AclRevision = ACL_REVISION; /* See 2.4.4.1 of MS-DTYP */
2324+
buf->sd.OffsetDacl = cpu_to_le32(ptr - (__u8 *)&buf->sd);
2325+
/* Ship the ACL for now. we will copy it into buf later. */
2326+
aclptr = ptr;
2327+
ptr += sizeof(struct cifs_acl);
23312328

23322329
/* create one ACE to hold the mode embedded in reserved special SID */
2333-
pace = (struct cifs_ace *)(sizeof(struct crt_sd_ctxt) + (char *)buf);
2334-
acelen = setup_special_mode_ACE(pace, (__u64)mode);
2330+
acelen = setup_special_mode_ACE((struct cifs_ace *)ptr, (__u64)mode);
2331+
ptr += acelen;
2332+
acl_size = acelen + sizeof(struct smb3_acl);
2333+
ace_count = 1;
23352334

23362335
if (set_owner) {
23372336
/* we do not need to reallocate buffer to add the two more ACEs. plenty of space */
2338-
pace = (struct cifs_ace *)(acelen + (sizeof(struct crt_sd_ctxt) + (char *)buf));
2339-
acelen += setup_special_user_owner_ACE(pace);
2340-
/* it does not appear necessary to add an ACE for the NFS group SID */
2341-
buf->acl.AceCount = cpu_to_le16(3);
2342-
} else
2343-
buf->acl.AceCount = cpu_to_le16(2);
2337+
acelen = setup_special_user_owner_ACE((struct cifs_ace *)ptr);
2338+
ptr += acelen;
2339+
acl_size += acelen;
2340+
ace_count += 1;
2341+
}
23442342

23452343
/* and one more ACE to allow access for authenticated users */
2346-
pace = (struct cifs_ace *)(acelen + (sizeof(struct crt_sd_ctxt) +
2347-
(char *)buf));
2348-
acelen += setup_authusers_ACE(pace);
2349-
2350-
buf->acl.AclSize = cpu_to_le16(sizeof(struct cifs_acl) + acelen);
2344+
acelen = setup_authusers_ACE((struct cifs_ace *)ptr);
2345+
ptr += acelen;
2346+
acl_size += acelen;
2347+
ace_count += 1;
2348+
2349+
acl.AclRevision = ACL_REVISION; /* See 2.4.4.1 of MS-DTYP */
2350+
acl.AclSize = cpu_to_le16(acl_size);
2351+
acl.AceCount = cpu_to_le16(ace_count);
2352+
memcpy(aclptr, &acl, sizeof(struct cifs_acl));
2353+
2354+
buf->ccontext.DataLength = cpu_to_le32(ptr - (__u8 *)&buf->sd);
2355+
*len = ptr - (__u8 *)buf;
23512356

23522357
return buf;
23532358
}

fs/cifs/smb2pdu.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -963,8 +963,6 @@ struct crt_sd_ctxt {
963963
struct create_context ccontext;
964964
__u8 Name[8];
965965
struct smb3_sd sd;
966-
struct smb3_acl acl;
967-
/* Followed by at least 4 ACEs */
968966
} __packed;
969967

970968

0 commit comments

Comments
 (0)