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 (c) 2013 by Delphix. 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>
*** 766,778 **** flowinfo = sin6->sin6_flowinfo; if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) scopeid = sin6->sin6_scope_id; 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); } break; } /* * If there is a different thread using conn_ixa then we get a new --- 767,783 ---- flowinfo = sin6->sin6_flowinfo; if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) scopeid = sin6->sin6_scope_id; srcid = sin6->__sin6_src_id; if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) { ! /* Due to check above, we know sin6_addr is v6-only. */ ! if (!ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp), ! B_FALSE, connp->conn_netstack)) { ! /* Mismatch - v6src would be v4mapped. */ ! return (EADDRNOTAVAIL); } + } break; } /* * If there is a different thread using conn_ixa then we get a new
*** 3335,3345 **** in6_addr_t v6src; in6_addr_t v6dst; in6_addr_t v6nexthop; in_port_t dstport; uint32_t flowinfo; - uint_t srcid; int is_absreq_failure = 0; conn_opt_arg_t coas, *coa; ASSERT(tudr_mp != NULL || msg != NULL); --- 3340,3349 ----
*** 3438,3447 **** --- 3442,3454 ---- 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; + uint_t srcid; + 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) {
*** 3448,3465 **** 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; flowinfo = connp->conn_flowinfo; } --- 3455,3478 ---- 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 failed; /* Does freemsg() and mib. */ + } + } } else { /* Connected case */ v6dst = connp->conn_faddr_v6; flowinfo = connp->conn_flowinfo; }
*** 4417,4434 **** 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) { --- 4430,4446 ---- 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) {
*** 4435,4453 **** 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) { --- 4447,4471 ---- 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) {