]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
cifs_atomic_open(): fix double-put on late allocation failure
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 12 Mar 2020 22:25:20 +0000 (18:25 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Mar 2020 06:14:21 +0000 (07:14 +0100)
commit d9a9f4849fe0c9d560851ab22a85a666cddfdd24 upstream.

several iterations of ->atomic_open() calling conventions ago, we
used to need fput() if ->atomic_open() failed at some point after
successful finish_open().  Now (since 2016) it's not needed -
struct file carries enough state to make fput() work regardless
of the point in struct file lifecycle and discarding it on
failure exits in open() got unified.  Unfortunately, I'd missed
the fact that we had an instance of ->atomic_open() (cifs one)
that used to need that fput(), as well as the stale comment in
finish_open() demanding such late failure handling.  Trivially
fixed...

Fixes: fe9ec8291fca "do_last(): take fput() on error after opening to out:"
Cc: stable@kernel.org # v4.7+
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/filesystems/porting
fs/cifs/dir.c
fs/open.c

index 32b5186be41264f3f85ec552ea07451a3dcd00ea..041b0ded8b4422a3bcaf330d43be7513e888968c 100644 (file)
@@ -627,3 +627,10 @@ in your dentry operations instead.
        DCACHE_RCUACCESS is gone; having an RCU delay on dentry freeing is the
        default.  DCACHE_NORCU opts out, and only d_alloc_pseudo() has any
        business doing so.
+--
+[mandatory]
+
+       [should've been added in 2016] stale comment in finish_open()
+       nonwithstanding, failure exits in ->atomic_open() instances should
+       *NOT* fput() the file, no matter what.  Everything is handled by the
+       caller.
index 2fb6fa51fd3ceab398cce84829318a3e79c9dadc..f6e3c008982541aa4f49c37a47a206a87c8430a1 100644 (file)
@@ -561,7 +561,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
                if (server->ops->close)
                        server->ops->close(xid, tcon, &fid);
                cifs_del_pending_open(&open);
-               fput(file);
                rc = -ENOMEM;
        }
 
index 878478745924b8ac6e324ab0bb7b2624a4d6684d..76996f920ebf5ac10bdfffcffe41bcfc5248c452 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -851,9 +851,6 @@ cleanup_file:
  * the return value of d_splice_alias(), then the caller needs to perform dput()
  * on it after finish_open().
  *
- * On successful return @file is a fully instantiated open file.  After this, if
- * an error occurs in ->atomic_open(), it needs to clean up with fput().
- *
  * Returns zero on success or -errno if the open failed.
  */
 int finish_open(struct file *file, struct dentry *dentry,