diff mbox series

[for-rc] RDMA/hfi1: Fix use-after-free bug for mm struct

Message ID 20220408133523.122165.72975.stgit@awfm-01.cornelisnetworks.com (mailing list archive)
State Accepted
Delegated to: Jason Gunthorpe
Headers show
Series [for-rc] RDMA/hfi1: Fix use-after-free bug for mm struct | expand

Commit Message

Dennis Dalessandro April 8, 2022, 1:35 p.m. UTC
From: Douglas Miller <doug.miller@cornelisnetworks.com>

Under certain conditions, such as MPI_Abort, the hfi1 cleanup
code may represent the last reference held on the task mm.
hfi1_mmu_rb_unregister() then drops the last reference and the mm is
freed before the final use in hfi1_release_user_pages().  A new task
may allocate the mm structure while it is still being used, resulting in
problems. One manifestation is corruption of the mmap_sem counter leading
to a hang in down_write().  Another is corruption of an mm struct that
is in use by another task.

Fixes: 3d2a9d642512 ("IB/hfi1: Ensure correct mm is used at all times")
Cc: <stable@vger.kernel.org>
Signed-off-by: Douglas Miller <doug.miller@cornelisnetworks.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
---
 drivers/infiniband/hw/hfi1/mmu_rb.c |    6 ++++++
 1 file changed, 6 insertions(+)

Comments

Jason Gunthorpe April 8, 2022, 4:48 p.m. UTC | #1
On Fri, Apr 08, 2022 at 09:35:23AM -0400, Dennis Dalessandro wrote:
> From: Douglas Miller <doug.miller@cornelisnetworks.com>
> 
> Under certain conditions, such as MPI_Abort, the hfi1 cleanup
> code may represent the last reference held on the task mm.
> hfi1_mmu_rb_unregister() then drops the last reference and the mm is
> freed before the final use in hfi1_release_user_pages().  A new task
> may allocate the mm structure while it is still being used, resulting in
> problems. One manifestation is corruption of the mmap_sem counter leading
> to a hang in down_write().  Another is corruption of an mm struct that
> is in use by another task.
> 
> Fixes: 3d2a9d642512 ("IB/hfi1: Ensure correct mm is used at all times")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Douglas Miller <doug.miller@cornelisnetworks.com>
> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
> ---
>  drivers/infiniband/hw/hfi1/mmu_rb.c |    6 ++++++
>  1 file changed, 6 insertions(+)

Applied to for-rc, thanks

Jason
diff mbox series

Patch

diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c
index 876cc78..7333646 100644
--- a/drivers/infiniband/hw/hfi1/mmu_rb.c
+++ b/drivers/infiniband/hw/hfi1/mmu_rb.c
@@ -80,6 +80,9 @@  void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler)
 	unsigned long flags;
 	struct list_head del_list;
 
+	/* Prevent freeing of mm until we are completely finished. */
+	mmgrab(handler->mn.mm);
+
 	/* Unregister first so we don't get any more notifications. */
 	mmu_notifier_unregister(&handler->mn, handler->mn.mm);
 
@@ -102,6 +105,9 @@  void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler)
 
 	do_remove(handler, &del_list);
 
+	/* Now the mm may be freed. */
+	mmdrop(handler->mn.mm);
+
 	kfree(handler);
 }