diff options
| author | Keith M Wesolowski <wesolows@foobazco.org> | 2014-03-05 16:14:42 +0000 |
|---|---|---|
| committer | Keith M Wesolowski <wesolows@foobazco.org> | 2014-03-05 16:14:42 +0000 |
| commit | 2d02bb4655a4bcc0b7f2e0b0e661270f13d0f8a3 (patch) | |
| tree | 93668f0237e432973b0c0d568ce4c24afbe505ad /usr/src/uts/common/inet/udp/udp.c | |
| parent | a16c14a26a4c72468482a0026ecaabafeb24fff9 (diff) | |
| parent | a1ca8b43681e3163e9f085ab65b8b6de1848d8ac (diff) | |
| download | illumos-joyent-2d02bb4655a4bcc0b7f2e0b0e661270f13d0f8a3.tar.gz | |
[illumos-gate merge]
commit a1ca8b43681e3163e9f085ab65b8b6de1848d8ac
4596 Callers of ip_srcid_find_id() need to be more careful
commit 7298ed33f6dda314aee9fee22d0dccfb09cc0ef6
4314 mountd(1m): Options are not related to Solaris
Diffstat (limited to 'usr/src/uts/common/inet/udp/udp.c')
| -rw-r--r-- | usr/src/uts/common/inet/udp/udp.c | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c index e6dfd3efe9..4a6e835b67 100644 --- a/usr/src/uts/common/inet/udp/udp.c +++ b/usr/src/uts/common/inet/udp/udp.c @@ -21,6 +21,7 @@ /* * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -2714,6 +2715,8 @@ udp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp, ixa->ixa_flags &= ~IXAF_SCOPEID_SET; ixa->ixa_flags |= IXAF_IS_IPV4; } else if (sin6 != NULL) { + boolean_t v4mapped; + v6dst = sin6->sin6_addr; dstport = sin6->sin6_port; flowinfo = sin6->sin6_flowinfo; @@ -2724,14 +2727,20 @@ udp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp, } else { ixa->ixa_flags &= ~IXAF_SCOPEID_SET; } - if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) { - ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp), - connp->conn_netstack); - } - if (IN6_IS_ADDR_V4MAPPED(&v6dst)) + v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst); + if (v4mapped) ixa->ixa_flags |= IXAF_IS_IPV4; else ixa->ixa_flags &= ~IXAF_IS_IPV4; + if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) { + if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp), + v4mapped, connp->conn_netstack)) { + /* Mismatch - v4mapped/v6 specified by srcid. */ + mutex_exit(&connp->conn_lock); + error = EADDRNOTAVAIL; + goto failed; /* Does freemsg() and mib. */ + } + } } else { /* Connected case */ v6dst = connp->conn_faddr_v6; @@ -3722,14 +3731,13 @@ udp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin, sin6_t *sin6, IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst); dstport = sin->sin_port; flowinfo = 0; + /* Don't bother with ip_srcid_find_id(), but indicate anyway. */ srcid = 0; ixa->ixa_flags &= ~IXAF_SCOPEID_SET; - if (srcid != 0 && V4_PART_OF_V6(&v6src) == INADDR_ANY) { - ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp), - connp->conn_netstack); - } ixa->ixa_flags |= IXAF_IS_IPV4; } else { + boolean_t v4mapped; + v6dst = sin6->sin6_addr; dstport = sin6->sin6_port; flowinfo = sin6->sin6_flowinfo; @@ -3740,14 +3748,20 @@ udp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin, sin6_t *sin6, } else { ixa->ixa_flags &= ~IXAF_SCOPEID_SET; } - if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) { - ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp), - connp->conn_netstack); - } - if (IN6_IS_ADDR_V4MAPPED(&v6dst)) + v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst); + if (v4mapped) ixa->ixa_flags |= IXAF_IS_IPV4; else ixa->ixa_flags &= ~IXAF_IS_IPV4; + if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) { + if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp), + v4mapped, connp->conn_netstack)) { + /* Mismatched v4mapped/v6 specified by srcid. */ + mutex_exit(&connp->conn_lock); + error = EADDRNOTAVAIL; + goto ud_error; + } + } } /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */ if (connp->conn_xmit_ipp.ipp_fields & IPPF_ADDR) { @@ -5526,6 +5540,7 @@ udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len, uint_t scopeid = 0; uint_t srcid = 0; in6_addr_t v6src = connp->conn_saddr_v6; + boolean_t v4mapped; udp = connp->conn_udp; us = udp->udp_us; @@ -5554,11 +5569,15 @@ udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len, v6dst = sin6->sin6_addr; dstport = sin6->sin6_port; srcid = sin6->__sin6_src_id; + v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst); if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) { - ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp), - connp->conn_netstack); + if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp), + v4mapped, connp->conn_netstack)) { + /* Mismatch v4mapped/v6 specified by srcid. */ + return (EADDRNOTAVAIL); + } } - if (IN6_IS_ADDR_V4MAPPED(&v6dst)) { + if (v4mapped) { if (connp->conn_ipv6_v6only) return (EADDRNOTAVAIL); |
