Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c14e43a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull cifs fixes from Steve French:

 - one smb3 (ACL related) fix for stable

 - one SMB3 security enhancement (when mounting -t smb3 forbid less
   secure dialects)

 - some RDMA and compounding fixes

* tag '4.18-fixes-smb3' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: fix a buffer leak in smb2_query_symlink
  smb3: do not allow insecure cifs mounts when using smb3
  CIFS: Fix NULL ptr deref
  CIFS: fix encryption in SMB3.1.1
  CIFS: Pass page offset for encrypting
  CIFS: Pass page offset for calculating signature
  CIFS: SMBD: Support page offset in memory registration
  CIFS: SMBD: Support page offset in RDMA recv
  CIFS: SMBD: Support page offset in RDMA send
  CIFS: When sending data on socket, pass the correct page offset
  CIFS: Introduce helper function to get page offset and length in smb_rqst
  CIFS: Calculate the correct request length based on page offset and tail size
  cifs: For SMB2 security informaion query, check for minimum sized security descriptor instead of sizeof FileAllInformation class
  CIFS: Fix signing for SMB2/3
parents bbaa1013 9d874c36
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -98,4 +98,18 @@ struct cifs_ace {
	struct cifs_sid sid; /* ie UUID of user or group who gets these perms */
} __attribute__((packed));

/*
 * Minimum security identifier can be one for system defined Users
 * and Groups such as NULL SID and World or Built-in accounts such
 * as Administrator and Guest and consists of
 * Revision + Num (Sub)Auths + Authority + Domain (one Subauthority)
 */
#define MIN_SID_LEN  (1 + 1 + 6 + 4) /* in bytes */

/*
 * Minimum security descriptor can be one without any SACL and DACL and can
 * consist of revision, type, and two sids of minimum size for owner and group
 */
#define MIN_SEC_DESC_LEN  (sizeof(struct cifs_ntsd) + (2 * MIN_SID_LEN))

#endif /* _CIFSACL_H */
+8 −9
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include <crypto/aead.h>

int __cifs_calc_signature(struct smb_rqst *rqst,
			int start,
			struct TCP_Server_Info *server, char *signature,
			struct shash_desc *shash)
{
@@ -45,10 +46,7 @@ int __cifs_calc_signature(struct smb_rqst *rqst,
	struct kvec *iov = rqst->rq_iov;
	int n_vec = rqst->rq_nvec;

	if (n_vec < 2 || iov[0].iov_len != 4)
		return -EIO;

	for (i = 1; i < n_vec; i++) {
	for (i = start; i < n_vec; i++) {
		if (iov[i].iov_len == 0)
			continue;
		if (iov[i].iov_base == NULL) {
@@ -68,11 +66,12 @@ int __cifs_calc_signature(struct smb_rqst *rqst,

	/* now hash over the rq_pages array */
	for (i = 0; i < rqst->rq_npages; i++) {
		void *kaddr = kmap(rqst->rq_pages[i]);
		size_t len = rqst->rq_pagesz;
		void *kaddr;
		unsigned int len, offset;

		rqst_page_get_length(rqst, i, &len, &offset);

		if (i == rqst->rq_npages - 1)
			len = rqst->rq_tailsz;
		kaddr = (char *) kmap(rqst->rq_pages[i]) + offset;

		crypto_shash_update(shash, kaddr, len);

@@ -119,7 +118,7 @@ static int cifs_calc_signature(struct smb_rqst *rqst,
		return rc;
	}

	return __cifs_calc_signature(rqst, server, signature,
	return __cifs_calc_signature(rqst, 1, server, signature,
				     &server->secmech.sdescmd5->shash);
}

+18 −4
Original line number Diff line number Diff line
@@ -698,8 +698,8 @@ static int cifs_set_super(struct super_block *sb, void *data)
}

static struct dentry *
cifs_do_mount(struct file_system_type *fs_type,
	      int flags, const char *dev_name, void *data)
cifs_smb3_do_mount(struct file_system_type *fs_type,
	      int flags, const char *dev_name, void *data, bool is_smb3)
{
	int rc;
	struct super_block *sb;
@@ -710,7 +710,7 @@ cifs_do_mount(struct file_system_type *fs_type,

	cifs_dbg(FYI, "Devname: %s flags: %d\n", dev_name, flags);

	volume_info = cifs_get_volume_info((char *)data, dev_name);
	volume_info = cifs_get_volume_info((char *)data, dev_name, is_smb3);
	if (IS_ERR(volume_info))
		return ERR_CAST(volume_info);

@@ -790,6 +790,20 @@ cifs_do_mount(struct file_system_type *fs_type,
	goto out;
}

static struct dentry *
smb3_do_mount(struct file_system_type *fs_type,
	      int flags, const char *dev_name, void *data)
{
	return cifs_smb3_do_mount(fs_type, flags, dev_name, data, true);
}

static struct dentry *
cifs_do_mount(struct file_system_type *fs_type,
	      int flags, const char *dev_name, void *data)
{
	return cifs_smb3_do_mount(fs_type, flags, dev_name, data, false);
}

static ssize_t
cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{
@@ -925,7 +939,7 @@ MODULE_ALIAS_FS("cifs");
static struct file_system_type smb3_fs_type = {
	.owner = THIS_MODULE,
	.name = "smb3",
	.mount = cifs_do_mount,
	.mount = smb3_do_mount,
	.kill_sb = cifs_kill_sb,
	/*  .fs_flags */
};
+6 −0
Original line number Diff line number Diff line
@@ -1019,6 +1019,12 @@ tlink_tcon(struct tcon_link *tlink)
	return tlink->tl_tcon;
}

static inline struct tcon_link *
cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
{
	return cifs_sb->master_tlink;
}

extern void cifs_put_tlink(struct tcon_link *tlink);

static inline struct tcon_link *
+5 −2
Original line number Diff line number Diff line
@@ -211,7 +211,7 @@ extern int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
extern int cifs_match_super(struct super_block *, void *);
extern void cifs_cleanup_volume_info(struct smb_vol *pvolume_info);
extern struct smb_vol *cifs_get_volume_info(char *mount_data,
					    const char *devname);
					    const char *devname, bool is_smb3);
extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *);
extern void cifs_umount(struct cifs_sb_info *);
extern void cifs_mark_open_files_invalid(struct cifs_tcon *tcon);
@@ -544,7 +544,7 @@ int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
			   struct cifs_sb_info *cifs_sb,
			   const unsigned char *path, char *pbuf,
			   unsigned int *pbytes_written);
int __cifs_calc_signature(struct smb_rqst *rqst,
int __cifs_calc_signature(struct smb_rqst *rqst, int start,
			struct TCP_Server_Info *server, char *signature,
			struct shash_desc *shash);
enum securityEnum cifs_select_sectype(struct TCP_Server_Info *,
@@ -557,4 +557,7 @@ int cifs_alloc_hash(const char *name, struct crypto_shash **shash,
		    struct sdesc **sdesc);
void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);

extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
				unsigned int *len, unsigned int *offset);

#endif			/* _CIFSPROTO_H */
Loading