Commit a78f7cdd authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull cifs fixes from Steve French:
 "Nine cifs/smb3 fixes:

   - one fix for stable (oops during oplock break)

   - two timestamp fixes including important one for updating mtime at
     close to avoid stale metadata caching issue on dirty files (also
     improves perf by using SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB over the
     wire)

   - two fixes for "modefromsid" mount option for file create (now
     allows mode bits to be set more atomically and accurately on create
     by adding "sd_context" on create when modefromsid specified on
     mount)

   - two fixes for multichannel found in testing this week against
     different servers

   - two small cleanup patches"

* tag '5.5-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6:
  smb3: improve check for when we send the security descriptor context on create
  smb3: fix mode passed in on create for modetosid mount option
  cifs: fix possible uninitialized access and race on iface_list
  cifs: Fix lookup of SMB connections on multichannel
  smb3: query attributes on file close
  smb3: remove unused flag passed into close functions
  cifs: remove redundant assignment to pointer pneg_ctxt
  fs: cifs: Fix atime update check vs mtime
  CIFS: Fix NULL-pointer dereference in smb2_push_mandatory_locks
parents 5bf9a06a 231e2a0b
Loading
Loading
Loading
Loading
+26 −16
Original line number Diff line number Diff line
@@ -802,6 +802,31 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
	return;
}

/*
 * Fill in the special SID based on the mode. See
 * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
 */
unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
{
	int i;
	unsigned int ace_size = 28;

	pntace->type = ACCESS_DENIED_ACE_TYPE;
	pntace->flags = 0x0;
	pntace->access_req = 0;
	pntace->sid.num_subauth = 3;
	pntace->sid.revision = 1;
	for (i = 0; i < NUM_AUTHS; i++)
		pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];

	pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
	pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
	pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);

	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
	pntace->size = cpu_to_le16(ace_size);
	return ace_size;
}

static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
			struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
@@ -815,23 +840,8 @@ static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
	if (modefromsid) {
		struct cifs_ace *pntace =
			(struct cifs_ace *)((char *)pnndacl + size);
		int i;

		pntace->type = ACCESS_ALLOWED;
		pntace->flags = 0x0;
		pntace->access_req = 0;
		pntace->sid.num_subauth = 3;
		pntace->sid.revision = 1;
		for (i = 0; i < NUM_AUTHS; i++)
			pntace->sid.authority[i] =
				sid_unix_NFS_mode.authority[i];
		pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
		pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
		pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);

		/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
		pntace->size = cpu_to_le16(28);
		size += 28;
		size += setup_special_mode_ACE(pntace, nmode);
		num_aces++;
	}

+16 −16
Original line number Diff line number Diff line
@@ -147,22 +147,22 @@ struct smb3_sd {
} __packed;

/* Meaning of 'Control' field flags */
#define ACL_CONTROL_SR	0x0001	/* Self relative */
#define ACL_CONTROL_RM	0x0002	/* Resource manager control bits */
#define ACL_CONTROL_PS	0x0004	/* SACL protected from inherits */
#define ACL_CONTROL_PD	0x0008	/* DACL protected from inherits */
#define ACL_CONTROL_SI	0x0010	/* SACL Auto-Inherited */
#define ACL_CONTROL_DI	0x0020	/* DACL Auto-Inherited */
#define ACL_CONTROL_SC	0x0040	/* SACL computed through inheritance */
#define ACL_CONTROL_DC	0x0080	/* DACL computed through inheritence */
#define ACL_CONTROL_SS	0x0100	/* Create server ACL */
#define ACL_CONTROL_DT	0x0200	/* DACL provided by trusteed source */
#define ACL_CONTROL_SD	0x0400	/* SACL defaulted */
#define ACL_CONTROL_SP	0x0800	/* SACL is present on object */
#define ACL_CONTROL_DD	0x1000	/* DACL defaulted */
#define ACL_CONTROL_DP	0x2000	/* DACL is present on object */
#define ACL_CONTROL_GD	0x4000	/* Group was defaulted */
#define ACL_CONTROL_OD	0x8000	/* User was defaulted */
#define ACL_CONTROL_SR	0x8000	/* Self relative */
#define ACL_CONTROL_RM	0x4000	/* Resource manager control bits */
#define ACL_CONTROL_PS	0x2000	/* SACL protected from inherits */
#define ACL_CONTROL_PD	0x1000	/* DACL protected from inherits */
#define ACL_CONTROL_SI	0x0800	/* SACL Auto-Inherited */
#define ACL_CONTROL_DI	0x0400	/* DACL Auto-Inherited */
#define ACL_CONTROL_SC	0x0200	/* SACL computed through inheritance */
#define ACL_CONTROL_DC	0x0100	/* DACL computed through inheritence */
#define ACL_CONTROL_SS	0x0080	/* Create server ACL */
#define ACL_CONTROL_DT	0x0040	/* DACL provided by trusted source */
#define ACL_CONTROL_SD	0x0020	/* SACL defaulted */
#define ACL_CONTROL_SP	0x0010	/* SACL is present on object */
#define ACL_CONTROL_DD	0x0008	/* DACL defaulted */
#define ACL_CONTROL_DP	0x0004	/* DACL is present on object */
#define ACL_CONTROL_GD	0x0002	/* Group was defaulted */
#define ACL_CONTROL_OD	0x0001	/* User was defaulted */

/* Meaning of AclRevision flags */
#define ACL_REVISION	0x02 /* See section 2.4.4.1 of MS-DTYP */
+4 −0
Original line number Diff line number Diff line
@@ -368,6 +368,9 @@ struct smb_version_operations {
	/* close a file */
	void (*close)(const unsigned int, struct cifs_tcon *,
		      struct cifs_fid *);
	/* close a file, returning file attributes and timestamps */
	void (*close_getattr)(const unsigned int xid, struct cifs_tcon *tcon,
		      struct cifsFileInfo *pfile_info);
	/* send a flush request to the server */
	int (*flush)(const unsigned int, struct cifs_tcon *, struct cifs_fid *);
	/* async read from the server */
@@ -774,6 +777,7 @@ struct TCP_Server_Info {
	 */
	int nr_targets;
	bool noblockcnt; /* use non-blocking connect() */
	bool is_channel; /* if a session channel */
};

struct cifs_credits {
+1 −0
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@ extern struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *,
						const struct cifs_fid *, u32 *);
extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
				const char *, int);
extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode);

extern void dequeue_mid(struct mid_q_entry *mid, bool malformed);
extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
+5 −1
Original line number Diff line number Diff line
@@ -2712,7 +2712,11 @@ cifs_find_tcp_session(struct smb_vol *vol)

	spin_lock(&cifs_tcp_ses_lock);
	list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
		if (!match_server(server, vol))
		/*
		 * Skip ses channels since they're only handled in lower layers
		 * (e.g. cifs_send_recv).
		 */
		if (server->is_channel || !match_server(server, vol))
			continue;

		++server->srv_count;
Loading