Commit d4e90419 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag '5.10-rc6-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
 "Three smb3 fixes (two for stable) fixing

   - a null pointer issue in a DFS error path

   - a problem with excessive padding when mounted with "idsfromsid"
     causing owner fields to get corrupted

   - a more recent problem with compounded reparse point query found in
     testing to the Linux kernel server"

* tag '5.10-rc6-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: refactor create_sd_buf() and and avoid corrupting the buffer
  cifs: add NULL check for ses->tcon_ipc
  smb3: set COMPOUND_FID to FileID field of subsequent compound request
parents 312b0bcd ea64370b
...@@ -4546,7 +4546,8 @@ static void set_root_ses(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, ...@@ -4546,7 +4546,8 @@ static void set_root_ses(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
if (ses) { if (ses) {
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
ses->ses_count++; ses->ses_count++;
ses->tcon_ipc->remap = cifs_remap(cifs_sb); if (ses->tcon_ipc)
ses->tcon_ipc->remap = cifs_remap(cifs_sb);
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
} }
*root_ses = ses; *root_ses = ses;
......
...@@ -3114,8 +3114,8 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -3114,8 +3114,8 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE; rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
rc = SMB2_ioctl_init(tcon, server, rc = SMB2_ioctl_init(tcon, server,
&rqst[1], fid.persistent_fid, &rqst[1], COMPOUND_FID,
fid.volatile_fid, FSCTL_GET_REPARSE_POINT, COMPOUND_FID, FSCTL_GET_REPARSE_POINT,
true /* is_fctl */, NULL, 0, true /* is_fctl */, NULL, 0,
CIFSMaxBufSize - CIFSMaxBufSize -
MAX_SMB2_CREATE_RESPONSE_SIZE - MAX_SMB2_CREATE_RESPONSE_SIZE -
......
...@@ -2272,17 +2272,15 @@ static struct crt_sd_ctxt * ...@@ -2272,17 +2272,15 @@ static struct crt_sd_ctxt *
create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
{ {
struct crt_sd_ctxt *buf; struct crt_sd_ctxt *buf;
struct cifs_ace *pace; __u8 *ptr, *aclptr;
unsigned int sdlen, acelen; unsigned int acelen, acl_size, ace_count;
unsigned int owner_offset = 0; unsigned int owner_offset = 0;
unsigned int group_offset = 0; unsigned int group_offset = 0;
struct smb3_acl acl;
*len = roundup(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 2), 8); *len = roundup(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 4), 8);
if (set_owner) { if (set_owner) {
/* offset fields are from beginning of security descriptor not of create context */
owner_offset = sizeof(struct smb3_acl) + (sizeof(struct cifs_ace) * 2);
/* sizeof(struct owner_group_sids) is already multiple of 8 so no need to round */ /* sizeof(struct owner_group_sids) is already multiple of 8 so no need to round */
*len += sizeof(struct owner_group_sids); *len += sizeof(struct owner_group_sids);
} }
...@@ -2291,26 +2289,22 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) ...@@ -2291,26 +2289,22 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
if (buf == NULL) if (buf == NULL)
return buf; return buf;
ptr = (__u8 *)&buf[1];
if (set_owner) { if (set_owner) {
/* offset fields are from beginning of security descriptor not of create context */
owner_offset = ptr - (__u8 *)&buf->sd;
buf->sd.OffsetOwner = cpu_to_le32(owner_offset); buf->sd.OffsetOwner = cpu_to_le32(owner_offset);
group_offset = owner_offset + sizeof(struct owner_sid); group_offset = owner_offset + offsetof(struct owner_group_sids, group);
buf->sd.OffsetGroup = cpu_to_le32(group_offset); buf->sd.OffsetGroup = cpu_to_le32(group_offset);
setup_owner_group_sids(ptr);
ptr += sizeof(struct owner_group_sids);
} else { } else {
buf->sd.OffsetOwner = 0; buf->sd.OffsetOwner = 0;
buf->sd.OffsetGroup = 0; buf->sd.OffsetGroup = 0;
} }
sdlen = sizeof(struct smb3_sd) + sizeof(struct smb3_acl) + buf->ccontext.DataOffset = cpu_to_le16(offsetof(struct crt_sd_ctxt, sd));
2 * sizeof(struct cifs_ace);
if (set_owner) {
sdlen += sizeof(struct owner_group_sids);
setup_owner_group_sids(owner_offset + sizeof(struct create_context) + 8 /* name */
+ (char *)buf);
}
buf->ccontext.DataOffset = cpu_to_le16(offsetof
(struct crt_sd_ctxt, sd));
buf->ccontext.DataLength = cpu_to_le32(sdlen);
buf->ccontext.NameOffset = cpu_to_le16(offsetof(struct crt_sd_ctxt, Name)); buf->ccontext.NameOffset = cpu_to_le16(offsetof(struct crt_sd_ctxt, Name));
buf->ccontext.NameLength = cpu_to_le16(4); buf->ccontext.NameLength = cpu_to_le16(4);
/* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */ /* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */
...@@ -2319,6 +2313,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) ...@@ -2319,6 +2313,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
buf->Name[2] = 'c'; buf->Name[2] = 'c';
buf->Name[3] = 'D'; buf->Name[3] = 'D';
buf->sd.Revision = 1; /* Must be one see MS-DTYP 2.4.6 */ buf->sd.Revision = 1; /* Must be one see MS-DTYP 2.4.6 */
/* /*
* ACL is "self relative" ie ACL is stored in contiguous block of memory * ACL is "self relative" ie ACL is stored in contiguous block of memory
* and "DP" ie the DACL is present * and "DP" ie the DACL is present
...@@ -2326,28 +2321,38 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) ...@@ -2326,28 +2321,38 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
buf->sd.Control = cpu_to_le16(ACL_CONTROL_SR | ACL_CONTROL_DP); buf->sd.Control = cpu_to_le16(ACL_CONTROL_SR | ACL_CONTROL_DP);
/* offset owner, group and Sbz1 and SACL are all zero */ /* offset owner, group and Sbz1 and SACL are all zero */
buf->sd.OffsetDacl = cpu_to_le32(sizeof(struct smb3_sd)); buf->sd.OffsetDacl = cpu_to_le32(ptr - (__u8 *)&buf->sd);
buf->acl.AclRevision = ACL_REVISION; /* See 2.4.4.1 of MS-DTYP */ /* Ship the ACL for now. we will copy it into buf later. */
aclptr = ptr;
ptr += sizeof(struct cifs_acl);
/* create one ACE to hold the mode embedded in reserved special SID */ /* create one ACE to hold the mode embedded in reserved special SID */
pace = (struct cifs_ace *)(sizeof(struct crt_sd_ctxt) + (char *)buf); acelen = setup_special_mode_ACE((struct cifs_ace *)ptr, (__u64)mode);
acelen = setup_special_mode_ACE(pace, (__u64)mode); ptr += acelen;
acl_size = acelen + sizeof(struct smb3_acl);
ace_count = 1;
if (set_owner) { if (set_owner) {
/* we do not need to reallocate buffer to add the two more ACEs. plenty of space */ /* we do not need to reallocate buffer to add the two more ACEs. plenty of space */
pace = (struct cifs_ace *)(acelen + (sizeof(struct crt_sd_ctxt) + (char *)buf)); acelen = setup_special_user_owner_ACE((struct cifs_ace *)ptr);
acelen += setup_special_user_owner_ACE(pace); ptr += acelen;
/* it does not appear necessary to add an ACE for the NFS group SID */ acl_size += acelen;
buf->acl.AceCount = cpu_to_le16(3); ace_count += 1;
} else }
buf->acl.AceCount = cpu_to_le16(2);
/* and one more ACE to allow access for authenticated users */ /* and one more ACE to allow access for authenticated users */
pace = (struct cifs_ace *)(acelen + (sizeof(struct crt_sd_ctxt) + acelen = setup_authusers_ACE((struct cifs_ace *)ptr);
(char *)buf)); ptr += acelen;
acelen += setup_authusers_ACE(pace); acl_size += acelen;
ace_count += 1;
buf->acl.AclSize = cpu_to_le16(sizeof(struct cifs_acl) + acelen);
acl.AclRevision = ACL_REVISION; /* See 2.4.4.1 of MS-DTYP */
acl.AclSize = cpu_to_le16(acl_size);
acl.AceCount = cpu_to_le16(ace_count);
memcpy(aclptr, &acl, sizeof(struct cifs_acl));
buf->ccontext.DataLength = cpu_to_le32(ptr - (__u8 *)&buf->sd);
*len = ptr - (__u8 *)buf;
return buf; return buf;
} }
......
...@@ -963,8 +963,6 @@ struct crt_sd_ctxt { ...@@ -963,8 +963,6 @@ struct crt_sd_ctxt {
struct create_context ccontext; struct create_context ccontext;
__u8 Name[8]; __u8 Name[8];
struct smb3_sd sd; struct smb3_sd sd;
struct smb3_acl acl;
/* Followed by at least 4 ACEs */
} __packed; } __packed;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment