aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2008-08-18 10:34:34 -0400
committerVlad Yasevich <vladislav.yasevich@hp.com>2008-10-01 11:33:06 -0400
commit52cae8f06babf9eed327479c1aa024ce3732f912 (patch)
tree2ef0dc1e4daf53735681ba7223d40058f1175092
parentc226ef9b83694311327f3ab0036c6de9c22e9daf (diff)
sctp: try harder to figure out address family when checking wildcards
sctp_is_any() function that is used to check for wildcard addresses only looks at the address itself to determine the address family. This function is used in the API to check the address passed in from the user. If the user simply zerroes out the sockaddr_storage and pass that in, we'll end up failing. So, let's try harder to determine the address family by also checking the socket if it's possible. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
-rw-r--r--include/net/sctp/structs.h2
-rw-r--r--net/sctp/bind_addr.c16
-rw-r--r--net/sctp/ipv6.c5
-rw-r--r--net/sctp/socket.c10
4 files changed, 22 insertions, 11 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 0dc1b7267c37..94c62e4ddea9 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1228,7 +1228,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len,
1228 1228
1229sctp_scope_t sctp_scope(const union sctp_addr *); 1229sctp_scope_t sctp_scope(const union sctp_addr *);
1230int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope); 1230int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope);
1231int sctp_is_any(const union sctp_addr *addr); 1231int sctp_is_any(struct sock *sk, const union sctp_addr *addr);
1232int sctp_addr_is_valid(const union sctp_addr *addr); 1232int sctp_addr_is_valid(const union sctp_addr *addr);
1233 1233
1234 1234
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index f62bc2468935..6d5944a745d4 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -457,7 +457,7 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
457{ 457{
458 int error = 0; 458 int error = 0;
459 459
460 if (sctp_is_any(addr)) { 460 if (sctp_is_any(NULL, addr)) {
461 error = sctp_copy_local_addr_list(dest, scope, gfp, flags); 461 error = sctp_copy_local_addr_list(dest, scope, gfp, flags);
462 } else if (sctp_in_scope(addr, scope)) { 462 } else if (sctp_in_scope(addr, scope)) {
463 /* Now that the address is in scope, check to see if 463 /* Now that the address is in scope, check to see if
@@ -477,11 +477,21 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
477} 477}
478 478
479/* Is this a wildcard address? */ 479/* Is this a wildcard address? */
480int sctp_is_any(const union sctp_addr *addr) 480int sctp_is_any(struct sock *sk, const union sctp_addr *addr)
481{ 481{
482 struct sctp_af *af = sctp_get_af_specific(addr->sa.sa_family); 482 unsigned short fam = 0;
483 struct sctp_af *af;
484
485 /* Try to get the right address family */
486 if (addr->sa.sa_family != AF_UNSPEC)
487 fam = addr->sa.sa_family;
488 else if (sk)
489 fam = sk->sk_family;
490
491 af = sctp_get_af_specific(fam);
483 if (!af) 492 if (!af)
484 return 0; 493 return 0;
494
485 return af->is_any(addr); 495 return af->is_any(addr);
486} 496}
487 497
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 47f91afa0211..c78da3c9dd34 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -837,6 +837,7 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
837 struct sctp_sock *opt) 837 struct sctp_sock *opt)
838{ 838{
839 struct sctp_af *af1, *af2; 839 struct sctp_af *af1, *af2;
840 struct sock *sk = sctp_opt2sk(opt);
840 841
841 af1 = sctp_get_af_specific(addr1->sa.sa_family); 842 af1 = sctp_get_af_specific(addr1->sa.sa_family);
842 af2 = sctp_get_af_specific(addr2->sa.sa_family); 843 af2 = sctp_get_af_specific(addr2->sa.sa_family);
@@ -845,11 +846,11 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
845 return 0; 846 return 0;
846 847
847 /* If the socket is IPv6 only, v4 addrs will not match */ 848 /* If the socket is IPv6 only, v4 addrs will not match */
848 if (__ipv6_only_sock(sctp_opt2sk(opt)) && af1 != af2) 849 if (__ipv6_only_sock(sk) && af1 != af2)
849 return 0; 850 return 0;
850 851
851 /* Today, wildcard AF_INET/AF_INET6. */ 852 /* Today, wildcard AF_INET/AF_INET6. */
852 if (sctp_is_any(addr1) || sctp_is_any(addr2)) 853 if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2))
853 return 1; 854 return 1;
854 855
855 if (addr1->sa.sa_family != addr2->sa.sa_family) 856 if (addr1->sa.sa_family != addr2->sa.sa_family)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5ffb9dec1c3f..a1b904529d5e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2309,7 +2309,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
2309 /* If an address other than INADDR_ANY is specified, and 2309 /* If an address other than INADDR_ANY is specified, and
2310 * no transport is found, then the request is invalid. 2310 * no transport is found, then the request is invalid.
2311 */ 2311 */
2312 if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) { 2312 if (!sctp_is_any(sk, ( union sctp_addr *)&params.spp_address)) {
2313 trans = sctp_addr_id2transport(sk, &params.spp_address, 2313 trans = sctp_addr_id2transport(sk, &params.spp_address,
2314 params.spp_assoc_id); 2314 params.spp_assoc_id);
2315 if (!trans) 2315 if (!trans)
@@ -4062,7 +4062,7 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
4062 /* If an address other than INADDR_ANY is specified, and 4062 /* If an address other than INADDR_ANY is specified, and
4063 * no transport is found, then the request is invalid. 4063 * no transport is found, then the request is invalid.
4064 */ 4064 */
4065 if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) { 4065 if (!sctp_is_any(sk, ( union sctp_addr *)&params.spp_address)) {
4066 trans = sctp_addr_id2transport(sk, &params.spp_address, 4066 trans = sctp_addr_id2transport(sk, &params.spp_address,
4067 params.spp_assoc_id); 4067 params.spp_assoc_id);
4068 if (!trans) { 4068 if (!trans) {
@@ -4414,7 +4414,7 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
4414 if (sctp_list_single_entry(&bp->address_list)) { 4414 if (sctp_list_single_entry(&bp->address_list)) {
4415 addr = list_entry(bp->address_list.next, 4415 addr = list_entry(bp->address_list.next,
4416 struct sctp_sockaddr_entry, list); 4416 struct sctp_sockaddr_entry, list);
4417 if (sctp_is_any(&addr->a)) { 4417 if (sctp_is_any(sk, &addr->a)) {
4418 rcu_read_lock(); 4418 rcu_read_lock();
4419 list_for_each_entry_rcu(addr, 4419 list_for_each_entry_rcu(addr,
4420 &sctp_local_addr_list, list) { 4420 &sctp_local_addr_list, list) {
@@ -4602,7 +4602,7 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
4602 if (sctp_list_single_entry(&bp->address_list)) { 4602 if (sctp_list_single_entry(&bp->address_list)) {
4603 addr = list_entry(bp->address_list.next, 4603 addr = list_entry(bp->address_list.next,
4604 struct sctp_sockaddr_entry, list); 4604 struct sctp_sockaddr_entry, list);
4605 if (sctp_is_any(&addr->a)) { 4605 if (sctp_is_any(sk, &addr->a)) {
4606 cnt = sctp_copy_laddrs_old(sk, bp->port, 4606 cnt = sctp_copy_laddrs_old(sk, bp->port,
4607 getaddrs.addr_num, 4607 getaddrs.addr_num,
4608 addrs, &bytes_copied); 4608 addrs, &bytes_copied);
@@ -4695,7 +4695,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
4695 if (sctp_list_single_entry(&bp->address_list)) { 4695 if (sctp_list_single_entry(&bp->address_list)) {
4696 addr = list_entry(bp->address_list.next, 4696 addr = list_entry(bp->address_list.next,
4697 struct sctp_sockaddr_entry, list); 4697 struct sctp_sockaddr_entry, list);
4698 if (sctp_is_any(&addr->a)) { 4698 if (sctp_is_any(sk, &addr->a)) {
4699 cnt = sctp_copy_laddrs(sk, bp->port, addrs, 4699 cnt = sctp_copy_laddrs(sk, bp->port, addrs,
4700 space_left, &bytes_copied); 4700 space_left, &bytes_copied);
4701 if (cnt < 0) { 4701 if (cnt < 0) {