diff options
Diffstat (limited to 'drivers/infiniband/core/uverbs_cmd.c')
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 65f6e7dc380c..f1cc83855af6 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -2593,6 +2593,9 @@ out_put: | |||
2593 | static int kern_spec_to_ib_spec(struct ib_uverbs_flow_spec *kern_spec, | 2593 | static int kern_spec_to_ib_spec(struct ib_uverbs_flow_spec *kern_spec, |
2594 | union ib_flow_spec *ib_spec) | 2594 | union ib_flow_spec *ib_spec) |
2595 | { | 2595 | { |
2596 | if (kern_spec->reserved) | ||
2597 | return -EINVAL; | ||
2598 | |||
2596 | ib_spec->type = kern_spec->type; | 2599 | ib_spec->type = kern_spec->type; |
2597 | 2600 | ||
2598 | switch (ib_spec->type) { | 2601 | switch (ib_spec->type) { |
@@ -2646,6 +2649,9 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file, | |||
2646 | void *ib_spec; | 2649 | void *ib_spec; |
2647 | int i; | 2650 | int i; |
2648 | 2651 | ||
2652 | if (ucore->inlen < sizeof(cmd)) | ||
2653 | return -EINVAL; | ||
2654 | |||
2649 | if (ucore->outlen < sizeof(resp)) | 2655 | if (ucore->outlen < sizeof(resp)) |
2650 | return -ENOSPC; | 2656 | return -ENOSPC; |
2651 | 2657 | ||
@@ -2671,6 +2677,10 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file, | |||
2671 | (cmd.flow_attr.num_of_specs * sizeof(struct ib_uverbs_flow_spec))) | 2677 | (cmd.flow_attr.num_of_specs * sizeof(struct ib_uverbs_flow_spec))) |
2672 | return -EINVAL; | 2678 | return -EINVAL; |
2673 | 2679 | ||
2680 | if (cmd.flow_attr.reserved[0] || | ||
2681 | cmd.flow_attr.reserved[1]) | ||
2682 | return -EINVAL; | ||
2683 | |||
2674 | if (cmd.flow_attr.num_of_specs) { | 2684 | if (cmd.flow_attr.num_of_specs) { |
2675 | kern_flow_attr = kmalloc(sizeof(*kern_flow_attr) + cmd.flow_attr.size, | 2685 | kern_flow_attr = kmalloc(sizeof(*kern_flow_attr) + cmd.flow_attr.size, |
2676 | GFP_KERNEL); | 2686 | GFP_KERNEL); |
@@ -2731,6 +2741,7 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file, | |||
2731 | if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) { | 2741 | if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) { |
2732 | pr_warn("create flow failed, flow %d: %d bytes left from uverb cmd\n", | 2742 | pr_warn("create flow failed, flow %d: %d bytes left from uverb cmd\n", |
2733 | i, cmd.flow_attr.size); | 2743 | i, cmd.flow_attr.size); |
2744 | err = -EINVAL; | ||
2734 | goto err_free; | 2745 | goto err_free; |
2735 | } | 2746 | } |
2736 | flow_id = ib_create_flow(qp, flow_attr, IB_FLOW_DOMAIN_USER); | 2747 | 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, | |||
2791 | struct ib_uobject *uobj; | 2802 | struct ib_uobject *uobj; |
2792 | int ret; | 2803 | int ret; |
2793 | 2804 | ||
2805 | if (ucore->inlen < sizeof(cmd)) | ||
2806 | return -EINVAL; | ||
2807 | |||
2794 | ret = ib_copy_from_udata(&cmd, ucore, sizeof(cmd)); | 2808 | ret = ib_copy_from_udata(&cmd, ucore, sizeof(cmd)); |
2795 | if (ret) | 2809 | if (ret) |
2796 | return ret; | 2810 | return ret; |
2797 | 2811 | ||
2812 | if (cmd.comp_mask) | ||
2813 | return -EINVAL; | ||
2814 | |||
2798 | uobj = idr_write_uobj(&ib_uverbs_rule_idr, cmd.flow_handle, | 2815 | uobj = idr_write_uobj(&ib_uverbs_rule_idr, cmd.flow_handle, |
2799 | file->ucontext); | 2816 | file->ucontext); |
2800 | if (!uobj) | 2817 | if (!uobj) |