aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 89c4ce2da78b..87ffeebc0b28 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -3488,8 +3488,8 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
3488 struct ib_flow_attr *flow_attr; 3488 struct ib_flow_attr *flow_attr;
3489 struct ib_qp *qp; 3489 struct ib_qp *qp;
3490 struct ib_uflow_resources *uflow_res; 3490 struct ib_uflow_resources *uflow_res;
3491 struct ib_uverbs_flow_spec_hdr *kern_spec;
3491 int err = 0; 3492 int err = 0;
3492 void *kern_spec;
3493 void *ib_spec; 3493 void *ib_spec;
3494 int i; 3494 int i;
3495 3495
@@ -3538,8 +3538,8 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
3538 if (!kern_flow_attr) 3538 if (!kern_flow_attr)
3539 return -ENOMEM; 3539 return -ENOMEM;
3540 3540
3541 memcpy(kern_flow_attr, &cmd.flow_attr, sizeof(*kern_flow_attr)); 3541 *kern_flow_attr = cmd.flow_attr;
3542 err = ib_copy_from_udata(kern_flow_attr + 1, ucore, 3542 err = ib_copy_from_udata(&kern_flow_attr->flow_specs, ucore,
3543 cmd.flow_attr.size); 3543 cmd.flow_attr.size);
3544 if (err) 3544 if (err)
3545 goto err_free_attr; 3545 goto err_free_attr;
@@ -3583,21 +3583,22 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
3583 flow_attr->flags = kern_flow_attr->flags; 3583 flow_attr->flags = kern_flow_attr->flags;
3584 flow_attr->size = sizeof(*flow_attr); 3584 flow_attr->size = sizeof(*flow_attr);
3585 3585
3586 kern_spec = kern_flow_attr + 1; 3586 kern_spec = kern_flow_attr->flow_specs;
3587 ib_spec = flow_attr + 1; 3587 ib_spec = flow_attr + 1;
3588 for (i = 0; i < flow_attr->num_of_specs && 3588 for (i = 0; i < flow_attr->num_of_specs &&
3589 cmd.flow_attr.size > offsetof(struct ib_uverbs_flow_spec, reserved) && 3589 cmd.flow_attr.size > sizeof(*kern_spec) &&
3590 cmd.flow_attr.size >= 3590 cmd.flow_attr.size >= kern_spec->size;
3591 ((struct ib_uverbs_flow_spec *)kern_spec)->size; i++) { 3591 i++) {
3592 err = kern_spec_to_ib_spec(file->ucontext, kern_spec, ib_spec, 3592 err = kern_spec_to_ib_spec(
3593 uflow_res); 3593 file->ucontext, (struct ib_uverbs_flow_spec *)kern_spec,
3594 ib_spec, uflow_res);
3594 if (err) 3595 if (err)
3595 goto err_free; 3596 goto err_free;
3596 3597
3597 flow_attr->size += 3598 flow_attr->size +=
3598 ((union ib_flow_spec *) ib_spec)->size; 3599 ((union ib_flow_spec *) ib_spec)->size;
3599 cmd.flow_attr.size -= ((struct ib_uverbs_flow_spec *)kern_spec)->size; 3600 cmd.flow_attr.size -= kern_spec->size;
3600 kern_spec += ((struct ib_uverbs_flow_spec *) kern_spec)->size; 3601 kern_spec = ((void *)kern_spec) + kern_spec->size;
3601 ib_spec += ((union ib_flow_spec *) ib_spec)->size; 3602 ib_spec += ((union ib_flow_spec *) ib_spec)->size;
3602 } 3603 }
3603 if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) { 3604 if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) {