git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
RDMA/ucma: Check that device exists prior to accessing it
[pandora-kernel.git]
/
drivers
/
infiniband
/
core
/
ucma.c
diff --git
a/drivers/infiniband/core/ucma.c
b/drivers/infiniband/core/ucma.c
index
b69307f
..
49d94c1
100644
(file)
--- a/
drivers/infiniband/core/ucma.c
+++ b/
drivers/infiniband/core/ucma.c
@@
-41,11
+41,13
@@
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
+#include <linux/module.h>
#include <rdma/rdma_user_cm.h>
#include <rdma/ib_marshall.h>
#include <rdma/rdma_cm.h>
#include <rdma/rdma_cm_ib.h>
#include <rdma/rdma_user_cm.h>
#include <rdma/ib_marshall.h>
#include <rdma/rdma_cm.h>
#include <rdma/rdma_cm_ib.h>
+#include <rdma/ib.h>
MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
@@
-124,7
+126,7
@@
static inline struct ucma_context *_ucma_find_context(int id,
ctx = idr_find(&ctx_idr, id);
if (!ctx)
ctx = ERR_PTR(-ENOENT);
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;
}
ctx = ERR_PTR(-EINVAL);
return ctx;
}
@@
-391,6
+393,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_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;
enum ib_qp_type qp_type;
int ret;
@@
-411,9
+414,9
@@
static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
return -ENOMEM;
ctx->uid = cmd.uid;
return -ENOMEM;
ctx->uid = cmd.uid;
- c
tx->c
m_id = rdma_create_id(ucma_event_handler, ctx, cmd.ps, qp_type);
- if (IS_ERR(c
tx->c
m_id)) {
- ret = PTR_ERR(c
tx->c
m_id);
+ cm_id = rdma_create_id(ucma_event_handler, ctx, cmd.ps, qp_type);
+ if (IS_ERR(cm_id)) {
+ ret = PTR_ERR(cm_id);
goto err1;
}
goto err1;
}
@@
-423,14
+426,19
@@
static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
ret = -EFAULT;
goto err2;
}
ret = -EFAULT;
goto err2;
}
+
+ ctx->cm_id = cm_id;
return 0;
err2:
return 0;
err2:
- rdma_destroy_id(c
tx->c
m_id);
+ rdma_destroy_id(cm_id);
err1:
mutex_lock(&mut);
idr_remove(&ctx_idr, ctx->id);
mutex_unlock(&mut);
err1:
mutex_lock(&mut);
idr_remove(&ctx_idr, ctx->id);
mutex_unlock(&mut);
+ mutex_lock(&file->mut);
+ list_del(&ctx->list);
+ mutex_unlock(&file->mut);
kfree(ctx);
return ret;
}
kfree(ctx);
return ret;
}
@@
-871,10
+879,18
@@
static ssize_t ucma_init_qp_attr(struct ucma_file *file,
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
return -EFAULT;
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
return -EFAULT;
+ if (cmd.qp_state > IB_QPS_ERR)
+ return -EINVAL;
+
ctx = ucma_get_ctx(file, cmd.id);
if (IS_ERR(ctx))
return PTR_ERR(ctx);
ctx = ucma_get_ctx(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;
resp.qp_attr_mask = 0;
memset(&qp_attr, 0, sizeof qp_attr);
qp_attr.qp_state = cmd.qp_state;
@@
-998,6
+1014,9
@@
static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf,
if (IS_ERR(ctx))
return PTR_ERR(ctx);
if (IS_ERR(ctx))
return PTR_ERR(ctx);
+ if (unlikely(cmd.optlen > KMALLOC_MAX_SIZE))
+ return -EINVAL;
+
optval = kmalloc(cmd.optlen, GFP_KERNEL);
if (!optval) {
ret = -ENOMEM;
optval = kmalloc(cmd.optlen, GFP_KERNEL);
if (!optval) {
ret = -ENOMEM;
@@
-1024,7
+1043,7
@@
static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf,
{
struct rdma_ucm_notify cmd;
struct ucma_context *ctx;
{
struct rdma_ucm_notify cmd;
struct ucma_context *ctx;
- int ret;
+ int ret
= -EINVAL
;
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
return -EFAULT;
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
return -EFAULT;
@@
-1033,7
+1052,9
@@
static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf,
if (IS_ERR(ctx))
return PTR_ERR(ctx);
if (IS_ERR(ctx))
return PTR_ERR(ctx);
- ret = rdma_notify(ctx->cm_id, (enum ib_event_type) cmd.event);
+ if (ctx->cm_id->device)
+ ret = rdma_notify(ctx->cm_id, (enum ib_event_type)cmd.event);
+
ucma_put_ctx(ctx);
return ret;
}
ucma_put_ctx(ctx);
return ret;
}
@@
-1267,6
+1288,9
@@
static ssize_t ucma_write(struct file *filp, const char __user *buf,
struct rdma_ucm_cmd_hdr hdr;
ssize_t ret;
struct rdma_ucm_cmd_hdr hdr;
ssize_t ret;
+ if (WARN_ON_ONCE(!ib_safe_file_access(filp)))
+ return -EACCES;
+
if (len < sizeof(hdr))
return -EINVAL;
if (len < sizeof(hdr))
return -EINVAL;