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

Commit cfe89091 authored by Steve French's avatar Steve French
Browse files

smb3: fix various xid leaks



Fix a few cases where we were not freeing the xid which led to
active requests being non-zero at unmount time.

Signed-off-by: default avatarSteve French <smfrench@gmail.com>
CC: Stable <stable@vger.kernel.org>
Reviewed-by: default avatarRonnie Sahlberg <lsahlber@redhat.com>
parent 57a929a6
Loading
Loading
Loading
Loading
+44 −19
Original line number Diff line number Diff line
@@ -1637,8 +1637,11 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb,
		oparms.create_options = 0;

	utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
	if (!utf16_path)
		return ERR_PTR(-ENOMEM);
	if (!utf16_path) {
		rc = -ENOMEM;
		free_xid(xid);
		return ERR_PTR(rc);
	}

	oparms.tcon = tcon;
	oparms.desired_access = READ_CONTROL;
@@ -1696,8 +1699,11 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
		access_flags = WRITE_DAC;

	utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
	if (!utf16_path)
		return -ENOMEM;
	if (!utf16_path) {
		rc = -ENOMEM;
		free_xid(xid);
		return rc;
	}

	oparms.tcon = tcon;
	oparms.desired_access = access_flags;
@@ -1757,15 +1763,21 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,

	/* if file not oplocked can't be sure whether asking to extend size */
	if (!CIFS_CACHE_READ(cifsi))
		if (keep_size == false)
			return -EOPNOTSUPP;
		if (keep_size == false) {
			rc = -EOPNOTSUPP;
			free_xid(xid);
			return rc;
		}

	/*
	 * Must check if file sparse since fallocate -z (zero range) assumes
	 * non-sparse allocation
	 */
	if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE))
		return -EOPNOTSUPP;
	if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE)) {
		rc = -EOPNOTSUPP;
		free_xid(xid);
		return rc;
	}

	/*
	 * need to make sure we are not asked to extend the file since the SMB3
@@ -1774,8 +1786,11 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
	 * which for a non sparse file would zero the newly extended range
	 */
	if (keep_size == false)
		if (i_size_read(inode) < offset + len)
			return -EOPNOTSUPP;
		if (i_size_read(inode) < offset + len) {
			rc = -EOPNOTSUPP;
			free_xid(xid);
			return rc;
		}

	cifs_dbg(FYI, "offset %lld len %lld", offset, len);

@@ -1808,8 +1823,11 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,

	/* Need to make file sparse, if not already, before freeing range. */
	/* Consider adding equivalent for compressed since it could also work */
	if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse))
		return -EOPNOTSUPP;
	if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse)) {
		rc = -EOPNOTSUPP;
		free_xid(xid);
		return rc;
	}

	cifs_dbg(FYI, "offset %lld len %lld", offset, len);

@@ -1840,8 +1858,10 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,

	/* if file not oplocked can't be sure whether asking to extend size */
	if (!CIFS_CACHE_READ(cifsi))
		if (keep_size == false)
			return -EOPNOTSUPP;
		if (keep_size == false) {
			free_xid(xid);
			return rc;
		}

	/*
	 * Files are non-sparse by default so falloc may be a no-op
@@ -1850,14 +1870,16 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
	 */
	if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) == 0) {
		if (keep_size == true)
			return 0;
			rc = 0;
		/* check if extending file */
		else if (i_size_read(inode) >= off + len)
			/* not extending file and already not sparse */
			return 0;
			rc = 0;
		/* BB: in future add else clause to extend file */
		else
			return -EOPNOTSUPP;
			rc = -EOPNOTSUPP;
		free_xid(xid);
		return rc;
	}

	if ((keep_size == true) || (i_size_read(inode) >= off + len)) {
@@ -1869,8 +1891,11 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
		 * ie potentially making a few extra pages at the beginning
		 * or end of the file non-sparse via set_sparse is harmless.
		 */
		if ((off > 8192) || (off + len + 8192 < i_size_read(inode)))
			return -EOPNOTSUPP;
		if ((off > 8192) || (off + len + 8192 < i_size_read(inode))) {
			rc = -EOPNOTSUPP;
			free_xid(xid);
			return rc;
		}

		rc = smb2_set_sparse(xid, tcon, cfile, inode, false);
	}