|
|
@@ -2593,6 +2593,9 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
|
|
|
static int kern_spec_to_ib_spec(struct ib_uverbs_flow_spec *kern_spec,
|
|
|
union ib_flow_spec *ib_spec)
|
|
|
{
|
|
|
+ if (kern_spec->reserved)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
ib_spec->type = kern_spec->type;
|
|
|
|
|
|
switch (ib_spec->type) {
|
|
|
@@ -2646,6 +2649,9 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
|
|
|
void *ib_spec;
|
|
|
int i;
|
|
|
|
|
|
+ if (ucore->inlen < sizeof(cmd))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
if (ucore->outlen < sizeof(resp))
|
|
|
return -ENOSPC;
|
|
|
|
|
|
@@ -2671,6 +2677,10 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
|
|
|
(cmd.flow_attr.num_of_specs * sizeof(struct ib_uverbs_flow_spec)))
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ if (cmd.flow_attr.reserved[0] ||
|
|
|
+ cmd.flow_attr.reserved[1])
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
if (cmd.flow_attr.num_of_specs) {
|
|
|
kern_flow_attr = kmalloc(sizeof(*kern_flow_attr) + cmd.flow_attr.size,
|
|
|
GFP_KERNEL);
|
|
|
@@ -2731,6 +2741,7 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
|
|
|
if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) {
|
|
|
pr_warn("create flow failed, flow %d: %d bytes left from uverb cmd\n",
|
|
|
i, cmd.flow_attr.size);
|
|
|
+ err = -EINVAL;
|
|
|
goto err_free;
|
|
|
}
|
|
|
flow_id = ib_create_flow(qp, flow_attr, IB_FLOW_DOMAIN_USER);
|
|
|
@@ -2791,10 +2802,16 @@ int ib_uverbs_ex_destroy_flow(struct ib_uverbs_file *file,
|
|
|
struct ib_uobject *uobj;
|
|
|
int ret;
|
|
|
|
|
|
+ if (ucore->inlen < sizeof(cmd))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
ret = ib_copy_from_udata(&cmd, ucore, sizeof(cmd));
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
+ if (cmd.comp_mask)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
uobj = idr_write_uobj(&ib_uverbs_rule_idr, cmd.flow_handle,
|
|
|
file->ucontext);
|
|
|
if (!uobj)
|