summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/addr.c16
-rw-r--r--drivers/infiniband/core/ucma.c34
-rw-r--r--include/rdma/ib_addr.h2
3 files changed, 35 insertions, 17 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index c3e6811bb1bd..cb1d2ab13c66 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -207,6 +207,22 @@ int rdma_addr_size(struct sockaddr *addr)
207} 207}
208EXPORT_SYMBOL(rdma_addr_size); 208EXPORT_SYMBOL(rdma_addr_size);
209 209
210int rdma_addr_size_in6(struct sockaddr_in6 *addr)
211{
212 int ret = rdma_addr_size((struct sockaddr *) addr);
213
214 return ret <= sizeof(*addr) ? ret : 0;
215}
216EXPORT_SYMBOL(rdma_addr_size_in6);
217
218int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr)
219{
220 int ret = rdma_addr_size((struct sockaddr *) addr);
221
222 return ret <= sizeof(*addr) ? ret : 0;
223}
224EXPORT_SYMBOL(rdma_addr_size_kss);
225
210static struct rdma_addr_client self; 226static struct rdma_addr_client self;
211 227
212void rdma_addr_register_client(struct rdma_addr_client *client) 228void rdma_addr_register_client(struct rdma_addr_client *client)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 21585055cf32..d933336d7e01 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -632,6 +632,9 @@ static ssize_t ucma_bind_ip(struct ucma_file *file, const char __user *inbuf,
632 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 632 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
633 return -EFAULT; 633 return -EFAULT;
634 634
635 if (!rdma_addr_size_in6(&cmd.addr))
636 return -EINVAL;
637
635 ctx = ucma_get_ctx(file, cmd.id); 638 ctx = ucma_get_ctx(file, cmd.id);
636 if (IS_ERR(ctx)) 639 if (IS_ERR(ctx))
637 return PTR_ERR(ctx); 640 return PTR_ERR(ctx);
@@ -645,22 +648,21 @@ static ssize_t ucma_bind(struct ucma_file *file, const char __user *inbuf,
645 int in_len, int out_len) 648 int in_len, int out_len)
646{ 649{
647 struct rdma_ucm_bind cmd; 650 struct rdma_ucm_bind cmd;
648 struct sockaddr *addr;
649 struct ucma_context *ctx; 651 struct ucma_context *ctx;
650 int ret; 652 int ret;
651 653
652 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 654 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
653 return -EFAULT; 655 return -EFAULT;
654 656
655 addr = (struct sockaddr *) &cmd.addr; 657 if (cmd.reserved || !cmd.addr_size ||
656 if (cmd.reserved || !cmd.addr_size || (cmd.addr_size != rdma_addr_size(addr))) 658 cmd.addr_size != rdma_addr_size_kss(&cmd.addr))
657 return -EINVAL; 659 return -EINVAL;
658 660
659 ctx = ucma_get_ctx(file, cmd.id); 661 ctx = ucma_get_ctx(file, cmd.id);
660 if (IS_ERR(ctx)) 662 if (IS_ERR(ctx))
661 return PTR_ERR(ctx); 663 return PTR_ERR(ctx);
662 664
663 ret = rdma_bind_addr(ctx->cm_id, addr); 665 ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr);
664 ucma_put_ctx(ctx); 666 ucma_put_ctx(ctx);
665 return ret; 667 return ret;
666} 668}
@@ -670,23 +672,22 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file,
670 int in_len, int out_len) 672 int in_len, int out_len)
671{ 673{
672 struct rdma_ucm_resolve_ip cmd; 674 struct rdma_ucm_resolve_ip cmd;
673 struct sockaddr *src, *dst;
674 struct ucma_context *ctx; 675 struct ucma_context *ctx;
675 int ret; 676 int ret;
676 677
677 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 678 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
678 return -EFAULT; 679 return -EFAULT;
679 680
680 src = (struct sockaddr *) &cmd.src_addr; 681 if (!rdma_addr_size_in6(&cmd.src_addr) ||
681 dst = (struct sockaddr *) &cmd.dst_addr; 682 !rdma_addr_size_in6(&cmd.dst_addr))
682 if (!rdma_addr_size(src) || !rdma_addr_size(dst))
683 return -EINVAL; 683 return -EINVAL;
684 684
685 ctx = ucma_get_ctx(file, cmd.id); 685 ctx = ucma_get_ctx(file, cmd.id);
686 if (IS_ERR(ctx)) 686 if (IS_ERR(ctx))
687 return PTR_ERR(ctx); 687 return PTR_ERR(ctx);
688 688
689 ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms); 689 ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
690 (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms);
690 ucma_put_ctx(ctx); 691 ucma_put_ctx(ctx);
691 return ret; 692 return ret;
692} 693}
@@ -696,24 +697,23 @@ static ssize_t ucma_resolve_addr(struct ucma_file *file,
696 int in_len, int out_len) 697 int in_len, int out_len)
697{ 698{
698 struct rdma_ucm_resolve_addr cmd; 699 struct rdma_ucm_resolve_addr cmd;
699 struct sockaddr *src, *dst;
700 struct ucma_context *ctx; 700 struct ucma_context *ctx;
701 int ret; 701 int ret;
702 702
703 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 703 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
704 return -EFAULT; 704 return -EFAULT;
705 705
706 src = (struct sockaddr *) &cmd.src_addr; 706 if (cmd.reserved ||
707 dst = (struct sockaddr *) &cmd.dst_addr; 707 (cmd.src_size && (cmd.src_size != rdma_addr_size_kss(&cmd.src_addr))) ||
708 if (cmd.reserved || (cmd.src_size && (cmd.src_size != rdma_addr_size(src))) || 708 !cmd.dst_size || (cmd.dst_size != rdma_addr_size_kss(&cmd.dst_addr)))
709 !cmd.dst_size || (cmd.dst_size != rdma_addr_size(dst)))
710 return -EINVAL; 709 return -EINVAL;
711 710
712 ctx = ucma_get_ctx(file, cmd.id); 711 ctx = ucma_get_ctx(file, cmd.id);
713 if (IS_ERR(ctx)) 712 if (IS_ERR(ctx))
714 return PTR_ERR(ctx); 713 return PTR_ERR(ctx);
715 714
716 ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms); 715 ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
716 (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms);
717 ucma_put_ctx(ctx); 717 ucma_put_ctx(ctx);
718 return ret; 718 return ret;
719} 719}
@@ -1433,7 +1433,7 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
1433 join_cmd.response = cmd.response; 1433 join_cmd.response = cmd.response;
1434 join_cmd.uid = cmd.uid; 1434 join_cmd.uid = cmd.uid;
1435 join_cmd.id = cmd.id; 1435 join_cmd.id = cmd.id;
1436 join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr); 1436 join_cmd.addr_size = rdma_addr_size_in6(&cmd.addr);
1437 if (!join_cmd.addr_size) 1437 if (!join_cmd.addr_size)
1438 return -EINVAL; 1438 return -EINVAL;
1439 1439
@@ -1452,7 +1452,7 @@ static ssize_t ucma_join_multicast(struct ucma_file *file,
1452 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 1452 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
1453 return -EFAULT; 1453 return -EFAULT;
1454 1454
1455 if (!rdma_addr_size((struct sockaddr *)&cmd.addr)) 1455 if (!rdma_addr_size_kss(&cmd.addr))
1456 return -EINVAL; 1456 return -EINVAL;
1457 1457
1458 return ucma_process_join(file, &cmd, out_len); 1458 return ucma_process_join(file, &cmd, out_len);
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index d656809f1217..415e09960017 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -130,6 +130,8 @@ void rdma_copy_addr(struct rdma_dev_addr *dev_addr,
130 const unsigned char *dst_dev_addr); 130 const unsigned char *dst_dev_addr);
131 131
132int rdma_addr_size(struct sockaddr *addr); 132int rdma_addr_size(struct sockaddr *addr);
133int rdma_addr_size_in6(struct sockaddr_in6 *addr);
134int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr);
133 135
134int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid, 136int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
135 const union ib_gid *dgid, 137 const union ib_gid *dgid,