Skip to content

Commit 724768a

Browse files
committed
ovl: fix incorrect fdput() on aio completion
ovl_{read,write}_iter() always call fdput(real) to put one or zero refcounts of the real file, but for aio, whether it was submitted or not, ovl_aio_put() also calls fdput(), which is not balanced. This is only a problem in the less common case when FDPUT_FPUT flag is set. To fix the problem use get_file() to take file refcount and use fput() instead of fdput() in ovl_aio_put(). Fixes: 2406a30 ("ovl: implement async IO routines") Cc: <stable@vger.kernel.org> # v5.6 Reviewed-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Amir Goldstein <amir73il@gmail.com>
1 parent ab04830 commit 724768a

File tree

1 file changed

+3
-6
lines changed

1 file changed

+3
-6
lines changed

fs/overlayfs/file.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ struct ovl_aio_req {
1919
struct kiocb iocb;
2020
refcount_t ref;
2121
struct kiocb *orig_iocb;
22-
struct fd fd;
2322
};
2423

2524
static struct kmem_cache *ovl_aio_request_cachep;
@@ -280,7 +279,7 @@ static rwf_t ovl_iocb_to_rwf(int ifl)
280279
static inline void ovl_aio_put(struct ovl_aio_req *aio_req)
281280
{
282281
if (refcount_dec_and_test(&aio_req->ref)) {
283-
fdput(aio_req->fd);
282+
fput(aio_req->iocb.ki_filp);
284283
kmem_cache_free(ovl_aio_request_cachep, aio_req);
285284
}
286285
}
@@ -342,10 +341,9 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
342341
if (!aio_req)
343342
goto out;
344343

345-
aio_req->fd = real;
346344
real.flags = 0;
347345
aio_req->orig_iocb = iocb;
348-
kiocb_clone(&aio_req->iocb, iocb, real.file);
346+
kiocb_clone(&aio_req->iocb, iocb, get_file(real.file));
349347
aio_req->iocb.ki_complete = ovl_aio_rw_complete;
350348
refcount_set(&aio_req->ref, 2);
351349
ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter);
@@ -409,10 +407,9 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
409407
if (!aio_req)
410408
goto out;
411409

412-
aio_req->fd = real;
413410
real.flags = 0;
414411
aio_req->orig_iocb = iocb;
415-
kiocb_clone(&aio_req->iocb, iocb, real.file);
412+
kiocb_clone(&aio_req->iocb, iocb, get_file(real.file));
416413
aio_req->iocb.ki_flags = ifl;
417414
aio_req->iocb.ki_complete = ovl_aio_rw_complete;
418415
refcount_set(&aio_req->ref, 2);

0 commit comments

Comments
 (0)