Print this page
4596 Callers of ip_srcid_find_id() need to be more careful

*** 19,28 **** --- 19,29 ---- * CDDL HEADER END */ /* * 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. */ #include <sys/types.h> #include <sys/stream.h>
*** 2712,2721 **** --- 2713,2724 ---- dstport = sin->sin_port; flowinfo = 0; 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; srcid = sin6->__sin6_src_id; if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
*** 2722,2739 **** ixa->ixa_scopeid = sin6->sin6_scope_id; ixa->ixa_flags |= IXAF_SCOPEID_SET; } 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)) ixa->ixa_flags |= IXAF_IS_IPV4; else ixa->ixa_flags &= ~IXAF_IS_IPV4; } else { /* Connected case */ v6dst = connp->conn_faddr_v6; dstport = connp->conn_fport; flowinfo = connp->conn_flowinfo; --- 2725,2748 ---- ixa->ixa_scopeid = sin6->sin6_scope_id; ixa->ixa_flags |= IXAF_SCOPEID_SET; } else { ixa->ixa_flags &= ~IXAF_SCOPEID_SET; } ! 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; dstport = connp->conn_fport; flowinfo = connp->conn_flowinfo;
*** 3720,3737 **** v6src = connp->conn_saddr_v6; if (sin != NULL) { IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst); dstport = sin->sin_port; flowinfo = 0; 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 { v6dst = sin6->sin6_addr; dstport = sin6->sin6_port; flowinfo = sin6->sin6_flowinfo; srcid = sin6->__sin6_src_id; if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) { --- 3729,3745 ---- v6src = connp->conn_saddr_v6; if (sin != NULL) { 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; ixa->ixa_flags |= IXAF_IS_IPV4; } else { + boolean_t v4mapped; + v6dst = sin6->sin6_addr; dstport = sin6->sin6_port; flowinfo = sin6->sin6_flowinfo; srcid = sin6->__sin6_src_id; if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
*** 3738,3756 **** ixa->ixa_scopeid = sin6->sin6_scope_id; ixa->ixa_flags |= IXAF_SCOPEID_SET; } 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)) ixa->ixa_flags |= IXAF_IS_IPV4; else ixa->ixa_flags &= ~IXAF_IS_IPV4; } /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */ if (connp->conn_xmit_ipp.ipp_fields & IPPF_ADDR) { ip_pkt_t *ipp = &connp->conn_xmit_ipp; if (ixa->ixa_flags & IXAF_IS_IPV4) { --- 3746,3770 ---- ixa->ixa_scopeid = sin6->sin6_scope_id; ixa->ixa_flags |= IXAF_SCOPEID_SET; } else { ixa->ixa_flags &= ~IXAF_SCOPEID_SET; } ! 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) { ip_pkt_t *ipp = &connp->conn_xmit_ipp; if (ixa->ixa_flags & IXAF_IS_IPV4) {
*** 5524,5533 **** --- 5538,5548 ---- ip_xmit_attr_t *ixa; ip_xmit_attr_t *oldixa; 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; /*
*** 5552,5566 **** case sizeof (sin6_t): sin6 = (sin6_t *)sa; v6dst = sin6->sin6_addr; dstport = sin6->sin6_port; srcid = sin6->__sin6_src_id; 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)) { if (connp->conn_ipv6_v6only) return (EADDRNOTAVAIL); /* * Destination adress is mapped IPv6 address. --- 5567,5585 ---- case sizeof (sin6_t): sin6 = (sin6_t *)sa; 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)) { ! if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp), ! v4mapped, connp->conn_netstack)) { ! /* Mismatch v4mapped/v6 specified by srcid. */ ! return (EADDRNOTAVAIL); } ! } ! if (v4mapped) { if (connp->conn_ipv6_v6only) return (EADDRNOTAVAIL); /* * Destination adress is mapped IPv6 address.