lkml.org 
[lkml]   [2020]   [Feb]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 115/191] RDMA/uverbs: Remove needs_kfree_rcu from uverbs_obj_type_class
    Date
    From: Jason Gunthorpe <jgg@mellanox.com>

    [ Upstream commit 8bdf9dd984c18375d1090ddeb1792511f619c5c1 ]

    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.

    Link: https://lore.kernel.org/r/20200113143306.GA28717@ziepe.ca
    Signed-off-by: Michael Guralnik <michaelgur@mellanox.com>
    Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/infiniband/core/rdma_core.c | 23 +----------------------
    include/rdma/uverbs_types.h | 1 -
    2 files changed, 1 insertion(+), 23 deletions(-)

    diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c
    index c4118bcd51035..c2c9bd72b350f 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)
    @@ -753,20 +747,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);

    @@ -954,7 +934,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 acb1bfa3cc99a..f70155cc73979 100644
    --- a/include/rdma/uverbs_types.h
    +++ b/include/rdma/uverbs_types.h
    @@ -97,7 +97,6 @@ struct uverbs_obj_type_class {
    int __must_check (*destroy_hw)(struct ib_uobject *uobj,
    enum rdma_remove_reason why);
    void (*remove_handle)(struct ib_uobject *uobj);
    - u8 needs_kfree_rcu;
    };

    struct uverbs_obj_type {
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-02-21 09:22    [W:3.050 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site