RDMA/ucma: Check for a cm_id->device in all user calls that need it
authorJason Gunthorpe <jgg@mellanox.com>
Thu, 5 Apr 2018 03:00:01 +0000 (21:00 -0600)
committerDoug Ledford <dledford@redhat.com>
Fri, 20 Apr 2018 02:01:11 +0000 (22:01 -0400)
This is done by auditing all callers of ucma_get_ctx and switching the
ones that unconditionally touch ->device to ucma_get_ctx_dev. This covers
a little less than  half of the call sites.

The 11 remaining call sites to ucma_get_ctx() were manually audited.

Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/core/ucma.c

index 680b3536ad3efe8ad3eef1ee56c9fddebb65f23d..0efa0e2a3cd33e3f36c09f341818722eca2fb712 100644 (file)
@@ -159,6 +159,23 @@ static void ucma_put_ctx(struct ucma_context *ctx)
                complete(&ctx->comp);
 }
 
+/*
+ * Same as ucm_get_ctx but requires that ->cm_id->device is valid, eg that the
+ * CM_ID is bound.
+ */
+static struct ucma_context *ucma_get_ctx_dev(struct ucma_file *file, int id)
+{
+       struct ucma_context *ctx = ucma_get_ctx(file, id);
+
+       if (IS_ERR(ctx))
+               return ctx;
+       if (!ctx->cm_id->device) {
+               ucma_put_ctx(ctx);
+               return ERR_PTR(-EINVAL);
+       }
+       return ctx;
+}
+
 static void ucma_close_event_id(struct work_struct *work)
 {
        struct ucma_event *uevent_close =  container_of(work, struct ucma_event, close_work);
@@ -734,7 +751,7 @@ static ssize_t ucma_resolve_route(struct ucma_file *file,
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
-       ctx = ucma_get_ctx(file, cmd.id);
+       ctx = ucma_get_ctx_dev(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
@@ -1050,7 +1067,7 @@ static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf,
        if (!cmd.conn_param.valid)
                return -EINVAL;
 
-       ctx = ucma_get_ctx(file, cmd.id);
+       ctx = ucma_get_ctx_dev(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
@@ -1092,7 +1109,7 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf,
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
-       ctx = ucma_get_ctx(file, cmd.id);
+       ctx = ucma_get_ctx_dev(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
@@ -1120,7 +1137,7 @@ static ssize_t ucma_reject(struct ucma_file *file, const char __user *inbuf,
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
-       ctx = ucma_get_ctx(file, cmd.id);
+       ctx = ucma_get_ctx_dev(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
@@ -1139,7 +1156,7 @@ static ssize_t ucma_disconnect(struct ucma_file *file, const char __user *inbuf,
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
-       ctx = ucma_get_ctx(file, cmd.id);
+       ctx = ucma_get_ctx_dev(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
@@ -1167,15 +1184,10 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file,
        if (cmd.qp_state > IB_QPS_ERR)
                return -EINVAL;
 
-       ctx = ucma_get_ctx(file, cmd.id);
+       ctx = ucma_get_ctx_dev(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
-       if (!ctx->cm_id->device) {
-               ret = -EINVAL;
-               goto out;
-       }
-
        resp.qp_attr_mask = 0;
        memset(&qp_attr, 0, sizeof qp_attr);
        qp_attr.qp_state = cmd.qp_state;
@@ -1384,7 +1396,7 @@ static ssize_t ucma_process_join(struct ucma_file *file,
        else
                return -EINVAL;
 
-       ctx = ucma_get_ctx(file, cmd->id);
+       ctx = ucma_get_ctx_dev(file, cmd->id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);