From 745b9a714889e1577aa153a3aa8096bf757984f3 Mon Sep 17 00:00:00 2001 From: hselasky Date: Tue, 17 Jul 2018 09:13:11 +0000 Subject: [PATCH] Ensure that CM_ID exists prior to access it in ibcore. Prior to access UCMA commands, the context should be initialized and connected to CM_ID with ucma_create_id(). In case user skips this step, he can provide non-valid ctx without CM_ID and cause to multiple NULL dereferences. Also there are situations where the create_id can be raced with other user access, ensure that the context is only shared to other threads once it is fully initialized to avoid the races. Linux commit: e8980d67d6017c8eee8f9c35f782c4bd68e004c9 MFC after: 1 week Sponsored by: Mellanox Technologies --- sys/ofed/drivers/infiniband/core/ib_ucma.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sys/ofed/drivers/infiniband/core/ib_ucma.c b/sys/ofed/drivers/infiniband/core/ib_ucma.c index ddbc29575749..4a55795318c1 100644 --- a/sys/ofed/drivers/infiniband/core/ib_ucma.c +++ b/sys/ofed/drivers/infiniband/core/ib_ucma.c @@ -124,7 +124,7 @@ static inline struct ucma_context *_ucma_find_context(int id, ctx = idr_find(&ctx_idr, id); if (!ctx) ctx = ERR_PTR(-ENOENT); - else if (ctx->file != file) + else if (ctx->file != file || !ctx->cm_id) ctx = ERR_PTR(-EINVAL); return ctx; } @@ -446,6 +446,7 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, struct rdma_ucm_create_id cmd; struct rdma_ucm_create_id_resp resp; struct ucma_context *ctx; + struct rdma_cm_id *cm_id; enum ib_qp_type qp_type; int ret; @@ -465,11 +466,10 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, if (!ctx) return -ENOMEM; - ctx->uid = cmd.uid; - ctx->cm_id = rdma_create_id(TD_TO_VNET(curthread), - ucma_event_handler, ctx, cmd.ps, qp_type); - if (IS_ERR(ctx->cm_id)) { - ret = PTR_ERR(ctx->cm_id); + cm_id = rdma_create_id(TD_TO_VNET(curthread), + ucma_event_handler, ctx, cmd.ps, qp_type); + if (IS_ERR(cm_id)) { + ret = PTR_ERR(cm_id); goto err1; } @@ -479,10 +479,12 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, ret = -EFAULT; goto err2; } + + ctx->cm_id = cm_id; return 0; err2: - rdma_destroy_id(ctx->cm_id); + rdma_destroy_id(cm_id); err1: mutex_lock(&mut); idr_remove(&ctx_idr, ctx->id);