]> git.baikalelectronics.ru Git - kernel.git/commitdiff
fix the breakage in close_fd_get_file() calling conventions change
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 5 Jun 2022 18:01:42 +0000 (14:01 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 5 Jun 2022 19:03:03 +0000 (15:03 -0400)
It used to grab an extra reference to struct file rather than
just transferring to caller the one it had removed from descriptor
table.  New variant doesn't, and callers need to be adjusted.

Reported-and-tested-by: syzbot+47dd250f527cb7bebf24@syzkaller.appspotmail.com
Fixes: 8d392c99b321 ("Unify the primitives for file descriptor closing")
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
drivers/android/binder.c
fs/file.c
fs/io_uring.c

index 27c9b004823aa949e3735a88a2c075ecaf0ccdb9..73beea5dc18c94c5c7237514212258c23b78edc6 100644 (file)
@@ -1857,6 +1857,8 @@ static void binder_deferred_fd_close(int fd)
        init_task_work(&twcb->twork, binder_do_fd_close);
        twcb->file = close_fd_get_file(fd);
        if (twcb->file) {
+               // pin it until binder_do_fd_close(); see comments there
+               get_file(twcb->file);
                filp_close(twcb->file, current->files);
                task_work_add(current, &twcb->twork, TWA_RESUME);
        } else {
index dd6692048f4f1111dc7047b964723ff0d03ebafb..3bcc1ecc314a78e90daedecf6a7ec575c642504a 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -800,8 +800,7 @@ struct file *__close_fd_get_file(unsigned int fd)
 
 /*
  * variant of close_fd that gets a ref on the file for later fput.
- * The caller must ensure that filp_close() called on the file, and then
- * an fput().
+ * The caller must ensure that filp_close() called on the file.
  */
 struct file *close_fd_get_file(unsigned int fd)
 {
index 7257b087035371c49f282f2677288f649726d3de..33da5116cc38ca4062750f52bf2843749e152ade 100644 (file)
@@ -5110,7 +5110,7 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags)
        struct files_struct *files = current->files;
        struct io_close *close = &req->close;
        struct fdtable *fdt;
-       struct file *file = NULL;
+       struct file *file;
        int ret = -EBADF;
 
        if (req->close.file_slot) {
@@ -5127,7 +5127,6 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags)
        file = fdt->fd[close->fd];
        if (!file || file->f_op == &io_uring_fops) {
                spin_unlock(&files->file_lock);
-               file = NULL;
                goto err;
        }
 
@@ -5147,8 +5146,6 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags)
 err:
        if (ret < 0)
                req_set_fail(req);
-       if (file)
-               fput(file);
        __io_req_complete(req, issue_flags, ret, 0);
        return 0;
 }