summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Nordmark <Erik.Nordmark@Sun.COM>2010-02-17 19:52:19 -0800
committerErik Nordmark <Erik.Nordmark@Sun.COM>2010-02-17 19:52:19 -0800
commit76a1033e5eab8f829e5080c3397bf826f6dd382c (patch)
treeba166dbaf43567f180d7260459c258d5718a271d
parent707da956f10b527c61331142582204e292b21bd6 (diff)
downloadillumos-gate-76a1033e5eab8f829e5080c3397bf826f6dd382c.tar.gz
6923355 tcp leaves conn_ixa->ixa_cred unitialized causing confusion
-rw-r--r--usr/src/uts/common/inet/ip/icmp.c42
-rw-r--r--usr/src/uts/common/inet/ip/ip.c1
-rw-r--r--usr/src/uts/common/inet/ip/ip_attr.c6
-rw-r--r--usr/src/uts/common/inet/ip/ipclassifier.c3
-rw-r--r--usr/src/uts/common/inet/tcp/tcp.c6
-rw-r--r--usr/src/uts/common/inet/udp/udp.c32
6 files changed, 81 insertions, 9 deletions
diff --git a/usr/src/uts/common/inet/ip/icmp.c b/usr/src/uts/common/inet/ip/icmp.c
index a070f1de35..0df82f2a53 100644
--- a/usr/src/uts/common/inet/ip/icmp.c
+++ b/usr/src/uts/common/inet/ip/icmp.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1990 Mentat Inc. */
@@ -800,6 +800,15 @@ rawip_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
connp->conn_flowinfo = flowinfo;
}
+ /*
+ * We update our cred/cpid based on the caller of connect
+ */
+ if (connp->conn_cred != cr) {
+ crhold(cr);
+ crfree(connp->conn_cred);
+ connp->conn_cred = cr;
+ }
+ connp->conn_cpid = pid;
ixa->ixa_cred = cr;
ixa->ixa_cpid = pid;
if (is_system_labeled()) {
@@ -3050,6 +3059,8 @@ icmp_output_hdrincl(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid)
/* Get a copy of conn_xmit_ipp since the TX label might change it */
ipp = kmem_zalloc(sizeof (*ipp), KM_NOSLEEP);
if (ipp == NULL) {
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
BUMP_MIB(&is->is_rawip_mib, rawipOutErrors);
freemsg(mp);
@@ -3273,6 +3284,8 @@ icmp_output_hdrincl(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid)
break;
}
done:
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
ip_pkt_free(ipp);
kmem_free(ipp, sizeof (*ipp));
@@ -3352,6 +3365,8 @@ icmp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp,
/* Get a copy of conn_xmit_ipp since the options might change it */
ipp = kmem_zalloc(sizeof (*ipp), KM_NOSLEEP);
if (ipp == NULL) {
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
BUMP_MIB(&is->is_rawip_mib, rawipOutErrors);
freemsg(mp);
@@ -3582,6 +3597,8 @@ icmp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp,
break;
}
done:
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
ip_pkt_free(ipp);
kmem_free(ipp, sizeof (*ipp));
@@ -3633,6 +3650,8 @@ icmp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid)
if (mp == NULL) {
ASSERT(error != 0);
mutex_exit(&connp->conn_lock);
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
BUMP_MIB(&is->is_rawip_mib, rawipOutErrors);
freemsg(mp);
@@ -3645,6 +3664,8 @@ icmp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid)
if (mp == NULL) {
mutex_exit(&connp->conn_lock);
BUMP_MIB(&is->is_rawip_mib, rawipOutErrors);
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
return (EHOSTUNREACH); /* IPsec policy failure */
}
@@ -3699,6 +3720,8 @@ icmp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid)
/* FALLTHRU */
default:
failed:
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
BUMP_MIB(&is->is_rawip_mib, rawipOutErrors);
freemsg(mp);
@@ -3729,6 +3752,8 @@ icmp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid)
error = ENETUNREACH;
break;
}
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
return (error);
}
@@ -3772,6 +3797,8 @@ icmp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid,
if (mp == NULL) {
ASSERT(error != 0);
mutex_exit(&connp->conn_lock);
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
BUMP_MIB(&is->is_rawip_mib, rawipOutErrors);
freemsg(mp);
@@ -3784,6 +3811,8 @@ icmp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid,
if (mp == NULL) {
mutex_exit(&connp->conn_lock);
BUMP_MIB(&is->is_rawip_mib, rawipOutErrors);
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
return (EHOSTUNREACH); /* IPsec policy failure */
}
@@ -3838,6 +3867,8 @@ icmp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid,
/* FALLTHRU */
default:
failed:
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
BUMP_MIB(&is->is_rawip_mib, rawipOutErrors);
freemsg(mp);
@@ -3880,6 +3911,8 @@ icmp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid,
mutex_exit(&connp->conn_lock);
break;
}
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
return (error);
}
@@ -4595,12 +4628,15 @@ icmp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin, sin6_t *sin6,
break;
}
done:
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
return (error);
ud_error:
- if (ixa != NULL)
- ixa_refrele(ixa);
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
+ ixa_refrele(ixa);
BUMP_MIB(&is->is_rawip_mib, rawipOutErrors);
freemsg(data_mp);
diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c
index 8924e40669..26547e6304 100644
--- a/usr/src/uts/common/inet/ip/ip.c
+++ b/usr/src/uts/common/inet/ip/ip.c
@@ -6162,6 +6162,7 @@ ip_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp,
* connp->conn_cred is crfree()ed in ipcl_conn_destroy()
*/
connp->conn_cred = credp;
+ connp->conn_cpid = curproc->p_pid;
/* Cache things in ixa without an extra refhold */
connp->conn_ixa->ixa_cred = connp->conn_cred;
connp->conn_ixa->ixa_cpid = connp->conn_cpid;
diff --git a/usr/src/uts/common/inet/ip/ip_attr.c b/usr/src/uts/common/inet/ip/ip_attr.c
index a46a82c85f..c3a55e19bc 100644
--- a/usr/src/uts/common/inet/ip/ip_attr.c
+++ b/usr/src/uts/common/inet/ip/ip_attr.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1990 Mentat Inc. */
@@ -1073,15 +1073,15 @@ ixa_cleanup(ip_xmit_attr_t *ixa)
if (ixa->ixa_free_flags & IXA_FREE_TSL) {
ASSERT(ixa->ixa_tsl != NULL);
label_rele(ixa->ixa_tsl);
- ixa->ixa_tsl = NULL;
ixa->ixa_free_flags &= ~IXA_FREE_TSL;
}
+ ixa->ixa_tsl = NULL;
if (ixa->ixa_free_flags & IXA_FREE_CRED) {
ASSERT(ixa->ixa_cred != NULL);
crfree(ixa->ixa_cred);
- ixa->ixa_cred = NULL;
ixa->ixa_free_flags &= ~IXA_FREE_CRED;
}
+ ixa->ixa_cred = NULL;
ixa->ixa_src_preferences = 0;
ixa->ixa_ifindex = 0;
ixa->ixa_multicast_ifindex = 0;
diff --git a/usr/src/uts/common/inet/ip/ipclassifier.c b/usr/src/uts/common/inet/ip/ipclassifier.c
index fe15feaff8..3cd30ba4ca 100644
--- a/usr/src/uts/common/inet/ip/ipclassifier.c
+++ b/usr/src/uts/common/inet/ip/ipclassifier.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -641,6 +641,7 @@ ipcl_conn_destroy(conn_t *connp)
if (connp->conn_cred != NULL) {
crfree(connp->conn_cred);
connp->conn_cred = NULL;
+ /* ixa_cred done in ipcl_conn_cleanup below */
}
if (connp->conn_ht_iphc != NULL) {
diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c
index 165614e8f9..1b43c16b72 100644
--- a/usr/src/uts/common/inet/tcp/tcp.c
+++ b/usr/src/uts/common/inet/tcp/tcp.c
@@ -2412,6 +2412,7 @@ tcp_accept_swap(tcp_t *listener, tcp_t *acceptor, tcp_t *eager)
if (econnp->conn_cred != NULL)
crfree(econnp->conn_cred);
econnp->conn_cred = aconnp->conn_cred;
+ econnp->conn_ixa->ixa_cred = econnp->conn_cred;
aconnp->conn_cred = NULL;
econnp->conn_cpid = aconnp->conn_cpid;
ASSERT(econnp->conn_netstack == aconnp->conn_netstack);
@@ -6542,6 +6543,7 @@ tcp_reinit(tcp_t *tcp)
*/
tcp_reinit_values(tcp);
ipcl_hash_remove(connp);
+ /* Note that ixa_cred gets cleared in ixa_cleanup */
ixa_cleanup(connp->conn_ixa);
tcp_ipsec_cleanup(tcp);
@@ -7882,6 +7884,10 @@ tcp_create_common(cred_t *credp, boolean_t isv6, boolean_t issocket,
connp->conn_cpid = curproc->p_pid;
connp->conn_open_time = ddi_get_lbolt64();
+ /* Cache things in the ixa without any refhold */
+ connp->conn_ixa->ixa_cred = credp;
+ connp->conn_ixa->ixa_cpid = connp->conn_cpid;
+
connp->conn_zoneid = zoneid;
/* conn_allzones can not be set this early, hence no IPCL_ZONEID */
connp->conn_ixa->ixa_zoneid = zoneid;
diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c
index ff83382a1c..bd0599c115 100644
--- a/usr/src/uts/common/inet/udp/udp.c
+++ b/usr/src/uts/common/inet/udp/udp.c
@@ -3128,6 +3128,8 @@ udp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp,
/* Get a copy of conn_xmit_ipp since the options might change it */
ipp = kmem_zalloc(sizeof (*ipp), KM_NOSLEEP);
if (ipp == NULL) {
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
BUMP_MIB(&us->us_udp_mib, udpOutErrors);
freemsg(mp);
@@ -3357,6 +3359,8 @@ udp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp,
break;
}
done:
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
ip_pkt_free(ipp);
kmem_free(ipp, sizeof (*ipp));
@@ -3397,6 +3401,8 @@ udp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid)
if (mp == NULL) {
ASSERT(error != 0);
mutex_exit(&connp->conn_lock);
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
BUMP_MIB(&us->us_udp_mib, udpOutErrors);
freemsg(mp);
@@ -3452,6 +3458,8 @@ udp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid)
/* FALLTHRU */
default:
failed:
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
freemsg(mp);
BUMP_MIB(&us->us_udp_mib, udpOutErrors);
@@ -3483,6 +3491,8 @@ udp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid)
error = ENETUNREACH;
break;
}
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
return (error);
}
@@ -3514,6 +3524,8 @@ udp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid,
if (mp == NULL) {
ASSERT(error != 0);
mutex_exit(&connp->conn_lock);
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
BUMP_MIB(&us->us_udp_mib, udpOutErrors);
freemsg(mp);
@@ -3569,6 +3581,8 @@ udp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid,
/* FALLTHRU */
default:
failed:
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
freemsg(mp);
BUMP_MIB(&us->us_udp_mib, udpOutErrors);
@@ -3612,6 +3626,8 @@ udp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid,
mutex_exit(&connp->conn_lock);
break;
}
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
return (error);
}
@@ -4409,12 +4425,15 @@ udp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin, sin6_t *sin6,
mutex_exit(&connp->conn_lock);
break;
}
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
ixa_refrele(ixa);
return (error);
ud_error:
- if (ixa != NULL)
- ixa_refrele(ixa);
+ ixa->ixa_cred = connp->conn_cred; /* Restore */
+ ixa->ixa_cpid = connp->conn_cpid;
+ ixa_refrele(ixa);
freemsg(data_mp);
BUMP_MIB(&us->us_udp_mib, udpOutErrors);
@@ -6200,6 +6219,15 @@ udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
}
mutex_exit(&udpf->uf_lock);
+ /*
+ * We update our cred/cpid based on the caller of connect
+ */
+ if (connp->conn_cred != cr) {
+ crhold(cr);
+ crfree(connp->conn_cred);
+ connp->conn_cred = cr;
+ }
+ connp->conn_cpid = pid;
ixa->ixa_cred = cr;
ixa->ixa_cpid = pid;
if (is_system_labeled()) {