IB/ucma: Fix theoretical user triggered use-after-free
PATCH 1/1 IB/ucma: Fix theoretical user triggered use-after-free
Something like this:
CPU A CPU B
======================== ================================ucma_destroy_id()
wait_for_completion()
.. anything
ucma_put_ctx()
complete()
.. continues ...
ucma_leave_multicast()
mutex_lock(mut)
atomic_inc(ctx->ref)
mutex_unlock(mut)
ucma_free_ctx()
ucma_cleanup_multicast()
mutex_lock(mut)
kfree(mc)
rdma_leave_multicast(mc->ctx->cm_id,..Fix it by latching the ref at 0. Once it goes to 0 mc and ctx cannot leave the mutex(mut) protection.
The other atomic_inc in ucma_get_ctx is OK because mutex(mut) protects it from racing with ucma_destroy_id.
--- drivers/infiniband/core/ucma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/infiniband/core/ucma.c +3 -3
@@ -1321,10 +1321,10 @@ static ssize_t ucma_leave_multicast(struct ucma_file *file, mc =ERR_PTR (-ENOENT ); else if (mc->ctx->file != file) mc =ERR_PTR (-EINVAL ); - else { + else if (!atomic_inc_not_zero(&mc->ctx->ref)) + mc =ERR_PTR (-ENXIO ); + else idr_remove(&multicast_idr, mc->id); -atomic_inc (&mc->ctx->ref); - }mutex_unlock (&mut);if (IS_ERR (mc)) {
Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20150804231332.GA22959-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org
Hefty, Sean
Acked-byQuoted 20 lines
Something like this:
CPU A CPU B
======================== ================================ucma_destroy_id()
wait_for_completion().. anything ucma_put_ctx() complete() .. continues ... ucma_leave_multicast() mutex_lock(mut) atomic_inc(ctx->ref) mutex_unlock(mut) ucma_free_ctx() ucma_cleanup_multicast() mutex_lock(mut) kfree(mc) rdma_leave_multicast(mc->ctx->cm_id,..
Quoted 7 lines
Fix it by latching the ref at 0. Once it goes to 0 mc and ctx cannot leave the mutex(mut) protection.
The other
atomic_incinucma_get_ctxis OK because mutex(mut) protects it from racing withucma_destroy_id.
Quoted 23 lines
--- drivers/infiniband/core/ucma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)drivers/infiniband/core/ucma.c +3
-3@@ -1321,10 +1321,10 @@ static ssize_t ucma_leave_multicast(structucma_file *file, mc =ERR_PTR (-ENOENT ); else if (mc->ctx->file != file) mc =ERR_PTR (-EINVAL ); - else { + else if (!atomic_inc_not_zero(&mc->ctx->ref)) + mc =ERR_PTR (-ENXIO ); + else idr_remove(&multicast_idr, mc->id); -atomic_inc (&mc->ctx->ref); - }mutex_unlock (&mut);
Quoted 1 line
if (
IS_ERR(mc)) {
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 1828884A29C6694DAF28B7E6B8A82373A9023323-P5GAC/[email protected]
Quoted 23 lines · Sean
Quoted 23 lines
Something like this:
CPU A CPU B
======================== ================================ucma_destroy_id()
wait_for_completion().. anything ucma_put_ctx() complete() .. continues ... ucma_leave_multicast() mutex_lock(mut) atomic_inc(ctx->ref) mutex_unlock(mut) ucma_free_ctx() ucma_cleanup_multicast() mutex_lock(mut) kfree(mc) rdma_leave_multicast(mc->ctx->cm_id,..Fix it by latching the ref at 0. Once it goes to 0 mc and ctx cannot leave the mutex(mut) protection.
Quoted 6 lines
Quoted 4 lines
The other
atomic_incinucma_get_ctxis OK because mutex(mut) protects it from racing withucma_destroy_id.Acked-by Sean Hefty <[email protected]>
This has been picked up. Thanks.
Signature · 2 lines
Doug Ledford <[email protected]> GPG KeyID: 0E572FDD