aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2014-09-23 05:38:26 -0400
committerRoland Dreier <roland@purestorage.com>2014-10-14 03:30:56 -0400
commita040f95dc81986d7d55bd98a9455217522ef706d (patch)
treedf2e9a410250723d03cf8f68160abb5503f8b3c8
parent8b0f93d9490653a7b9fc91f3570089132faed1c0 (diff)
IB/core: Fix XRC race condition in ib_uverbs_open_qp
In ib_uverbs_open_qp, the sharable xrc target qp is created as a "pseudo" qp and added to a list of qp's sharing the same physical QP. This is done before the "pseudo" qp is assigned a uobject. There is a race condition here if an async event arrives at the physical qp. If the event is handled after the pseudo qp is added to the list, but before it is assigned a uobject, the kernel crashes in ib_uverbs_qp_event_handler, due to trying to dereference a NULL uobject pointer. Note that simply checking for non-NULL is not enough, due to error flows in ib_uverbs_open_qp. If the failure is after assigning the uobject, but before the qp has fully been created, we still have a problem. Thus, in ib_uverbs_qp_event_handler, we test that the uobject is present, and also that it is live. Reported-by: Matthew Finlay <matt@mellanox.com> Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/core/uverbs_main.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index c73b22a257fe..bb6fea12ce31 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -502,6 +502,10 @@ void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr)
502{ 502{
503 struct ib_uevent_object *uobj; 503 struct ib_uevent_object *uobj;
504 504
505 /* for XRC target qp's, check that qp is live */
506 if (!event->element.qp->uobject || !event->element.qp->uobject->live)
507 return;
508
505 uobj = container_of(event->element.qp->uobject, 509 uobj = container_of(event->element.qp->uobject,
506 struct ib_uevent_object, uobject); 510 struct ib_uevent_object, uobject);
507 511