* [PATCH AUTOSEL 5.7 56/61] ceph: fix potential mdsc use-after-free crash
[not found] <20200821161545.347622-1-sashal@kernel.org>
@ 2020-08-21 16:15 ` Sasha Levin
2020-08-21 16:15 ` [PATCH AUTOSEL 5.7 57/61] ceph: do not access the kiocb after aio requests Sasha Levin
1 sibling, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2020-08-21 16:15 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Xiubo Li, Jeff Layton, Ilya Dryomov, Sasha Levin, ceph-devel
From: Xiubo Li <xiubli@redhat.com>
[ Upstream commit fa9967734227b44acb1b6918033f9122dc7825b9 ]
Make sure the delayed work stopped before releasing the resources.
cancel_delayed_work_sync() will only guarantee that the work finishes
executing if the work is already in the ->worklist. That means after
the cancel_delayed_work_sync() returns, it will leave the work requeued
if it was rearmed at the end. That can lead to a use after free once the
work struct is freed.
Fix it by flushing the delayed work instead of trying to cancel it, and
ensure that the work doesn't rearm if the mdsc is stopping.
URL: https://tracker.ceph.com/issues/46293
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ceph/mds_client.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 7c63abf5bea91..5e1d1070c8dfd 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -4260,6 +4260,9 @@ static void delayed_work(struct work_struct *work)
dout("mdsc delayed_work\n");
+ if (mdsc->stopping)
+ return;
+
mutex_lock(&mdsc->mutex);
renew_interval = mdsc->mdsmap->m_session_timeout >> 2;
renew_caps = time_after_eq(jiffies, HZ*renew_interval +
@@ -4625,7 +4628,16 @@ void ceph_mdsc_force_umount(struct ceph_mds_client *mdsc)
static void ceph_mdsc_stop(struct ceph_mds_client *mdsc)
{
dout("stop\n");
- cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */
+ /*
+ * Make sure the delayed work stopped before releasing
+ * the resources.
+ *
+ * Because the cancel_delayed_work_sync() will only
+ * guarantee that the work finishes executing. But the
+ * delayed work will re-arm itself again after that.
+ */
+ flush_delayed_work(&mdsc->delayed_work);
+
if (mdsc->mdsmap)
ceph_mdsmap_destroy(mdsc->mdsmap);
kfree(mdsc->sessions);
--
2.25.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH AUTOSEL 5.7 57/61] ceph: do not access the kiocb after aio requests
[not found] <20200821161545.347622-1-sashal@kernel.org>
2020-08-21 16:15 ` [PATCH AUTOSEL 5.7 56/61] ceph: fix potential mdsc use-after-free crash Sasha Levin
@ 2020-08-21 16:15 ` Sasha Levin
1 sibling, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2020-08-21 16:15 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Xiubo Li, Jeff Layton, Ilya Dryomov, Sasha Levin, ceph-devel
From: Xiubo Li <xiubli@redhat.com>
[ Upstream commit d1d9655052606fd9078e896668ec90191372d513 ]
In aio case, if the completion comes very fast just before the
ceph_read_iter() returns to fs/aio.c, the kiocb will be freed in
the completion callback, then if ceph_read_iter() access again
we will potentially hit the use-after-free bug.
[ jlayton: initialize direct_lock early, and use it everywhere ]
URL: https://tracker.ceph.com/issues/45649
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ceph/file.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index afdfca965a7fc..599eca249973d 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -1508,6 +1508,7 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to)
struct inode *inode = file_inode(filp);
struct ceph_inode_info *ci = ceph_inode(inode);
struct page *pinned_page = NULL;
+ bool direct_lock = iocb->ki_flags & IOCB_DIRECT;
ssize_t ret;
int want, got = 0;
int retry_op = 0, read = 0;
@@ -1516,7 +1517,7 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to)
dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n",
inode, ceph_vinop(inode), iocb->ki_pos, (unsigned)len, inode);
- if (iocb->ki_flags & IOCB_DIRECT)
+ if (direct_lock)
ceph_start_io_direct(inode);
else
ceph_start_io_read(inode);
@@ -1573,7 +1574,7 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to)
}
ceph_put_cap_refs(ci, got);
- if (iocb->ki_flags & IOCB_DIRECT)
+ if (direct_lock)
ceph_end_io_direct(inode);
else
ceph_end_io_read(inode);
--
2.25.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-08-21 17:14 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20200821161545.347622-1-sashal@kernel.org>
2020-08-21 16:15 ` [PATCH AUTOSEL 5.7 56/61] ceph: fix potential mdsc use-after-free crash Sasha Levin
2020-08-21 16:15 ` [PATCH AUTOSEL 5.7 57/61] ceph: do not access the kiocb after aio requests Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox