Print this page
4596 Callers of ip_srcid_find_id() need to be more careful
@@ -19,10 +19,11 @@
* 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,10 +2713,12 @@
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,18 +2725,24 @@
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))
+ 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,18 +3729,17 @@
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;
- 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;
srcid = sin6->__sin6_src_id;
if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
@@ -3738,19 +3746,25 @@
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))
+ 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,10 +5538,11 @@
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,15 +5567,19 @@
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)) {
- 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);
/*
* Destination adress is mapped IPv6 address.