diff options
author | Ben Murdoch <benm@google.com> | 2014-07-20 18:31:19 -0700 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2014-07-20 18:31:19 -0700 |
commit | ed9a6fb519aa7606cab965b2c4218756e849ddb6 (patch) | |
tree | e44213c06aa2801acffafafef538021815559979 | |
parent | 46100e9a86ac58447f99ee8ed55a9d7eb01d101a (diff) | |
parent | 20d3b9ce7744465ea350696de9160a349cd52a05 (diff) | |
download | usrsctplib-ed9a6fb519aa7606cab965b2c4218756e849ddb6.tar.gz |
Merge from Chromium at DEPS revision 284076android-wear-5.1.1_r1android-wear-5.1.0_r1
This commit was generated by merge_to_master.py.
Change-Id: Id9832ab1559c6be7b68890be21e02a23214c7e5f
-rwxr-xr-x | netinet/sctp_asconf.c | 68 | ||||
-rwxr-xr-x | netinet/sctp_input.c | 8 | ||||
-rwxr-xr-x | netinet/sctp_os_userspace.h | 18 | ||||
-rwxr-xr-x | netinet/sctp_output.c | 244 | ||||
-rwxr-xr-x | netinet/sctp_pcb.c | 121 | ||||
-rwxr-xr-x | netinet/sctp_sysctl.c | 14 | ||||
-rwxr-xr-x | netinet/sctp_timer.c | 4 | ||||
-rwxr-xr-x | netinet/sctp_userspace.c | 4 | ||||
-rwxr-xr-x | netinet/sctp_usrreq.c | 131 | ||||
-rwxr-xr-x | netinet/sctputil.c | 14 | ||||
-rwxr-xr-x | user_malloc.h | 10 | ||||
-rwxr-xr-x | user_socket.c | 2 | ||||
-rw-r--r-- | usrsctp.h | 1 |
13 files changed, 543 insertions, 96 deletions
diff --git a/netinet/sctp_asconf.c b/netinet/sctp_asconf.c index 3f8b5f2..0f35ae1 100755 --- a/netinet/sctp_asconf.c +++ b/netinet/sctp_asconf.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 257803 2013-11-07 17:08:09Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 267674 2014-06-20 13:26:49Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -1296,7 +1296,7 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa, { struct sockaddr_in *sin; - sin= (struct sockaddr_in *)&ifa->address.sa; + sin = (struct sockaddr_in *)&ifa->address.sa; aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS; aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param)); aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + @@ -1900,14 +1900,26 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, * this is boundall or subset bound w/ASCONF allowed */ - /* first, make sure it's a good address family */ + /* first, make sure that the address is IPv4 or IPv6 and not jailed */ switch (ifa->address.sa.sa_family) { #ifdef INET6 case AF_INET6: +#if defined(__FreeBSD__) + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &ifa->address.sin6.sin6_addr) != 0) { + return; + } +#endif break; #endif #ifdef INET case AF_INET: +#if defined(__FreeBSD__) + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &ifa->address.sin.sin_addr) != 0) { + return; + } +#endif break; #endif default: @@ -2134,6 +2146,12 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, /* we skip unspecifed addresses */ continue; } +#if defined(__FreeBSD__) + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } +#endif if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (stcb->asoc.scope.local_scope == 0) { continue; @@ -2164,6 +2182,12 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, /* we skip unspecifed addresses */ continue; } +#if defined(__FreeBSD__) + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } +#endif if (stcb->asoc.scope.ipv4_local_scope == 0 && IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { continue; @@ -2221,7 +2245,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, } else if (type == SCTP_SET_PRIM_ADDR) { if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { /* must validate the ifa is in the ep */ - if (sctp_is_addr_in_ep(stcb->sctp_ep,ifa) == 0) { + if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) { continue; } } else { @@ -2477,6 +2501,12 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked) /* skip unspecifed addresses */ continue; } +#if defined(__FreeBSD__) + if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } +#endif if (stcb->asoc.scope.ipv4_local_scope == 0 && IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) continue; @@ -2505,6 +2535,12 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked) /* we skip unspecifed addresses */ continue; } +#if defined(__FreeBSD__) + if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } +#endif if (stcb->asoc.scope.local_scope == 0 && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) continue; @@ -3116,6 +3152,12 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset, #ifdef INET case AF_INET: sin = (struct sockaddr_in *)&sctp_ifa->address.sin; +#if defined(__FreeBSD__) + if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } +#endif if ((ipv4_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { /* private address not in scope */ @@ -3126,6 +3168,12 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset, #ifdef INET6 case AF_INET6: sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sin6; +#if defined(__FreeBSD__) + if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } +#endif if ((local_scope == 0) && (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) { continue; @@ -3413,6 +3461,12 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb, #ifdef INET case AF_INET: to = &sctp_ifap->address.sin; +#if defined(__FreeBSD__) + if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, + &to->sin_addr) != 0) { + continue; + } +#endif if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) { continue; } @@ -3424,6 +3478,12 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb, #ifdef INET6 case AF_INET6: to6 = &sctp_ifap->address.sin6; +#if defined(__FreeBSD__) + if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, + &to6->sin6_addr) != 0) { + continue; + } +#endif if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) { continue; } diff --git a/netinet/sctp_input.c b/netinet/sctp_input.c index 889f9bb..df244e8 100755 --- a/netinet/sctp_input.c +++ b/netinet/sctp_input.c @@ -49,9 +49,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 263237 2014-03-16 12:32:16Z tu #include <netinet/sctp_bsd_addr.h> #include <netinet/sctp_timer.h> #include <netinet/sctp_crc32.h> +#if defined INET || defined INET6 #if !defined(__Userspace_os_Windows) #include <netinet/udp.h> #endif +#endif #if defined(__FreeBSD__) #include <sys/smp.h> #endif @@ -5754,12 +5756,14 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt calc_check, check, (void *)m, length, iphlen); stcb = sctp_findassociation_addr(m, offset, src, dst, sh, ch, &inp, &net, vrf_id); +#if defined INET || defined INET6 if ((net != NULL) && (port != 0)) { if (net->port == 0) { sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); } net->port = port; } +#endif #if defined(__FreeBSD__) if ((net != NULL) && (use_mflowid != 0)) { net->flowid = mflowid; @@ -5787,12 +5791,14 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt } stcb = sctp_findassociation_addr(m, offset, src, dst, sh, ch, &inp, &net, vrf_id); +#if defined INET || defined INET6 if ((net != NULL) && (port != 0)) { if (net->port == 0) { sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); } net->port = port; } +#endif #if defined(__FreeBSD__) if ((net != NULL) && (use_mflowid != 0)) { net->flowid = mflowid; @@ -5921,12 +5927,14 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt * and it changes our INP. */ inp = stcb->sctp_ep; +#if defined INET || defined INET6 if ((net) && (port)) { if (net->port == 0) { sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); } net->port = port; } +#endif } } else { /* diff --git a/netinet/sctp_os_userspace.h b/netinet/sctp_os_userspace.h index f863295..eca3e18 100755 --- a/netinet/sctp_os_userspace.h +++ b/netinet/sctp_os_userspace.h @@ -217,11 +217,6 @@ typedef HANDLE userland_thread_t; typedef char* caddr_t; -int Win_getifaddrs(struct ifaddrs**); -#define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces) -int win_if_nametoindex(const char *); -#define if_nametoindex(x) win_if_nametoindex(x) - #define bzero(buf, len) memset(buf, 0, len) #define bcopy(srcKey, dstKey, len) memcpy(dstKey, srcKey, len) #define snprintf(data, size, format, ...) _snprintf_s(data, size, _TRUNCATE, format, __VA_ARGS__) @@ -399,6 +394,11 @@ struct udphdr { unsigned __int16 uh_sum; }; +int Win_getifaddrs(struct ifaddrs**); +#define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces) +int win_if_nametoindex(const char *); +#define if_nametoindex(x) win_if_nametoindex(x) + #else /* !defined(Userspace_os_Windows) */ #include <sys/cdefs.h> /* needed? added from old __FreeBSD__ */ #include <sys/socket.h> @@ -474,9 +474,13 @@ struct sx {int dummy;}; #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> -#include <netinet/ip_icmp.h> -#else +#endif +#if defined INET +#if defined(__Userspace_os_Windows) #include <user_ip_icmp.h> +#else +#include <netinet/ip_icmp.h> +#endif #endif /* #include <netinet/in_pcb.h> ported to userspace */ #include <user_inpcb.h> diff --git a/netinet/sctp_output.c b/netinet/sctp_output.c index 72f6bc3..14f2cc0 100755 --- a/netinet/sctp_output.c +++ b/netinet/sctp_output.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 264017 2014-04-01 18:38:04Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 267674 2014-06-20 13:26:49Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -57,9 +57,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 264017 2014-04-01 18:38:04Z t #if defined(__Userspace_os_Linux) #define __FAVOR_BSD /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */ #endif +#if defined INET || defined INET6 #if !defined(__Userspace_os_Windows) #include <netinet/udp.h> #endif +#endif #if defined(__APPLE__) #include <netinet/in.h> #endif @@ -2096,6 +2098,22 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb, continue; } LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) { +#if defined(__FreeBSD__) +#ifdef INET + if ((sctp_ifap->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifap->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifap->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifap->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif +#endif if (sctp_is_addr_restricted(stcb, sctp_ifap)) { continue; } @@ -2130,6 +2148,22 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb, continue; } LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) { +#if defined(__FreeBSD__) +#ifdef INET + if ((sctp_ifap->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifap->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifap->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifap->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif +#endif if (sctp_is_addr_restricted(stcb, sctp_ifap)) { continue; } @@ -2502,6 +2536,22 @@ sctp_choose_boundspecific_inp(struct sctp_inpcb *inp, if (sctp_ifn) { /* is a preferred one on the interface we route out? */ LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { +#if defined(__FreeBSD__) +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; @@ -2628,6 +2678,22 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp, if (sctp_ifn) { /* first try for a preferred address on the ep */ LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { +#if defined(__FreeBSD__) +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; if (sctp_is_addr_in_ep(inp, sctp_ifa)) { @@ -2648,6 +2714,22 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp, } /* next try for an acceptable address on the ep */ LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { +#if defined(__FreeBSD__) +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; if (sctp_is_addr_in_ep(inp, sctp_ifa)) { @@ -2753,6 +2835,11 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp, static struct sctp_ifa * sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn, +#if defined(__FreeBSD__) + struct sctp_inpcb *inp, +#else + struct sctp_inpcb *inp SCTP_UNUSED, +#endif struct sctp_tcb *stcb, int non_asoc_addr_ok, uint8_t dest_is_loop, @@ -2779,6 +2866,22 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn, #endif /* SCTP_EMBEDDED_V6_SCOPE */ #endif /* INET6 */ LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) { +#if defined(__FreeBSD__) +#ifdef INET + if ((ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif +#endif if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; @@ -2866,6 +2969,11 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn, static int sctp_count_num_preferred_boundall(struct sctp_ifn *ifn, +#if defined(__FreeBSD__) + struct sctp_inpcb *inp, +#else + struct sctp_inpcb *inp SCTP_UNUSED, +#endif struct sctp_tcb *stcb, int non_asoc_addr_ok, uint8_t dest_is_loop, @@ -2876,6 +2984,23 @@ sctp_count_num_preferred_boundall(struct sctp_ifn *ifn, int num_eligible_addr = 0; LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) { +#if defined(__FreeBSD__) +#ifdef INET + if ((ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((ifa->address.sa.sa_family == AF_INET6) && + (stcb != NULL) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif +#endif if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) { continue; @@ -2907,7 +3032,8 @@ sctp_count_num_preferred_boundall(struct sctp_ifn *ifn, } static struct sctp_ifa * -sctp_choose_boundall(struct sctp_tcb *stcb, +sctp_choose_boundall(struct sctp_inpcb *inp, + struct sctp_tcb *stcb, struct sctp_nets *net, sctp_route_t *ro, uint32_t vrf_id, @@ -2960,7 +3086,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb, cur_addr_num = net->indx_of_eligible_next_to_use; } num_preferred = sctp_count_num_preferred_boundall(sctp_ifn, - stcb, + inp, stcb, non_asoc_addr_ok, dest_is_loop, dest_is_priv, fam); @@ -2987,7 +3113,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb, */ SCTPDBG(SCTP_DEBUG_OUTPUT2, "cur_addr_num:%d\n", cur_addr_num); - sctp_ifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop, + sctp_ifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop, dest_is_priv, cur_addr_num, fam, ro); /* if sctp_ifa is NULL something changed??, fall to plan b. */ @@ -3018,7 +3144,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb, SCTPDBG(SCTP_DEBUG_OUTPUT2, "already seen\n"); continue; } - num_preferred = sctp_count_num_preferred_boundall(sctp_ifn, stcb, non_asoc_addr_ok, + num_preferred = sctp_count_num_preferred_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop, dest_is_priv, fam); SCTPDBG(SCTP_DEBUG_OUTPUT2, "Found ifn:%p %d preferred source addresses\n", @@ -3040,7 +3166,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb, if (cur_addr_num >= num_preferred) { cur_addr_num = 0; } - sifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop, + sifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop, dest_is_priv, cur_addr_num, fam, ro); if (sifa == NULL) continue; @@ -3068,6 +3194,24 @@ again_with_private_addresses_allowed: } LIST_FOREACH(sctp_ifa, &emit_ifn->ifalist, next_ifa) { SCTPDBG(SCTP_DEBUG_OUTPUT2, "ifa:%p\n", (void *)sctp_ifa); +#if defined(__FreeBSD__) +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + SCTPDBG(SCTP_DEBUG_OUTPUT2,"Jailed\n"); + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + SCTPDBG(SCTP_DEBUG_OUTPUT2,"Jailed\n"); + continue; + } +#endif +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) { SCTPDBG(SCTP_DEBUG_OUTPUT2,"Defer\n"); @@ -3118,6 +3262,22 @@ again_with_private_addresses_allowed: continue; } LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { +#if defined(__FreeBSD__) +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; @@ -3168,6 +3328,22 @@ out: LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { struct sctp_ifa *tmp_sifa; +#if defined(__FreeBSD__) +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; @@ -3352,7 +3528,7 @@ sctp_source_address_selection(struct sctp_inpcb *inp, /* * Bound all case */ - answer = sctp_choose_boundall(stcb, net, ro, vrf_id, + answer = sctp_choose_boundall(inp, stcb, net, ro, vrf_id, dest_is_priv, dest_is_loop, non_asoc_addr_ok, fam); SCTP_IPI_ADDR_RUNLOCK(); @@ -11280,11 +11456,11 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, struct mbuf *mout; struct sctphdr *shout; struct sctp_chunkhdr *ch; - struct udphdr *udp; - int len, cause_len, padding_len; #if defined(INET) || defined(INET6) + struct udphdr *udp; int ret; #endif + int len, cause_len, padding_len; #ifdef INET #if defined(__APPLE__) || defined(__Panda__) sctp_route_t ro; @@ -11336,9 +11512,11 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, default: break; } +#if defined INET || defined INET6 if (port) { len += sizeof(struct udphdr); } +#endif #if defined(__APPLE__) #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) mout = sctp_get_mbuf_for_msg(len + max_linkhdr, 1, M_NOWAIT, 1, MT_DATA); @@ -11443,6 +11621,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, shout = mtod(mout, struct sctphdr *); break; } +#if defined INET || defined INET6 if (port) { if (htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) == 0) { sctp_m_freem(mout); @@ -11461,6 +11640,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, } else { udp = NULL; } +#endif shout->src_port = sh->dest_port; shout->dest_port = sh->src_port; shout->checksum = 0; @@ -12532,8 +12712,8 @@ sctp_copy_resume(struct uio *uio, m = m_uiotombuf(uio, M_WAITOK, max_send_len, 0, (user_marks_eor ? M_EOR : 0)); if (m == NULL) { - SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); - *error = ENOMEM; + SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS); + *error = ENOBUFS; } else { *sndout = m_length(m, NULL); *new_tail = m_last(m); @@ -12545,8 +12725,8 @@ sctp_copy_resume(struct uio *uio, m = m_uiotombuf(uio, M_WAITOK, max_send_len, 0, (M_PKTHDR | (user_marks_eor ? M_EOR : 0))); if (m == NULL) { - SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); - *error = ENOMEM; + SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS); + *error = ENOBUFS; } else { *sndout = m_length(m, NULL); *new_tail = m_last(m); @@ -12558,18 +12738,18 @@ sctp_copy_resume(struct uio *uio, #if defined(__APPLE__) #if defined(APPLE_LEOPARD) - left = min(uio->uio_resid, max_send_len); + left = min(uio->uio_resid, max_send_len); #else - left = min(uio_resid(uio), max_send_len); + left = min(uio_resid(uio), max_send_len); #endif #else - left = min(uio->uio_resid, max_send_len); + left = min(uio->uio_resid, max_send_len); #endif /* Always get a header just in case */ head = sctp_get_mbuf_for_msg(left, 0, M_WAITOK, 0, MT_DATA); if (head == NULL) { - SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); - *error = ENOMEM; + SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS); + *error = ENOBUFS; return (NULL); } cancpy = M_TRAILINGSPACE(head); @@ -12590,8 +12770,8 @@ sctp_copy_resume(struct uio *uio, if (SCTP_BUF_NEXT(m) == NULL) { sctp_m_freem(head); *new_tail = NULL; - SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); - *error = ENOMEM; + SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS); + *error = ENOBUFS; return (NULL); } m = SCTP_BUF_NEXT(m); @@ -12619,17 +12799,17 @@ sctp_copy_resume(struct uio *uio, static int sctp_copy_one(struct sctp_stream_queue_pending *sp, - struct uio *uio, - int resv_upfront) + struct uio *uio, + int resv_upfront) { int left; #if defined(__Panda__) left = sp->length; sp->data = m_uiotombuf(uio, M_WAITOK, sp->length, - resv_upfront, 0); + resv_upfront, 0); if (sp->data == NULL) { - SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); - return (ENOMEM); + SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS); + return (ENOBUFS); } sp->tail_mbuf = m_last(sp->data); @@ -12638,10 +12818,10 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp, #elif defined(__FreeBSD__) && __FreeBSD_version > 602000 left = sp->length; sp->data = m_uiotombuf(uio, M_WAITOK, sp->length, - resv_upfront, 0); + resv_upfront, 0); if (sp->data == NULL) { - SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); - return (ENOMEM); + SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS); + return (ENOBUFS); } sp->tail_mbuf = m_last(sp->data); @@ -12655,8 +12835,8 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp, left = sp->length; head = m = sctp_get_mbuf_for_msg((left + resv_upfront), 0, M_WAITOK, 0, MT_DATA); if (m == NULL) { - SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); - return (ENOMEM); + SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS); + return (ENOBUFS); } /*- * Add this one for m in now, that way if the alloc fails we won't @@ -12683,8 +12863,8 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp, * the rest */ sctp_m_freem(head); - SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); - return (ENOMEM); + SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS); + return (ENOBUFS); } m = SCTP_BUF_NEXT(m); cancpy = M_TRAILINGSPACE(m); diff --git a/netinet/sctp_pcb.c b/netinet/sctp_pcb.c index fcacdac..a7f8b85 100755 --- a/netinet/sctp_pcb.c +++ b/netinet/sctp_pcb.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 265455 2014-05-06 16:51:07Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 267674 2014-06-20 13:26:49Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -52,9 +52,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 265455 2014-05-06 16:51:07Z tuex #if defined(__FreeBSD__) && __FreeBSD_version >= 803000 #include <netinet/sctp_dtrace_define.h> #endif +#if defined INET || defined INET6 #if !defined(__Userspace_os_Windows) #include <netinet/udp.h> #endif +#endif #ifdef INET6 #if defined(__Userspace__) #include "user_ip6_var.h" @@ -992,6 +994,12 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { continue; } +#if defined(__FreeBSD__) + if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } +#endif if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) { SCTP_IPI_ADDR_RUNLOCK(); return (1); @@ -1008,6 +1016,12 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) #endif sin6 = &sctp_ifa->address.sin6; rsin6 = (struct sockaddr_in6 *)to; +#if defined(__FreeBSD__) + if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } +#endif if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (local_scope == 0) continue; @@ -1207,6 +1221,41 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from, SCTP_INP_RUNLOCK(inp); continue; } +#if defined(__FreeBSD__) + switch (to->sa_family) { +#ifdef INET + case AF_INET: + { + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)to; + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + SCTP_INP_RUNLOCK(inp); + continue; + } + break; + } +#endif +#ifdef INET6 + case AF_INET6: + { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)to; + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + SCTP_INP_RUNLOCK(inp); + continue; + } + break; + } +#endif + default: + SCTP_INP_RUNLOCK(inp); + continue; + } +#endif #ifdef SCTP_MVRF fnd = 0; for (i = 0; i < inp->num_vrfs; i++) { @@ -1907,23 +1956,43 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head, if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) && (inp->sctp_lport == lport)) { /* got it */ + switch (nam->sa_family) { #ifdef INET - if ((nam->sa_family == AF_INET) && - (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && - SCTP_IPV6_V6ONLY(inp)) { - /* IPv4 on a IPv6 socket with ONLY IPv6 set */ - SCTP_INP_RUNLOCK(inp); - continue; - } + case AF_INET: + if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && + SCTP_IPV6_V6ONLY(inp)) { + /* IPv4 on a IPv6 socket with ONLY IPv6 set */ + SCTP_INP_RUNLOCK(inp); + continue; + } +#if defined(__FreeBSD__) + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + SCTP_INP_RUNLOCK(inp); + continue; + } +#endif + break; #endif #ifdef INET6 - /* A V6 address and the endpoint is NOT bound V6 */ - if (nam->sa_family == AF_INET6 && - (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { - SCTP_INP_RUNLOCK(inp); - continue; - } + case AF_INET6: + /* A V6 address and the endpoint is NOT bound V6 */ + if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { + SCTP_INP_RUNLOCK(inp); + continue; + } +#if defined(__FreeBSD__) + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + SCTP_INP_RUNLOCK(inp); + continue; + } #endif + break; +#endif + default: + break; + } /* does a VRF id match? */ fnd = 0; #ifdef SCTP_MVRF @@ -2753,6 +2822,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) /* setup socket pointers */ inp->sctp_socket = so; inp->ip_inp.inp.inp_socket = so; +#if defined(__FreeBSD__) + inp->ip_inp.inp.inp_cred = crhold(so->so_cred); +#endif #ifdef INET6 #if !defined(__Userspace__) && !defined(__Windows__) if (INP_SOCKAF(so) == AF_INET6) { @@ -2779,6 +2851,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) /* init the small hash table we use to track asocid <-> tcb */ inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark); if (inp->sctp_asocidhash == NULL) { +#if defined(__FreeBSD__) + crfree(inp->ip_inp.inp.inp_cred); +#endif SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); SCTP_INP_INFO_WUNLOCK(); return (ENOBUFS); @@ -2798,6 +2873,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) error = 0; #endif if (error != 0) { +#if defined(__FreeBSD__) + crfree(inp->ip_inp.inp.inp_cred); +#endif SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); SCTP_INP_INFO_WUNLOCK(); return error; @@ -2843,6 +2921,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) */ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EOPNOTSUPP); so->so_pcb = NULL; +#if defined(__FreeBSD__) + crfree(inp->ip_inp.inp.inp_cred); +#endif SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); return (EOPNOTSUPP); } @@ -2862,6 +2943,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) SCTP_PRINTF("Out of SCTP-INPCB->hashinit - no resources\n"); SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS); so->so_pcb = NULL; +#if defined(__FreeBSD__) + crfree(inp->ip_inp.inp.inp_cred); +#endif SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); return (ENOBUFS); } @@ -2873,6 +2957,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS); so->so_pcb = NULL; SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark); +#if defined(__FreeBSD__) + crfree(inp->ip_inp.inp.inp_cred); +#endif SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); return (ENOBUFS); } @@ -2891,6 +2978,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) #endif SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark); so->so_pcb = NULL; +#if defined(__FreeBSD__) + crfree(inp->ip_inp.inp.inp_cred); +#endif SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); SCTP_UNLOCK_EXC(SCTP_BASE_INFO(sctbinfo).ipi_lock); SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM); @@ -4265,6 +4355,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) } /* Now we must put the ep memory back into the zone pool */ #if defined(__FreeBSD__) + crfree(inp->ip_inp.inp.inp_cred); INP_LOCK_DESTROY(&inp->ip_inp.inp); #endif SCTP_INP_LOCK_DESTROY(inp); @@ -4629,9 +4720,11 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, break; } } +#if defined INET || defined INET6 if (net->port) { net->mtu -= (uint32_t)sizeof(struct udphdr); } +#endif if (from == SCTP_ALLOC_ASOC) { stcb->asoc.smallest_mtu = net->mtu; } diff --git a/netinet/sctp_sysctl.c b/netinet/sctp_sysctl.c index 1374dba..21329f0 100755 --- a/netinet/sctp_sysctl.c +++ b/netinet/sctp_sysctl.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 263237 2014-03-16 12:32:16Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 267674 2014-06-20 13:26:49Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -307,6 +307,12 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s sin = (struct sockaddr_in *)&sctp_ifa->address.sa; if (sin->sin_addr.s_addr == 0) continue; +#if defined(__FreeBSD__) + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } +#endif if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) continue; } else { @@ -325,6 +331,12 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa; if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) continue; +#if defined(__FreeBSD__) + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } +#endif if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (local_scope == 0) continue; diff --git a/netinet/sctp_timer.c b/netinet/sctp_timer.c index 0ad6de0..9627dc5 100755 --- a/netinet/sctp_timer.c +++ b/netinet/sctp_timer.c @@ -54,9 +54,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 263237 2014-03-16 12:32:16Z tu #include <netinet/sctp_input.h> #include <netinet/sctp.h> #include <netinet/sctp_uio.h> +#if defined INET || defined INET6 #if !defined(__Userspace_os_Windows) #include <netinet/udp.h> #endif +#endif #if defined(__APPLE__) #define APPLE_FILE_NO 6 @@ -1502,9 +1504,11 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp, } if (net->ro._s_addr) { mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_rt); +#if defined INET || defined INET6 if (net->port) { mtu -= sizeof(struct udphdr); } +#endif if (mtu > next_mtu) { net->mtu = next_mtu; } diff --git a/netinet/sctp_userspace.c b/netinet/sctp_userspace.c index e0cbac4..7763f30 100755 --- a/netinet/sctp_userspace.c +++ b/netinet/sctp_userspace.c @@ -141,7 +141,7 @@ Win_getifaddrs(struct ifaddrs** interfaces) ifa->ifa_name = strdup(pAdapt->AdapterName); ifa->ifa_flags = pAdapt->Flags; ifa->ifa_addr = (struct sockaddr *)addr; - memcpy(&addr, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in)); + memcpy(addr, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in)); interfaces[count] = ifa; } #endif @@ -175,7 +175,7 @@ Win_getifaddrs(struct ifaddrs** interfaces) ifa->ifa_name = strdup(pAdapt->AdapterName); ifa->ifa_flags = pAdapt->Flags; ifa->ifa_addr = (struct sockaddr *)addr6; - memcpy(&addr6, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in6)); + memcpy(addr6, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in6)); interfaces[count] = ifa; } } diff --git a/netinet/sctp_usrreq.c b/netinet/sctp_usrreq.c index a3b9641..796fd16 100755 --- a/netinet/sctp_usrreq.c +++ b/netinet/sctp_usrreq.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 263237 2014-03-16 12:32:16Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 267688 2014-06-20 20:17:39Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -56,7 +56,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 263237 2014-03-16 12:32:16Z t #include <netinet/sctp_timer.h> #include <netinet/sctp_auth.h> #include <netinet/sctp_bsd_addr.h> -#if !defined(__Userspace_os_Windows) +#if !defined(__Userspace__) #include <netinet/udp.h> #endif @@ -393,8 +393,6 @@ sctp_notify_mbuf(struct sctp_inpcb *inp, SCTP_TCB_UNLOCK(stcb); } -#endif -#endif void sctp_notify(struct sctp_inpcb *inp, @@ -489,6 +487,8 @@ sctp_notify(struct sctp_inpcb *inp, SCTP_TCB_UNLOCK(stcb); } } +#endif +#endif #ifdef INET #if !defined(__Panda__) && !defined(__Userspace__) @@ -1684,6 +1684,12 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, */ continue; } +#if defined(__FreeBSD__) + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } +#endif if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { continue; @@ -1727,6 +1733,12 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, */ continue; } +#if defined(__FreeBSD__) + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } +#endif if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (local_scope == 0) continue; @@ -6096,6 +6108,45 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, error = EINVAL; goto out_of_it; } +#if defined(__FreeBSD__) + } else { + switch (sspp->sspp_addr.ss_family) { +#ifdef INET + case AF_INET: + { + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)&sspp->sspp_addr; + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + goto out_of_it; + } + break; + } +#endif +#ifdef INET6 + case AF_INET6: + { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)&sspp->sspp_addr; + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + goto out_of_it; + } + break; + } +#endif + default: + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + goto out_of_it; + } +#endif } if (sctp_set_primary_ip_address_sa(stcb, (struct sockaddr *)&sspp->sspp_addr) != 0) { @@ -6477,7 +6528,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id); net = NULL; if (stcb) { - net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_assoc_id); + net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_address); } else { /* We increment here since sctp_findassociation_ep_addr() wil * do a decrement if it finds the stcb as long as the locked @@ -6485,7 +6536,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, */ SCTP_INP_INCR_REF(inp); stcb = sctp_findassociation_ep_addr(&inp, - (struct sockaddr *)&thlds->spt_assoc_id, + (struct sockaddr *)&thlds->spt_address, &net, NULL, NULL); if (stcb == NULL) { SCTP_INP_DECR_REF(inp); @@ -6494,7 +6545,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, if (stcb && (net == NULL)) { struct sockaddr *sa; - sa = (struct sockaddr *)&thlds->spt_assoc_id; + sa = (struct sockaddr *)&thlds->spt_address; #ifdef INET if (sa->sa_family == AF_INET) { @@ -7197,35 +7248,34 @@ sctp_listen(struct socket *so, struct proc *p) if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) { /* See if we have a listener */ struct sctp_inpcb *tinp; - union sctp_sockstore store, *sp; + union sctp_sockstore store; - sp = &store; if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { /* not bound all */ struct sctp_laddr *laddr; LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { memcpy(&store, &laddr->ifa->address, sizeof(store)); - switch (sp->sa.sa_family) { + switch (store.sa.sa_family) { #ifdef INET case AF_INET: - sp->sin.sin_port = inp->sctp_lport; + store.sin.sin_port = inp->sctp_lport; break; #endif #ifdef INET6 case AF_INET6: - sp->sin6.sin6_port = inp->sctp_lport; + store.sin6.sin6_port = inp->sctp_lport; break; #endif #if defined(__Userspace__) case AF_CONN: - sp->sconn.sconn_port = inp->sctp_lport; + store.sconn.sconn_port = inp->sctp_lport; break; #endif default: break; } - tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id); + tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id); if (tinp && (tinp != inp) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && @@ -7240,25 +7290,6 @@ sctp_listen(struct socket *so, struct proc *p) } else { /* Setup a local addr bound all */ memset(&store, 0, sizeof(store)); - switch (sp->sa.sa_family) { -#ifdef INET - case AF_INET: - store.sin.sin_port = inp->sctp_lport; - break; -#endif -#ifdef INET6 - case AF_INET6: - sp->sin6.sin6_port = inp->sctp_lport; - break; -#endif -#if defined(__Userspace__) - case AF_CONN: - sp->sconn.sconn_port = inp->sctp_lport; - break; -#endif - default: - break; - } #ifdef INET6 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { store.sa.sa_family = AF_INET6; @@ -7267,15 +7298,47 @@ sctp_listen(struct socket *so, struct proc *p) #endif } #endif +#if defined(__Userspace__) + if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) { + store.sa.sa_family = AF_CONN; +#ifdef HAVE_SA_LEN + store.sa.sa_len = sizeof(struct sockaddr_conn); +#endif + } +#endif #ifdef INET +#if defined(__Userspace__) + if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && + ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) == 0)) { +#else if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { +#endif store.sa.sa_family = AF_INET; #ifdef HAVE_SA_LEN store.sa.sa_len = sizeof(struct sockaddr_in); #endif } #endif - tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id); + switch (store.sa.sa_family) { +#ifdef INET + case AF_INET: + store.sin.sin_port = inp->sctp_lport; + break; +#endif +#ifdef INET6 + case AF_INET6: + store.sin6.sin6_port = inp->sctp_lport; + break; +#endif +#if defined(__Userspace__) + case AF_CONN: + store.sconn.sconn_port = inp->sctp_lport; + break; +#endif + default: + break; + } + tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id); if (tinp && (tinp != inp) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && diff --git a/netinet/sctputil.c b/netinet/sctputil.c index 38cbcf7..73cf3ab 100755 --- a/netinet/sctputil.c +++ b/netinet/sctputil.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 264701 2014-04-20 18:15:23Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 267674 2014-06-20 13:26:49Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -7566,6 +7566,12 @@ sctp_local_addr_count(struct sctp_tcb *stcb) /* skip unspecified addrs */ continue; } +#if defined(__FreeBSD__) + if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } +#endif if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { continue; @@ -7589,6 +7595,12 @@ sctp_local_addr_count(struct sctp_tcb *stcb) if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { continue; } +#if defined(__FreeBSD__) + if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } +#endif if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (local_scope == 0) continue; diff --git a/user_malloc.h b/user_malloc.h index 07187ee..4ea9548 100755 --- a/user_malloc.h +++ b/user_malloc.h @@ -41,7 +41,15 @@ #include <strings.h> #include <stdint.h> #else -#include "netinet/sctp_os_userspace.h" +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include <stdint.h> +#elif defined(SCTP_STDINT_INCLUDE) +#include SCTP_STDINT_INCLUDE +#else +#define uint32_t unsigned __int32 +#define uint64_t unsigned __int64 +#endif +#include <winsock2.h> #endif #define MINALLOCSIZE UMA_SMALLEST_UNIT diff --git a/user_socket.c b/user_socket.c index adb798c..1b44f11 100755 --- a/user_socket.c +++ b/user_socket.c @@ -46,7 +46,9 @@ #define __FAVOR_BSD /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */ #endif #if !defined (__Userspace_os_Windows) +#if defined INET || defined INET6 #include <netinet/udp.h> +#endif #include <arpa/inet.h> #else #include <user_socketvar.h> @@ -35,6 +35,7 @@ extern "C" { #endif +#include <errno.h> #include <sys/types.h> #ifdef _WIN32 #ifdef _MSC_VER |