Commit 40a19260 authored by Al Viro's avatar Al Viro

fix the breakage in close_fd_get_file() calling conventions change

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: 6319194e ("Unify the primitives for file descriptor closing")
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 6319194e
...@@ -1857,6 +1857,8 @@ static void binder_deferred_fd_close(int fd) ...@@ -1857,6 +1857,8 @@ static void binder_deferred_fd_close(int fd)
init_task_work(&twcb->twork, binder_do_fd_close); init_task_work(&twcb->twork, binder_do_fd_close);
twcb->file = close_fd_get_file(fd); twcb->file = close_fd_get_file(fd);
if (twcb->file) { if (twcb->file) {
// pin it until binder_do_fd_close(); see comments there
get_file(twcb->file);
filp_close(twcb->file, current->files); filp_close(twcb->file, current->files);
task_work_add(current, &twcb->twork, TWA_RESUME); task_work_add(current, &twcb->twork, TWA_RESUME);
} else { } else {
......
...@@ -800,8 +800,7 @@ struct file *__close_fd_get_file(unsigned int fd) ...@@ -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. * 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 * The caller must ensure that filp_close() called on the file.
* an fput().
*/ */
struct file *close_fd_get_file(unsigned int fd) struct file *close_fd_get_file(unsigned int fd)
{ {
......
...@@ -5110,7 +5110,7 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags) ...@@ -5110,7 +5110,7 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags)
struct files_struct *files = current->files; struct files_struct *files = current->files;
struct io_close *close = &req->close; struct io_close *close = &req->close;
struct fdtable *fdt; struct fdtable *fdt;
struct file *file = NULL; struct file *file;
int ret = -EBADF; int ret = -EBADF;
if (req->close.file_slot) { if (req->close.file_slot) {
...@@ -5127,7 +5127,6 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags) ...@@ -5127,7 +5127,6 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags)
file = fdt->fd[close->fd]; file = fdt->fd[close->fd];
if (!file || file->f_op == &io_uring_fops) { if (!file || file->f_op == &io_uring_fops) {
spin_unlock(&files->file_lock); spin_unlock(&files->file_lock);
file = NULL;
goto err; goto err;
} }
...@@ -5147,8 +5146,6 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags) ...@@ -5147,8 +5146,6 @@ static int io_close(struct io_kiocb *req, unsigned int issue_flags)
err: err:
if (ret < 0) if (ret < 0)
req_set_fail(req); req_set_fail(req);
if (file)
fput(file);
__io_req_complete(req, issue_flags, ret, 0); __io_req_complete(req, issue_flags, ret, 0);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment