]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
smb3: fix various xid leaks
authorSteve French <stfrench@microsoft.com>
Sat, 19 May 2018 07:04:55 +0000 (02:04 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Jun 2018 23:54:00 +0000 (07:54 +0800)
commit cfe89091644c441a1ade6dae6d2e47b715648615 upstream.

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: Steve French <smfrench@gmail.com>
CC: Stable <stable@vger.kernel.org>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/cifs/smb2ops.c

index 097598543403dd63af538c9a6280852d0a9fada1..75b6995419beaf6b5bb72cf753dfdc23c044aa5b 100644 (file)
@@ -1589,8 +1589,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;
@@ -1648,8 +1651,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;
@@ -1709,15 +1715,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
@@ -1726,8 +1738,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);
 
@@ -1760,8 +1775,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);
 
@@ -1792,8 +1810,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
@@ -1802,14 +1822,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)) {
@@ -1821,8 +1843,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);
        }