Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband

Pull infiniband fixes from Roland Dreier:
"Last batch of InfiniBand/RDMA changes for 3.13 / 2014:
- Additional checks for uverbs to ensure forward compatibility,
handle malformed input better.
- Fix potential use-after-free in iWARP connection manager.
- Make a function static"

* tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
IB/uverbs: Check access to userspace response buffer in extended command
IB/uverbs: Check input length in flow steering uverbs
IB/uverbs: Set error code when fail to consume all flow_spec items
IB/uverbs: Check reserved fields in create_flow
IB/uverbs: Check comp_mask in destroy_flow
IB/uverbs: Check reserved field in extended command header
IB/uverbs: New macro to set pointers to NULL if length is 0 in INIT_UDATA()
IB/core: const'ify inbuf in struct ib_udata
RDMA/iwcm: Don't touch cm_id after deref in rem_ref
RDMA/cxgb4: Make _c4iw_write_mem_dma() static

+52 -15
+9 -2
drivers/infiniband/core/iwcm.c
··· 181 181 static void rem_ref(struct iw_cm_id *cm_id) 182 182 { 183 183 struct iwcm_id_private *cm_id_priv; 184 + int cb_destroy; 185 + 184 186 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); 185 - if (iwcm_deref_id(cm_id_priv) && 186 - test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) { 187 + 188 + /* 189 + * Test bit before deref in case the cm_id gets freed on another 190 + * thread. 191 + */ 192 + cb_destroy = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags); 193 + if (iwcm_deref_id(cm_id_priv) && cb_destroy) { 187 194 BUG_ON(!list_empty(&cm_id_priv->work_list)); 188 195 free_cm_id(cm_id_priv); 189 196 }
+9 -1
drivers/infiniband/core/uverbs.h
··· 49 49 50 50 #define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \ 51 51 do { \ 52 - (udata)->inbuf = (void __user *) (ibuf); \ 52 + (udata)->inbuf = (const void __user *) (ibuf); \ 53 53 (udata)->outbuf = (void __user *) (obuf); \ 54 54 (udata)->inlen = (ilen); \ 55 55 (udata)->outlen = (olen); \ 56 + } while (0) 57 + 58 + #define INIT_UDATA_BUF_OR_NULL(udata, ibuf, obuf, ilen, olen) \ 59 + do { \ 60 + (udata)->inbuf = (ilen) ? (const void __user *) (ibuf) : NULL; \ 61 + (udata)->outbuf = (olen) ? (void __user *) (obuf) : NULL; \ 62 + (udata)->inlen = (ilen); \ 63 + (udata)->outlen = (olen); \ 56 64 } while (0) 57 65 58 66 /*
+17
drivers/infiniband/core/uverbs_cmd.c
··· 2593 2593 static int kern_spec_to_ib_spec(struct ib_uverbs_flow_spec *kern_spec, 2594 2594 union ib_flow_spec *ib_spec) 2595 2595 { 2596 + if (kern_spec->reserved) 2597 + return -EINVAL; 2598 + 2596 2599 ib_spec->type = kern_spec->type; 2597 2600 2598 2601 switch (ib_spec->type) { ··· 2649 2646 void *ib_spec; 2650 2647 int i; 2651 2648 2649 + if (ucore->inlen < sizeof(cmd)) 2650 + return -EINVAL; 2651 + 2652 2652 if (ucore->outlen < sizeof(resp)) 2653 2653 return -ENOSPC; 2654 2654 ··· 2675 2669 if (cmd.flow_attr.size > ucore->inlen || 2676 2670 cmd.flow_attr.size > 2677 2671 (cmd.flow_attr.num_of_specs * sizeof(struct ib_uverbs_flow_spec))) 2672 + return -EINVAL; 2673 + 2674 + if (cmd.flow_attr.reserved[0] || 2675 + cmd.flow_attr.reserved[1]) 2678 2676 return -EINVAL; 2679 2677 2680 2678 if (cmd.flow_attr.num_of_specs) { ··· 2741 2731 if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) { 2742 2732 pr_warn("create flow failed, flow %d: %d bytes left from uverb cmd\n", 2743 2733 i, cmd.flow_attr.size); 2734 + err = -EINVAL; 2744 2735 goto err_free; 2745 2736 } 2746 2737 flow_id = ib_create_flow(qp, flow_attr, IB_FLOW_DOMAIN_USER); ··· 2802 2791 struct ib_uobject *uobj; 2803 2792 int ret; 2804 2793 2794 + if (ucore->inlen < sizeof(cmd)) 2795 + return -EINVAL; 2796 + 2805 2797 ret = ib_copy_from_udata(&cmd, ucore, sizeof(cmd)); 2806 2798 if (ret) 2807 2799 return ret; 2800 + 2801 + if (cmd.comp_mask) 2802 + return -EINVAL; 2808 2803 2809 2804 uobj = idr_write_uobj(&ib_uverbs_rule_idr, cmd.flow_handle, 2810 2805 file->ucontext);
+15 -10
drivers/infiniband/core/uverbs_main.c
··· 668 668 if ((hdr.in_words + ex_hdr.provider_in_words) * 8 != count) 669 669 return -EINVAL; 670 670 671 + if (ex_hdr.cmd_hdr_reserved) 672 + return -EINVAL; 673 + 671 674 if (ex_hdr.response) { 672 675 if (!hdr.out_words && !ex_hdr.provider_out_words) 673 676 return -EINVAL; 677 + 678 + if (!access_ok(VERIFY_WRITE, 679 + (void __user *) (unsigned long) ex_hdr.response, 680 + (hdr.out_words + ex_hdr.provider_out_words) * 8)) 681 + return -EFAULT; 674 682 } else { 675 683 if (hdr.out_words || ex_hdr.provider_out_words) 676 684 return -EINVAL; 677 685 } 678 686 679 - INIT_UDATA(&ucore, 680 - (hdr.in_words) ? buf : 0, 681 - (unsigned long)ex_hdr.response, 682 - hdr.in_words * 8, 683 - hdr.out_words * 8); 687 + INIT_UDATA_BUF_OR_NULL(&ucore, buf, (unsigned long) ex_hdr.response, 688 + hdr.in_words * 8, hdr.out_words * 8); 684 689 685 - INIT_UDATA(&uhw, 686 - (ex_hdr.provider_in_words) ? buf + ucore.inlen : 0, 687 - (ex_hdr.provider_out_words) ? (unsigned long)ex_hdr.response + ucore.outlen : 0, 688 - ex_hdr.provider_in_words * 8, 689 - ex_hdr.provider_out_words * 8); 690 + INIT_UDATA_BUF_OR_NULL(&uhw, 691 + buf + ucore.inlen, 692 + (unsigned long) ex_hdr.response + ucore.outlen, 693 + ex_hdr.provider_in_words * 8, 694 + ex_hdr.provider_out_words * 8); 690 695 691 696 err = uverbs_ex_cmd_table[command](file, 692 697 &ucore,
+1 -1
drivers/infiniband/hw/cxgb4/mem.c
··· 173 173 return ret; 174 174 } 175 175 176 - int _c4iw_write_mem_dma(struct c4iw_rdev *rdev, u32 addr, u32 len, void *data) 176 + static int _c4iw_write_mem_dma(struct c4iw_rdev *rdev, u32 addr, u32 len, void *data) 177 177 { 178 178 u32 remain = len; 179 179 u32 dmalen;
+1 -1
include/rdma/ib_verbs.h
··· 978 978 }; 979 979 980 980 struct ib_udata { 981 - void __user *inbuf; 981 + const void __user *inbuf; 982 982 void __user *outbuf; 983 983 size_t inlen; 984 984 size_t outlen;