[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20160109220826.GA11174@kvack.org>
Date: Sat, 9 Jan 2016 17:08:26 -0500
From: Benjamin LaHaise <bcrl@...ck.org>
To: Linus Torvalds <torvalds@...ux-foundation.org>
Cc: Linux Kernel <linux-kernel@...r.kernel.org>, linux-aio@...ck.org,
linux-fsdevel@...r.kernel.org, Jan Kara <jack@...e.cz>,
Dmitry Vyukov <dvyukov@...gle.com>
Subject: [GIT PULL] aio: a couple of fixes for 4.4
Hello Linus et al,
Please consider pulling the following changes to fix a couple of issues
reported by Dmitry from git://git.kvack.org/~bcrl/aio-fixes.git . Thanks!
-ben
Benjamin LaHaise (1):
aio: handle integer overflow in io_getevents() timespec usage
Jan Kara (1):
aio: Fix freeze protection of aio writes
fs/aio.c | 33 ++++++++++++++++++++++++++++++---
include/linux/fs.h | 1 +
2 files changed, 31 insertions(+), 3 deletions(-)
--
2.5.0
>From fec65924b0b08095f820ad11cff3fd15fb29b436 Mon Sep 17 00:00:00 2001
From: Benjamin LaHaise <bcrl@...ck.org>
Date: Thu, 7 Jan 2016 10:37:58 -0500
Subject: [PATCH 1/2] aio: handle integer overflow in io_getevents() timespec
usage
Dmitry Vyukov reported an integer overflow in io_getevents() when
running a fuzzer. Upon investigation, the triggers appears to be that
an invalid value for the tv_sec or tv_nsec was passed in which is not
handled by timespec_to_ktime(). This patch fixes that by making
io_getevents() return -EINVAL when timespec_valid() checks fail. We
use timespec_valid() instead of timespec_valid_strict() to avoid issues
caused by userspace not knowing the cutoff for KTIME_SEC_MAX.
Reported-by: Dmitry Vyukov <dvyukov@...gle.com>
Signed-off-by: Benjamin LaHaise <bcrl@...ck.org>
Acked-by: Dmitry Vyukov <dvyukov@...gle.com>
diff --git a/fs/aio.c b/fs/aio.c
index 155f842..e0d5398 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1269,6 +1269,8 @@ static long read_events(struct kioctx *ctx, long min_nr, long nr,
if (unlikely(copy_from_user(&ts, timeout, sizeof(ts))))
return -EFAULT;
+ if (!timespec_valid(&ts))
+ return -EINVAL;
until = timespec_to_ktime(ts);
}
--
2.5.0
>From 3b9688ff1e083a3c981bbc795f823fb0b0f2aacc Mon Sep 17 00:00:00 2001
From: Jan Kara <jack@...e.cz>
Date: Thu, 7 Jan 2016 16:03:04 +0100
Subject: [PATCH 2/2] aio: Fix freeze protection of aio writes
Currently we dropped freeze protection of aio writes just after IO was
submitted. Thus aio write could be in flight while the filesystem was
frozen and that could result in unexpected situation like aio completion
wanting to convert extent type on frozen filesystem. Testcase from
Dmitry triggering this is like:
for ((i=0;i<60;i++));do fsfreeze -f /mnt ;sleep 1;fsfreeze -u /mnt;done &
fio --bs=4k --ioengine=libaio --iodepth=128 --size=1g --direct=1 \
--runtime=60 --filename=/mnt/file --name=rand-write --rw=randwrite
Fix the problem by dropping freeze protection only once IO is completed
in aio_complete().
Reported-by: Dmitry Monakhov <dmonakhov@...nvz.org>
Signed-off-by: Jan Kara <jack@...e.cz>
Signed-off-by: Benjamin LaHaise <bcrl@...ck.org>
diff --git a/fs/aio.c b/fs/aio.c
index e0d5398..a574944 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1065,6 +1065,19 @@ static void aio_complete(struct kiocb *kiocb, long res, long res2)
unsigned tail, pos, head;
unsigned long flags;
+ if (kiocb->ki_flags & IOCB_WRITE) {
+ struct file *f = kiocb->ki_filp;
+
+ /*
+ * Tell lockdep we inherited freeze protection from submission
+ * thread.
+ */
+ percpu_rwsem_acquire(
+ &f->f_inode->i_sb->s_writers.rw_sem[SB_FREEZE_WRITE-1],
+ 1, _THIS_IP_);
+ file_end_write(f);
+ }
+
/*
* Special case handling for sync iocbs:
* - events go directly into the iocb for fast handling
@@ -1451,13 +1464,25 @@ rw_common:
len = ret;
- if (rw == WRITE)
+ if (rw == WRITE) {
file_start_write(file);
+ req->ki_flags |= IOCB_WRITE;
+ }
ret = iter_op(req, &iter);
- if (rw == WRITE)
- file_end_write(file);
+ if (rw == WRITE) {
+ /*
+ * We release freeze protection in aio_complete(). Fool
+ * lockdep by telling it the lock got released so that
+ * it doesn't complain about held lock when we return
+ * to userspace.
+ */
+ percpu_rwsem_release(
+ &file->f_inode->i_sb->s_writers.rw_sem[SB_FREEZE_WRITE-1],
+ 1, _THIS_IP_);
+ }
+
kfree(iovec);
break;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3aa5142..54af40e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -319,6 +319,7 @@ struct writeback_control;
#define IOCB_EVENTFD (1 << 0)
#define IOCB_APPEND (1 << 1)
#define IOCB_DIRECT (1 << 2)
+#define IOCB_WRITE (1 << 3)
struct kiocb {
struct file *ki_filp;
--
2.5.0
--
"Thought is the essence of where you are now."
Powered by blists - more mailing lists