* [PATCH] RDMA/uverbs: Remove needs_kfree_rcu from uverbs_obj_type_class
@ 2020-01-13 14:33 Jason Gunthorpe
2020-01-13 20:37 ` Jason Gunthorpe
0 siblings, 1 reply; 2+ messages in thread
From: Jason Gunthorpe @ 2020-01-13 14:33 UTC (permalink / raw)
To: linux-rdma; +Cc: Michael Guralnik, Yishai Hadas
After device disassociation the uapi_objects are destroyed and freed,
however it is still possible that core code can be holding a kref on the
uobject. When it finally goes to uverbs_uobject_free() via the kref_put()
it can trigger a use-after-free on the uapi_object.
Since needs_kfree_rcu is a micro optimization that only benefits file
uobjects, just get rid of it. There is no harm in using kfree_rcu even if
it isn't required, and the number of involved objects is small.
Signed-off-by: Michael Guralnik <michaelgur@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
---
drivers/infiniband/core/rdma_core.c | 23 +----------------------
include/rdma/uverbs_types.h | 1 -
2 files changed, 1 insertion(+), 23 deletions(-)
This should go before the 'refactoring fd usage' series as more
testing has shown the reworked code can trivially trigger this
existing bug.
diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c
index 6c72773faf2911..17bdbe38fdfa59 100644
--- a/drivers/infiniband/core/rdma_core.c
+++ b/drivers/infiniband/core/rdma_core.c
@@ -49,13 +49,7 @@ void uverbs_uobject_get(struct ib_uobject *uobject)
static void uverbs_uobject_free(struct kref *ref)
{
- struct ib_uobject *uobj =
- container_of(ref, struct ib_uobject, ref);
-
- if (uobj->uapi_object->type_class->needs_kfree_rcu)
- kfree_rcu(uobj, rcu);
- else
- kfree(uobj);
+ kfree_rcu(container_of(ref, struct ib_uobject, ref), rcu);
}
void uverbs_uobject_put(struct ib_uobject *uobject)
@@ -744,20 +738,6 @@ const struct uverbs_obj_type_class uverbs_idr_class = {
.lookup_put = lookup_put_idr_uobject,
.destroy_hw = destroy_hw_idr_uobject,
.remove_handle = remove_handle_idr_uobject,
- /*
- * When we destroy an object, we first just lock it for WRITE and
- * actually DESTROY it in the finalize stage. So, the problematic
- * scenario is when we just started the finalize stage of the
- * destruction (nothing was executed yet). Now, the other thread
- * fetched the object for READ access, but it didn't lock it yet.
- * The DESTROY thread continues and starts destroying the object.
- * When the other thread continue - without the RCU, it would
- * access freed memory. However, the rcu_read_lock delays the free
- * until the rcu_read_lock of the READ operation quits. Since the
- * exclusive lock of the object is still taken by the DESTROY flow, the
- * READ operation will get -EBUSY and it'll just bail out.
- */
- .needs_kfree_rcu = true,
};
EXPORT_SYMBOL(uverbs_idr_class);
@@ -920,7 +900,6 @@ const struct uverbs_obj_type_class uverbs_fd_class = {
.lookup_put = lookup_put_fd_uobject,
.destroy_hw = destroy_hw_fd_uobject,
.remove_handle = remove_handle_fd_uobject,
- .needs_kfree_rcu = false,
};
EXPORT_SYMBOL(uverbs_fd_class);
diff --git a/include/rdma/uverbs_types.h b/include/rdma/uverbs_types.h
index d57a5ba00c743e..0b0f5a5f392de7 100644
--- a/include/rdma/uverbs_types.h
+++ b/include/rdma/uverbs_types.h
@@ -98,7 +98,6 @@ struct uverbs_obj_type_class {
enum rdma_remove_reason why,
struct uverbs_attr_bundle *attrs);
void (*remove_handle)(struct ib_uobject *uobj);
- u8 needs_kfree_rcu;
};
struct uverbs_obj_type {
--
2.24.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] RDMA/uverbs: Remove needs_kfree_rcu from uverbs_obj_type_class
2020-01-13 14:33 [PATCH] RDMA/uverbs: Remove needs_kfree_rcu from uverbs_obj_type_class Jason Gunthorpe
@ 2020-01-13 20:37 ` Jason Gunthorpe
0 siblings, 0 replies; 2+ messages in thread
From: Jason Gunthorpe @ 2020-01-13 20:37 UTC (permalink / raw)
To: linux-rdma; +Cc: Michael Guralnik, Yishai Hadas
On Mon, Jan 13, 2020 at 02:33:10PM +0000, Jason Gunthorpe wrote:
> After device disassociation the uapi_objects are destroyed and freed,
> however it is still possible that core code can be holding a kref on the
> uobject. When it finally goes to uverbs_uobject_free() via the kref_put()
> it can trigger a use-after-free on the uapi_object.
>
> Since needs_kfree_rcu is a micro optimization that only benefits file
> uobjects, just get rid of it. There is no harm in using kfree_rcu even if
> it isn't required, and the number of involved objects is small.
>
> Signed-off-by: Michael Guralnik <michaelgur@mellanox.com>
> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
> ---
> drivers/infiniband/core/rdma_core.c | 23 +----------------------
> include/rdma/uverbs_types.h | 1 -
> 2 files changed, 1 insertion(+), 23 deletions(-)
>
> This should go before the 'refactoring fd usage' series as more
> testing has shown the reworked code can trivially trigger this
> existing bug.
Applied to for-next
Though it seems this might not be an existing problem as none of the
existing kref users can outlive disassociation. Nevertheless it is
very surprising that the kref becomes a segfault after disassociation.
Jason
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-01-13 20:37 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-13 14:33 [PATCH] RDMA/uverbs: Remove needs_kfree_rcu from uverbs_obj_type_class Jason Gunthorpe
2020-01-13 20:37 ` Jason Gunthorpe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).