mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 22:14:03 +02:00
RDMA/core: Fix potential use after free in counter_release()
When accessing a counter via the netlink path the only synchronization
mechanism for the said counter is rdma_restrack_get().
Currently, rdma_restrack_del() is invoked at the end of
counter_release(), which is too late, since by that point
vendor-specific resources associated with the counter might already be
freed. This can leave a short window where the counter remains
accessible through restrack, leading to a potential use-after-free.
Fix this by moving the rdma_restrack_del() call to be before the
freeing of the vendor-specific resources, ensuring that the counter is
removed from restrack before its internal resources are released.
This guarantees that no new users hold references to a counter that is
in the process of destruction.
Fixes: 99fa331dc8 ("RDMA/counter: Add "auto" configuration mode support")
Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
Reviewed-by: Michael Guralnik <michaelgur@nvidia.com>
Signed-off-by: Edward Srouji <edwards@nvidia.com>
Link: https://patch.msgid.link/20260713-restrack-uaf-fix-resub-v2-5-bbe8bb270d51@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
parent
88244ecc71
commit
235ef2d0e7
|
|
@ -234,7 +234,6 @@ static void rdma_counter_free(struct rdma_counter *counter)
|
|||
|
||||
mutex_unlock(&port_counter->lock);
|
||||
|
||||
rdma_restrack_del(&counter->res);
|
||||
rdma_free_hw_stats_struct(counter->stats);
|
||||
kfree(counter);
|
||||
}
|
||||
|
|
@ -329,6 +328,7 @@ static void counter_release(struct kref *kref)
|
|||
|
||||
counter = container_of(kref, struct rdma_counter, kref);
|
||||
counter_history_stat_update(counter);
|
||||
rdma_restrack_del(&counter->res);
|
||||
counter->device->ops.counter_dealloc(counter);
|
||||
rdma_counter_free(counter);
|
||||
}
|
||||
|
|
@ -490,7 +490,8 @@ static struct rdma_counter *rdma_get_counter_by_id(struct ib_device *dev,
|
|||
return NULL;
|
||||
|
||||
counter = container_of(res, struct rdma_counter, res);
|
||||
kref_get(&counter->kref);
|
||||
if (!kref_get_unless_zero(&counter->kref))
|
||||
counter = NULL;
|
||||
rdma_restrack_put(res);
|
||||
|
||||
return counter;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user