PSARC 2007/670 db_credp update
6619593 Simplify and strengthen db_credp handling
6619596 Add getpeerucred() support to SCTP SOCK_STREAM
diff --git a/usr/src/uts/common/fs/smbclnt/netsmb/smb_trantcp.c b/usr/src/uts/common/fs/smbclnt/netsmb/smb_trantcp.c
index 43b6805..d3036a7 100644
--- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_trantcp.c
+++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_trantcp.c
@@ -32,7 +32,7 @@
* $Id: smb_trantcp.c,v 1.39 2005/03/02 01:27:44 lindak Exp $
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -109,7 +109,7 @@
mlen = (sizeof (struct T_optmgmt_req) +
sizeof (struct opthdr) + sizeof (int));
- if (!(mp = allocb_wait(mlen, BPRI_LO, STR_NOSIG, &error)))
+ if (!(mp = allocb_cred_wait(mlen, STR_NOSIG, &error, CRED(), NOPID)))
return (error);
mp->b_datap->db_type = M_PROTO;
@@ -347,7 +347,7 @@
int error, fmode, mlen;
mlen = sizeof (struct T_discon_req);
- if (!(mp = allocb_wait(mlen, BPRI_LO, STR_NOSIG, &error)))
+ if (!(mp = allocb_cred_wait(mlen, STR_NOSIG, &error, CRED(), NOPID)))
return (error);
mp->b_datap->db_type = M_PROTO;
diff --git a/usr/src/uts/common/fs/sockfs/sockcommon.h b/usr/src/uts/common/fs/sockfs/sockcommon.h
index c4dbecb..ef903bb 100644
--- a/usr/src/uts/common/fs/sockfs/sockcommon.h
+++ b/usr/src/uts/common/fs/sockfs/sockcommon.h
@@ -20,15 +20,13 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SOCKCOMMON_H_
#define _SOCKCOMMON_H_
-#pragma ident "@(#)sockcommon.h 1.1 07/06/14 SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -185,7 +183,8 @@
rval_t *, int);
extern void so_enqueue_msg(struct sonode *, mblk_t *, size_t);
-extern mblk_t *socopyinuio(uio_t *, ssize_t, size_t, ssize_t, size_t, int *);
+extern mblk_t *socopyinuio(uio_t *, ssize_t, size_t, ssize_t, size_t, int *,
+ cred_t *);
extern mblk_t *socopyoutuio(mblk_t *, struct uio *, ssize_t, int *);
extern boolean_t somsghasdata(mblk_t *);
diff --git a/usr/src/uts/common/fs/sockfs/sockcommon_sops.c b/usr/src/uts/common/fs/sockfs/sockcommon_sops.c
index fb24093..5fd346b 100644
--- a/usr/src/uts/common/fs/sockfs/sockcommon_sops.c
+++ b/usr/src/uts/common/fs/sockfs/sockcommon_sops.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "@(#)sockcommon_sops.c 1.1 07/06/14 SMI"
-
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
@@ -273,7 +271,7 @@
bind_req.ADDR_length = namelen;
bind_req.ADDR_offset = (t_scalar_t)sizeof (bind_req);
mp = soallocproto2(&bind_req, sizeof (bind_req),
- name, namelen, 0, _ALLOC_SLEEP);
+ name, namelen, 0, _ALLOC_SLEEP, cr);
type = kssl_check_proxy(mp, so, &ent);
freemsg(mp);
@@ -472,7 +470,8 @@
so->so_proto_props.sopp_maxpsz,
so->so_proto_props.sopp_wroff,
so->so_proto_props.sopp_maxblk,
- so->so_proto_props.sopp_tail, &error)) == NULL) {
+ so->so_proto_props.sopp_tail, &error,
+ cr)) == NULL) {
break;
}
ASSERT(uiop->uio_resid >= 0);
diff --git a/usr/src/uts/common/fs/sockfs/sockcommon_subr.c b/usr/src/uts/common/fs/sockfs/sockcommon_subr.c
index 8988286..c8ff2be 100644
--- a/usr/src/uts/common/fs/sockfs/sockcommon_subr.c
+++ b/usr/src/uts/common/fs/sockfs/sockcommon_subr.c
@@ -468,7 +468,7 @@
/* Copy userdata into a new mblk_t */
mblk_t *
socopyinuio(uio_t *uiop, ssize_t iosize, size_t wroff, ssize_t maxblk,
- size_t tail_len, int *errorp)
+ size_t tail_len, int *errorp, cred_t *cr)
{
mblk_t *head = NULL, **tail = &head;
@@ -496,8 +496,12 @@
blocksize = MIN(iosize, maxblk);
ASSERT(blocksize >= 0);
- if ((mp = allocb(wroff + blocksize + tail_len,
- BPRI_MED)) == NULL) {
+ if (is_system_labeled())
+ mp = allocb_cred(wroff + blocksize + tail_len,
+ cr, curproc->p_pid);
+ else
+ mp = allocb(wroff + blocksize + tail_len, BPRI_MED);
+ if (mp == NULL) {
*errorp = ENOMEM;
return (head);
}
diff --git a/usr/src/uts/common/fs/sockfs/sockstr.c b/usr/src/uts/common/fs/sockfs/sockstr.c
index 71c8d4c..b05b60e 100644
--- a/usr/src/uts/common/fs/sockfs/sockstr.c
+++ b/usr/src/uts/common/fs/sockfs/sockstr.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -194,13 +194,25 @@
mblk_t *newmp;
size_t length;
cred_t *cr;
+ pid_t cpid;
+ int error; /* Dummy - error not returned */
/*
* Copy the message block because it is used
* elsewhere, too.
+ * Can't use copyb since we want to wait
+ * yet allow for EINTR.
*/
- length = MBLKL(mp);
- newmp = soallocproto(length, _ALLOC_INTR);
+ /* Round up size for reuse */
+ length = MAX(MBLKL(mp), 64);
+ cr = msg_getcred(mp, &cpid);
+ if (cr != NULL) {
+ newmp = allocb_cred_wait(length, 0,
+ &error, cr, cpid);
+ } else {
+ newmp = allocb_wait(length, 0, 0,
+ &error);
+ }
if (newmp == NULL) {
error = EINTR;
goto exit;
@@ -208,10 +220,6 @@
bcopy(mp->b_rptr, newmp->b_wptr, length);
newmp->b_wptr += length;
newmp->b_next = mp->b_next;
- cr = DB_CRED(mp);
- if (cr != NULL)
- mblk_setcred(newmp, cr);
- DB_CPID(newmp) = DB_CPID(mp);
/*
* Link the new message block into the queue
@@ -395,7 +403,7 @@
sotpi_info_t *sti = SOTOTPI(so);
/* Preallocate an unbind_req message */
- mp = soallocproto(sizeof (struct T_unbind_req), _ALLOC_SLEEP);
+ mp = soallocproto(sizeof (struct T_unbind_req), _ALLOC_SLEEP, CRED());
mutex_enter(&so->so_lock);
sti->sti_unbind_mp = mp;
#ifdef DEBUG
@@ -634,7 +642,7 @@
tir.PRIM_type = T_INFO_REQ;
mp = soallocproto1(&tir, sizeof (tir),
sizeof (struct T_info_req) + sizeof (struct T_info_ack),
- _ALLOC_INTR);
+ _ALLOC_INTR, CRED());
if (mp == NULL) {
eprintsoline(so, ENOBUFS);
return (ENOBUFS);
@@ -697,7 +705,7 @@
tcr.CAP_bits1 = cap_bits1;
mp = soallocproto1(&tcr, sizeof (tcr),
sizeof (struct T_capability_req) + sizeof (struct T_capability_ack),
- _ALLOC_INTR);
+ _ALLOC_INTR, CRED());
if (mp == NULL) {
eprintsoline(so, ENOBUFS);
return (ENOBUFS);
@@ -2264,8 +2272,7 @@
if (so->so_peercred != NULL)
crfree(so->so_peercred);
- so->so_peercred = DB_CRED(mp);
- so->so_cpid = DB_CPID(mp);
+ so->so_peercred = msg_getcred(mp, &so->so_cpid);
if (so->so_peercred != NULL)
crhold(so->so_peercred);
diff --git a/usr/src/uts/common/fs/sockfs/socksubr.c b/usr/src/uts/common/fs/sockfs/socksubr.c
index b82adb1..eee61f7 100644
--- a/usr/src/uts/common/fs/sockfs/socksubr.c
+++ b/usr/src/uts/common/fs/sockfs/socksubr.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1357,23 +1357,38 @@
* _ALLOC_SLEEP sleep forever. Don't return NULL.
*/
mblk_t *
-soallocproto(size_t size, int sleepflg)
+soallocproto(size_t size, int sleepflg, cred_t *cr)
{
mblk_t *mp;
/* Round up size for reuse */
size = MAX(size, 64);
- mp = allocb(size, BPRI_MED);
+ if (cr != NULL)
+ mp = allocb_cred(size, cr, curproc->p_pid);
+ else
+ mp = allocb(size, BPRI_MED);
+
if (mp == NULL) {
int error; /* Dummy - error not returned to caller */
switch (sleepflg) {
case _ALLOC_SLEEP:
- mp = allocb_wait(size, BPRI_MED, STR_NOSIG, &error);
+ if (cr != NULL) {
+ mp = allocb_cred_wait(size, STR_NOSIG, &error,
+ cr, curproc->p_pid);
+ } else {
+ mp = allocb_wait(size, BPRI_MED, STR_NOSIG,
+ &error);
+ }
ASSERT(mp);
break;
case _ALLOC_INTR:
- mp = allocb_wait(size, BPRI_MED, 0, &error);
+ if (cr != NULL) {
+ mp = allocb_cred_wait(size, 0, &error, cr,
+ curproc->p_pid);
+ } else {
+ mp = allocb_wait(size, BPRI_MED, 0, &error);
+ }
if (mp == NULL) {
/* Caught signal while sleeping for memory */
eprintline(ENOBUFS);
@@ -1398,7 +1413,8 @@
* This results in a bzero'ed chunk being placed the message.
*/
mblk_t *
-soallocproto1(const void *buf, ssize_t len, ssize_t size, int sleepflg)
+soallocproto1(const void *buf, ssize_t len, ssize_t size, int sleepflg,
+ cred_t *cr)
{
mblk_t *mp;
@@ -1408,7 +1424,7 @@
ASSERT(size >= len);
/* Round up size for reuse */
size = MAX(size, 64);
- mp = soallocproto(size, sleepflg);
+ mp = soallocproto(size, sleepflg, cr);
if (mp == NULL)
return (NULL);
mp->b_datap->db_type = M_PROTO;
@@ -1453,7 +1469,7 @@
*/
mblk_t *
soallocproto2(const void *buf1, ssize_t len1, const void *buf2, ssize_t len2,
- ssize_t size, int sleepflg)
+ ssize_t size, int sleepflg, cred_t *cr)
{
mblk_t *mp;
@@ -1461,7 +1477,7 @@
size = len1 + len2;
ASSERT(size >= len1 + len2);
- mp = soallocproto1(buf1, len1, size, sleepflg);
+ mp = soallocproto1(buf1, len1, size, sleepflg, cr);
if (mp)
soappendmsg(mp, buf2, len2);
return (mp);
@@ -1475,7 +1491,7 @@
*/
mblk_t *
soallocproto3(const void *buf1, ssize_t len1, const void *buf2, ssize_t len2,
- const void *buf3, ssize_t len3, ssize_t size, int sleepflg)
+ const void *buf3, ssize_t len3, ssize_t size, int sleepflg, cred_t *cr)
{
mblk_t *mp;
@@ -1483,7 +1499,7 @@
size = len1 + len2 +len3;
ASSERT(size >= len1 + len2 + len3);
- mp = soallocproto1(buf1, len1, size, sleepflg);
+ mp = soallocproto1(buf1, len1, size, sleepflg, cr);
if (mp != NULL) {
soappendmsg(mp, buf2, len2);
soappendmsg(mp, buf3, len3);
diff --git a/usr/src/uts/common/fs/sockfs/socksyscalls.c b/usr/src/uts/common/fs/sockfs/socksyscalls.c
index 4d0929f..b708469 100644
--- a/usr/src/uts/common/fs/sockfs/socksyscalls.c
+++ b/usr/src/uts/common/fs/sockfs/socksyscalls.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1945,7 +1945,13 @@
SOTOTPI(so)->sti_kssl_ctx != NULL)
iosize = (int)MIN(iosize, maxblk);
- if ((mp = allocb(iosize + extra, BPRI_MED)) == NULL) {
+ if (is_system_labeled()) {
+ mp = allocb_cred(iosize + extra, CRED(),
+ curproc->p_pid);
+ } else {
+ mp = allocb(iosize + extra, BPRI_MED);
+ }
+ if (mp == NULL) {
error = EAGAIN;
break;
}
@@ -2400,7 +2406,13 @@
SOTOTPI(so)->sti_kssl_ctx != NULL)
iosize = (int)MIN(iosize, maxblk);
- if ((mp = allocb(iosize + extra, BPRI_MED)) == NULL) {
+ if (is_system_labeled()) {
+ mp = allocb_cred(iosize + extra, CRED(),
+ curproc->p_pid);
+ } else {
+ mp = allocb(iosize + extra, BPRI_MED);
+ }
+ if (mp == NULL) {
error = EAGAIN;
break;
}
diff --git a/usr/src/uts/common/fs/sockfs/socktpi.c b/usr/src/uts/common/fs/sockfs/socktpi.c
index 6da1594..d801c1e 100644
--- a/usr/src/uts/common/fs/sockfs/socktpi.c
+++ b/usr/src/uts/common/fs/sockfs/socktpi.c
@@ -682,7 +682,8 @@
dprintso(so, 1, ("sobind: allocating unbind_req\n"));
/* NOTE: holding so_lock while sleeping */
sti->sti_unbind_mp =
- soallocproto(sizeof (struct T_unbind_req), _ALLOC_SLEEP);
+ soallocproto(sizeof (struct T_unbind_req), _ALLOC_SLEEP,
+ cr);
}
if (flags & _SOBIND_REBIND) {
@@ -1094,7 +1095,7 @@
bind_req.CONIND_number = backlog;
/* NOTE: holding so_lock while sleeping */
mp = soallocproto2(&bind_req, sizeof (bind_req),
- addr, addrlen, 0, _ALLOC_SLEEP);
+ addr, addrlen, 0, _ALLOC_SLEEP, cr);
sti->sti_laddr_valid = 0;
/* Done using sti_laddr_sa - can drop the lock */
@@ -1478,7 +1479,7 @@
unbind_req.PRIM_type = T_UNBIND_REQ;
mp = soallocproto1(&unbind_req, sizeof (unbind_req),
- 0, _ALLOC_SLEEP);
+ 0, _ALLOC_SLEEP, CRED());
error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0,
MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR, 0);
mutex_enter(&so->so_lock);
@@ -1663,7 +1664,7 @@
discon_req.PRIM_type = T_DISCON_REQ;
discon_req.SEQ_number = seqno;
mp = soallocproto1(&discon_req, sizeof (discon_req),
- 0, _ALLOC_SLEEP);
+ 0, _ALLOC_SLEEP, CRED());
error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0,
MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR, 0);
mutex_enter(&so->so_lock);
@@ -1781,7 +1782,7 @@
*/
sti->sti_direct = 0;
(void) strioctl(SOTOV(so), _SIOCSOCKFALLBACK,
- 0, 0, K_TO_K, CRED(), &rval);
+ 0, 0, K_TO_K, cr, &rval);
}
opt = NULL;
optlen = 0;
@@ -1881,19 +1882,25 @@
bcopy(src, nsti->sti_faddr_sa, srclen);
nsti->sti_faddr_valid = 1;
+ /*
+ * Record so_peercred and so_cpid from a cred in the T_CONN_IND.
+ * Send down a T_CONN_RES without a cred.
+ */
if ((DB_REF(mp) > 1) || MBLKSIZE(mp) <
(sizeof (struct T_conn_res) + sizeof (intptr_t))) {
- cred_t *cr;
+ cred_t *cr;
+ pid_t cpid;
- if ((cr = DB_CRED(mp)) != NULL) {
+ cr = msg_getcred(mp, &cpid);
+ if (cr != NULL) {
crhold(cr);
nso->so_peercred = cr;
- nso->so_cpid = DB_CPID(mp);
+ nso->so_cpid = cpid;
}
freemsg(mp);
mp = soallocproto1(NULL, sizeof (struct T_conn_res) +
- sizeof (intptr_t), 0, _ALLOC_INTR);
+ sizeof (intptr_t), 0, _ALLOC_INTR, NULL);
if (mp == NULL) {
/*
* Accept can not fail with ENOBUFS.
@@ -1905,9 +1912,12 @@
}
conn_res = (struct T_conn_res *)mp->b_rptr;
} else {
- nso->so_peercred = DB_CRED(mp);
- nso->so_cpid = DB_CPID(mp);
- DB_CRED(mp) = NULL;
+ /*
+ * For efficency reasons we use msg_extractcred; no crhold
+ * needed since db_credp is cleared (i.e., we move the cred
+ * from the message to so_peercred.
+ */
+ nso->so_peercred = msg_extractcred(mp, &nso->so_cpid);
mp->b_rptr = DB_BASE(mp);
conn_res = (struct T_conn_res *)mp->b_rptr;
@@ -1955,7 +1965,7 @@
nsti->sti_faddr_noxlate = sti->sti_faddr_noxlate;
if (nso->so_pgrp != 0) {
- if ((error = so_set_events(nso, nvp, CRED())) != 0) {
+ if ((error = so_set_events(nso, nvp, cr)) != 0) {
eprintsoline(nso, error);
error = 0;
nso->so_pgrp = 0;
@@ -2059,7 +2069,7 @@
*/
mutex_exit(&nso->so_lock);
(void) VOP_CLOSE(nvp, 0, 1, (offset_t)0,
- CRED(), NULL);
+ cr, NULL);
VN_RELE(nvp);
goto again;
}
@@ -2079,7 +2089,7 @@
int rval;
if ((error = strioctl(SOTOV(nso), _SIOCSOCKFALLBACK,
- 0, 0, K_TO_K, CRED(), &rval)) != 0) {
+ 0, 0, K_TO_K, cr, &rval)) != 0) {
mutex_enter(&so->so_lock);
so_lock_single(so);
eprintsoline(so, error);
@@ -2207,7 +2217,7 @@
pr_disc_vp_unl:
eprintsoline(so, error);
disconnect_vp_unlocked:
- (void) VOP_CLOSE(nvp, 0, 1, 0, CRED(), NULL);
+ (void) VOP_CLOSE(nvp, 0, 1, 0, cr, NULL);
VN_RELE(nvp);
disconnect_unlocked:
(void) sodisconnect(so, SEQ_number, 0);
@@ -2219,7 +2229,7 @@
(void) sodisconnect(so, SEQ_number, _SODISCONNECT_LOCK_HELD);
so_unlock_single(so, SOLOCKED);
mutex_exit(&so->so_lock);
- (void) VOP_CLOSE(nvp, 0, 1, 0, CRED(), NULL);
+ (void) VOP_CLOSE(nvp, 0, 1, 0, cr, NULL);
VN_RELE(nvp);
return (error);
@@ -2268,7 +2278,8 @@
* exceed sti_faddr_maxlen).
*/
mp = soallocproto(sizeof (struct T_conn_req) +
- 2 * sti->sti_faddr_maxlen + sizeof (struct T_opthdr), _ALLOC_INTR);
+ 2 * sti->sti_faddr_maxlen + sizeof (struct T_opthdr), _ALLOC_INTR,
+ cr);
if (mp == NULL) {
/*
* Connect can not fail with ENOBUFS. A signal was
@@ -2296,7 +2307,7 @@
dprintso(so, 1, ("sotpi_connect: allocating unbind_req\n"));
/* NOTE: holding so_lock while sleeping */
sti->sti_unbind_mp =
- soallocproto(sizeof (struct T_unbind_req), _ALLOC_INTR);
+ soallocproto(sizeof (struct T_unbind_req), _ALLOC_INTR, cr);
if (sti->sti_unbind_mp == NULL) {
error = EINTR;
goto done;
@@ -2820,7 +2831,7 @@
mutex_exit(&so->so_lock);
mp = soallocproto1(&ordrel_req, sizeof (ordrel_req),
- 0, _ALLOC_SLEEP);
+ 0, _ALLOC_SLEEP, cr);
/*
* Send down the T_ORDREL_REQ even if there is flow control.
* This prevents shutdown from blocking.
@@ -2897,7 +2908,7 @@
/* NOTE: holding so_lock while sleeping */
mp = soallocproto2(&tdr, sizeof (tdr),
- &toh, sizeof (toh), 0, _ALLOC_SLEEP);
+ &toh, sizeof (toh), 0, _ALLOC_SLEEP, CRED());
} else {
struct T_unitdata_req tudr;
void *addr;
@@ -2963,7 +2974,7 @@
size = tudr.OPT_offset + tudr.OPT_length;
/* NOTE: holding so_lock while sleeping */
mp = soallocproto2(&tudr, sizeof (tudr),
- addr, addrlen, size, _ALLOC_SLEEP);
+ addr, addrlen, size, _ALLOC_SLEEP, CRED());
mp->b_wptr += (_TPI_ALIGN_TOPT(addrlen) - addrlen);
soappendmsg(mp, &toh, sizeof (toh));
} else {
@@ -2986,7 +2997,7 @@
/* NOTE: holding so_lock while sleeping */
mp = soallocproto2(&tudr, sizeof (tudr),
- addr, addrlen, size, _ALLOC_SLEEP);
+ addr, addrlen, size, _ALLOC_SLEEP, CRED());
mp->b_wptr += _TPI_ALIGN_TOPT(addrlen) - addrlen;
soappendmsg(mp, &toh, sizeof (toh));
soappendmsg(mp, &toh2, sizeof (toh2));
@@ -3830,7 +3841,7 @@
return (error);
mp = fdbuf_allocmsg(size, fdbuf);
} else {
- mp = soallocproto(size, _ALLOC_INTR);
+ mp = soallocproto(size, _ALLOC_INTR, CRED());
if (mp == NULL) {
/*
* Caught a signal waiting for memory.
@@ -3963,7 +3974,7 @@
return (error);
mp = fdbuf_allocmsg(size, fdbuf);
} else {
- mp = soallocproto(size, _ALLOC_INTR);
+ mp = soallocproto(size, _ALLOC_INTR, CRED());
if (mp == NULL) {
/*
* Caught a signal waiting for memory.
@@ -4108,7 +4119,7 @@
tudr.OPT_offset = 0;
mp = soallocproto2(&tudr, sizeof (tudr),
- addr, addrlen, 0, _ALLOC_INTR);
+ addr, addrlen, 0, _ALLOC_INTR, CRED());
if (mp == NULL) {
/*
* Caught a signal waiting for memory.
@@ -4137,7 +4148,7 @@
size = tudr.OPT_offset + tudr.OPT_length;
mp = soallocproto2(&tudr, sizeof (tudr),
- addr, addrlen, size, _ALLOC_INTR);
+ addr, addrlen, size, _ALLOC_INTR, CRED());
if (mp == NULL) {
/*
* Caught a signal waiting for memory.
@@ -4211,7 +4222,7 @@
}
dprintso(so, 1, ("sosend_svc: sending 0x%x %d, %ld bytes\n",
prim, tdr.MORE_flag, iosize));
- mp = soallocproto1(&tdr, sizeof (tdr), 0, _ALLOC_INTR);
+ mp = soallocproto1(&tdr, sizeof (tdr), 0, _ALLOC_INTR, CRED());
if (mp == NULL) {
/*
* Caught a signal waiting for memory.
@@ -4711,7 +4722,7 @@
tudr.OPT_offset = 0;
mp = soallocproto2(&tudr, sizeof (tudr), addr, addrlen, 0,
- _ALLOC_INTR);
+ _ALLOC_INTR, CRED());
if (mp == NULL) {
/*
* Caught a signal waiting for memory.
@@ -5426,7 +5437,7 @@
oh.len = maxlen;
mp = soallocproto3(&optmgmt_req, sizeof (optmgmt_req),
- &oh, sizeof (oh), NULL, maxlen, 0, _ALLOC_SLEEP);
+ &oh, sizeof (oh), NULL, maxlen, 0, _ALLOC_SLEEP, cr);
/* Let option management work in the presence of data flow control */
error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0,
MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR|MSG_IGNFLOW, 0);
@@ -5733,7 +5744,7 @@
oh.len = optlen;
mp = soallocproto3(&optmgmt_req, sizeof (optmgmt_req),
- &oh, sizeof (oh), optval, optlen, 0, _ALLOC_SLEEP);
+ &oh, sizeof (oh), optval, optlen, 0, _ALLOC_SLEEP, cr);
/* Let option management work in the presence of data flow control */
error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0,
MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR|MSG_IGNFLOW, 0);
@@ -6297,7 +6308,7 @@
mutex_exit(&so->so_lock);
error = strioctl(vp, _SIOCSOCKFALLBACK, 0, 0, K_TO_K,
- CRED(), rvalp);
+ cr, rvalp);
mutex_enter(&so->so_lock);
if (error == 0)
diff --git a/usr/src/uts/common/fs/sockfs/socktpi_impl.h b/usr/src/uts/common/fs/sockfs/socktpi_impl.h
index aa0b04b..6a515be 100644
--- a/usr/src/uts/common/fs/sockfs/socktpi_impl.h
+++ b/usr/src/uts/common/fs/sockfs/socktpi_impl.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -71,13 +71,13 @@
extern void so_drain_discon_ind(struct sonode *);
extern void so_flush_discon_ind(struct sonode *);
-extern mblk_t *soallocproto(size_t, int);
-extern mblk_t *soallocproto1(const void *, ssize_t, ssize_t, int);
+extern mblk_t *soallocproto(size_t, int, cred_t *);
+extern mblk_t *soallocproto1(const void *, ssize_t, ssize_t, int, cred_t *);
extern void soappendmsg(mblk_t *, const void *, ssize_t);
extern mblk_t *soallocproto2(const void *, ssize_t, const void *, ssize_t,
- ssize_t, int);
+ ssize_t, int, cred_t *);
extern mblk_t *soallocproto3(const void *, ssize_t, const void *, ssize_t,
- const void *, ssize_t, ssize_t, int);
+ const void *, ssize_t, ssize_t, int, cred_t *);
extern int so_set_asyncsigs(vnode_t *, pid_t, int, int, cred_t *);
extern int so_flip_async(struct sonode *, vnode_t *, int, cred_t *);
diff --git a/usr/src/uts/common/inet/arp/arp.c b/usr/src/uts/common/inet/arp/arp.c
index 06c499c..f2bfb50 100644
--- a/usr/src/uts/common/inet/arp/arp.c
+++ b/usr/src/uts/common/inet/arp/arp.c
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/stropts.h>
+#include <sys/strsubr.h>
#include <sys/errno.h>
#include <sys/strlog.h>
#include <sys/dlpi.h>
@@ -1259,6 +1260,11 @@
mp = mp->b_cont;
if (!mp)
return (ENOENT);
+ } else {
+ cr = msg_getcred(mp, NULL);
+ /* For initial messages beteen IP and ARP, cr can be NULL */
+ if (cr == NULL)
+ cr = ((ar_t *)q->q_ptr)->ar_credp;
}
len = MBLKL(mp);
if (len < sizeof (uint32_t) || !OK_32PTR(mp->b_rptr))
@@ -1282,9 +1288,6 @@
if (arct->arct_priv_req != OP_NP) {
int error;
- if (cr == NULL)
- cr = DB_CREDDEF(mp_orig, ((ar_t *)q->q_ptr)->ar_credp);
-
if ((error = secpolicy_ip(cr, arct->arct_priv_req,
B_FALSE)) != 0)
return (error);
diff --git a/usr/src/uts/common/inet/ip.h b/usr/src/uts/common/inet/ip.h
index 4159528..ff82081 100644
--- a/usr/src/uts/common/inet/ip.h
+++ b/usr/src/uts/common/inet/ip.h
@@ -294,11 +294,6 @@
CONN_DEC_REF(connp); \
}
-/* Get the credential of an IP queue of unknown type */
-#define GET_QUEUE_CRED(wq) \
- ((wq)->q_next ? (((ill_t *)(wq)->q_ptr)->ill_credp) \
- : ((Q_TO_CONN((wq)))->conn_cred))
-
/*
* Flags for the various ip_fanout_* routines.
*/
@@ -3224,6 +3219,7 @@
extern void icmp_unreachable(queue_t *, mblk_t *, uint8_t, zoneid_t,
ip_stack_t *);
extern mblk_t *ip_add_info(mblk_t *, ill_t *, uint_t, zoneid_t, ip_stack_t *);
+cred_t *ip_best_cred(mblk_t *, conn_t *);
extern mblk_t *ip_bind_v4(queue_t *, mblk_t *, conn_t *);
extern boolean_t ip_bind_ipsec_policy_set(conn_t *, mblk_t *);
extern int ip_bind_laddr_v4(conn_t *, mblk_t **, uint8_t, ipaddr_t,
@@ -3231,9 +3227,10 @@
extern int ip_proto_bind_laddr_v4(conn_t *, mblk_t **, uint8_t, ipaddr_t,
uint16_t, boolean_t);
extern int ip_proto_bind_connected_v4(conn_t *, mblk_t **,
- uint8_t, ipaddr_t *, uint16_t, ipaddr_t, uint16_t, boolean_t, boolean_t);
+ uint8_t, ipaddr_t *, uint16_t, ipaddr_t, uint16_t, boolean_t, boolean_t,
+ cred_t *);
extern int ip_bind_connected_v4(conn_t *, mblk_t **, uint8_t, ipaddr_t *,
- uint16_t, ipaddr_t, uint16_t, boolean_t, boolean_t);
+ uint16_t, ipaddr_t, uint16_t, boolean_t, boolean_t, cred_t *);
extern uint_t ip_cksum(mblk_t *, int, uint32_t);
extern int ip_close(queue_t *, int);
extern uint16_t ip_csum_hdr(ipha_t *);
diff --git a/usr/src/uts/common/inet/ip/icmp.c b/usr/src/uts/common/inet/ip/icmp.c
index b381983..e26254a 100644
--- a/usr/src/uts/common/inet/ip/icmp.c
+++ b/usr/src/uts/common/inet/ip/icmp.c
@@ -141,6 +141,7 @@
cred_t *cr);
static void icmp_ud_err(queue_t *q, mblk_t *mp, t_scalar_t err);
static void icmp_tpi_unbind(queue_t *q, mblk_t *mp);
+static int icmp_update_label(icmp_t *icmp, mblk_t *mp, ipaddr_t dst);
static void icmp_wput(queue_t *q, mblk_t *mp);
static void icmp_wput_fallback(queue_t *q, mblk_t *mp);
static int raw_ip_send_data_v6(queue_t *q, conn_t *connp, mblk_t *mp,
@@ -248,7 +249,7 @@
static int rawip_do_bind(conn_t *connp, struct sockaddr *sa, socklen_t len);
static int rawip_do_connect(conn_t *connp, const struct sockaddr *sa,
- socklen_t len);
+ socklen_t len, cred_t *cr);
static void rawip_post_ip_bind_connect(icmp_t *icmp, mblk_t *ire_mp, int error);
/*
@@ -270,6 +271,21 @@
icmp_t *icmp;
conn_t *connp = Q_TO_CONN(q);
mblk_t *mp1;
+ cred_t *cr;
+
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ icmp_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
icmp = connp->conn_icmp;
if ((mp->b_wptr - mp->b_rptr) < sizeof (*tbr)) {
@@ -579,6 +595,21 @@
struct sockaddr *sa;
socklen_t len;
int error;
+ cred_t *cr;
+
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ icmp_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
icmp = connp->conn_icmp;
tcr = (struct T_conn_req *)mp->b_rptr;
@@ -615,7 +646,7 @@
return;
}
- error = rawip_do_connect(connp, sa, len);
+ error = rawip_do_connect(connp, sa, len, cr);
if (error != 0) {
if (error < 0) {
icmp_err_ack(q, mp, -error, 0);
@@ -659,7 +690,8 @@
}
static int
-rawip_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len)
+rawip_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
+ cred_t *cr)
{
icmp_t *icmp;
sin_t *sin;
@@ -779,12 +811,12 @@
error = ip_proto_bind_connected_v6(connp, &ire_mp,
icmp->icmp_proto, &icmp->icmp_v6src, 0,
&icmp->icmp_v6dst.sin6_addr,
- NULL, sin6->sin6_port, B_TRUE, B_TRUE);
+ NULL, sin6->sin6_port, B_TRUE, B_TRUE, cr);
} else {
error = ip_proto_bind_connected_v4(connp, &ire_mp,
icmp->icmp_proto, &V4_PART_OF_V6(icmp->icmp_v6src), 0,
V4_PART_OF_V6(icmp->icmp_v6dst.sin6_addr), sin->sin_port,
- B_TRUE, B_TRUE);
+ B_TRUE, B_TRUE, cr);
}
rawip_post_ip_bind_connect(icmp, ire_mp, error);
return (error);
@@ -4370,7 +4402,6 @@
}
}
- mblk_setcred(mp, connp->conn_cred);
ip_output_options(connp, mp, q, IP_WPUT, &optinfo);
return (0);
}
@@ -4381,9 +4412,21 @@
int err;
uchar_t opt_storage[IP_MAX_OPT_LENGTH];
icmp_stack_t *is = icmp->icmp_is;
- conn_t *connp = icmp->icmp_connp;
+ conn_t *connp = icmp->icmp_connp;
+ cred_t *cr;
- err = tsol_compute_label(DB_CREDDEF(mp, connp->conn_cred), dst,
+ /*
+ * All Solaris components should pass a db_credp
+ * for this message, hence we ASSERT.
+ * On production kernels we return an error to be robust against
+ * random streams modules sitting on top of us.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL)
+ return (EINVAL);
+
+ err = tsol_compute_label(cr, dst,
opt_storage, connp->conn_mac_exempt,
is->is_netstack->netstack_ip);
if (err == 0) {
@@ -4740,7 +4783,6 @@
}
BUMP_MIB(&is->is_rawip_mib, rawipOutDatagrams);
- mblk_setcred(mp, connp->conn_cred);
ip_output_options(connp, mp, q, IP_WPUT, &optinfo);
return (0);
}
@@ -4751,9 +4793,21 @@
int err;
uchar_t opt_storage[TSOL_MAX_IPV6_OPTION];
icmp_stack_t *is = icmp->icmp_is;
- conn_t *connp = icmp->icmp_connp;
+ conn_t *connp = icmp->icmp_connp;
+ cred_t *cr;
- err = tsol_compute_label_v6(DB_CREDDEF(mp, connp->conn_cred), dst,
+ /*
+ * All Solaris components should pass a db_credp
+ * for this message, hence we ASSERT.
+ * On production kernels we return an error to be robust against
+ * random streams modules sitting on top of us.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL)
+ return (EINVAL);
+
+ err = tsol_compute_label_v6(cr, dst,
opt_storage, connp->conn_mac_exempt,
is->is_netstack->netstack_ip);
if (err == 0) {
@@ -5331,8 +5385,6 @@
icmp_stack_t *is = icmp->icmp_is;
cred_t *cr;
- cr = DB_CREDDEF(mp, connp->conn_cred);
-
switch (mp->b_datap->db_type) {
case M_PROTO:
case M_PCPROTO:
@@ -5374,6 +5426,20 @@
return;
case T_SVR4_OPTMGMT_REQ:
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ icmp_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
+
if (!snmpcom_req(q, mp, icmp_snmp_set, ip_snmp_get,
cr)) {
/* Only IP can return anything meaningful */
@@ -5383,6 +5449,19 @@
return;
case T_OPTMGMT_REQ:
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ icmp_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
/* Only IP can return anything meaningful */
(void) tpi_optcom_req(q, mp, cr, &icmp_opt_obj, B_TRUE);
return;
@@ -5568,7 +5647,6 @@
icmp_unitdata_opt_process(queue_t *q, mblk_t *mp, int *errorp,
void *thisdg_attrs)
{
- conn_t *connp = Q_TO_CONN(q);
struct T_unitdata_req *udreqp;
int is_absreq_failure;
cred_t *cr;
@@ -5576,7 +5654,17 @@
udreqp = (struct T_unitdata_req *)mp->b_rptr;
*errorp = 0;
- cr = DB_CREDDEF(mp, connp->conn_cred);
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL)
+ return (-1);
*errorp = tpi_optcom_buf(q, mp, &udreqp->OPT_length,
udreqp->OPT_offset, cr, &icmp_opt_obj,
@@ -5747,6 +5835,9 @@
conn_t *connp = (conn_t *)proto_handle;
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
/* Binding to a NULL address really means unbind */
if (sa == NULL)
error = rawip_do_unbind(connp);
@@ -5820,6 +5911,9 @@
int error;
boolean_t did_bind = B_FALSE;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (sa == NULL) {
/*
* Disconnect
@@ -5854,7 +5948,7 @@
*/
icmp->icmp_dgram_errind = B_TRUE;
- error = rawip_do_connect(connp, sa, len);
+ error = rawip_do_connect(connp, sa, len, cr);
if (error != 0 && did_bind) {
int unbind_err;
@@ -5927,9 +6021,9 @@
laddrlen = faddrlen = sizeof (sin6_t);
(void) rawip_getsockname((sock_lower_handle_t)connp,
- (struct sockaddr *)&laddr, &laddrlen, NULL);
+ (struct sockaddr *)&laddr, &laddrlen, CRED());
error = rawip_getpeername((sock_lower_handle_t)connp,
- (struct sockaddr *)&faddr, &faddrlen, NULL);
+ (struct sockaddr *)&faddr, &faddrlen, CRED());
if (error != 0)
faddrlen = 0;
opts = 0;
@@ -6038,6 +6132,9 @@
icmp_stack_t *is = connp->conn_icmp->icmp_is;
struct sock_proto_props sopp;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
connp->conn_upcalls = sock_upcalls;
connp->conn_upper_handle = sock_handle;
@@ -6169,6 +6266,9 @@
icmp_t *icmp = connp->conn_icmp;
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
ASSERT(icmp != NULL);
rw_enter(&icmp->icmp_rwlock, RW_READER);
@@ -6189,6 +6289,9 @@
icmp_t *icmp = connp->conn_icmp;
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
ASSERT(icmp != NULL);
rw_enter(&icmp->icmp_rwlock, RW_READER);
@@ -6207,6 +6310,9 @@
icmp_t *icmp = connp->conn_icmp;
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
error = proto_opt_check(level, option_name, optlen, NULL,
icmp_opt_obj.odb_opt_des_arr,
icmp_opt_obj.odb_opt_arr_cnt,
@@ -6253,6 +6359,9 @@
void *optvalp_buf;
int len;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
error = proto_opt_check(level, option_name, *optlen, &max_optbuf_len,
icmp_opt_obj.odb_opt_des_arr,
icmp_opt_obj.odb_opt_arr_cnt,
@@ -6296,6 +6405,10 @@
rawip_close(sock_lower_handle_t proto_handle, int flags, cred_t *cr)
{
conn_t *connp = (conn_t *)proto_handle;
+
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
(void) rawip_do_close(connp);
return (0);
}
@@ -6306,6 +6419,9 @@
{
conn_t *connp = (conn_t *)proto_handle;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
/* shut down the send side */
if (how != SHUT_RD)
(*connp->conn_upcalls->su_opctl)(connp->conn_upper_handle,
@@ -6335,6 +6451,9 @@
conn_t *connp = (conn_t *)proto_handle;
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
switch (cmd) {
case ND_SET:
case ND_GET:
@@ -6371,8 +6490,11 @@
ASSERT(DB_TYPE(mp) == M_DATA);
- if (is_system_labeled())
- msg_setcredpid(mp, cr, curproc->p_pid);
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
+ /* If labeled then sockfs should have already set db_credp */
+ ASSERT(!is_system_labeled() || msg_getcred(mp, NULL) != NULL);
/* do an implicit bind if necessary */
if (icmp->icmp_state == TS_UNBND) {
@@ -6454,7 +6576,7 @@
if (msg->msg_controllen != 0) {
error = process_auxiliary_options(connp,
msg->msg_control, msg->msg_controllen,
- ipp, &icmp_opt_obj, icmp_opt_set);
+ ipp, &icmp_opt_obj, icmp_opt_set, cr);
if (error != 0) {
goto done_lock;
}
@@ -6524,7 +6646,7 @@
if (msg->msg_controllen != 0) {
error = process_auxiliary_options(connp,
msg->msg_control, msg->msg_controllen,
- pktinfop, &icmp_opt_obj, icmp_opt_set);
+ pktinfop, &icmp_opt_obj, icmp_opt_set, cr);
if (error != 0) {
goto done_lock;
}
diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c
index 5994e06..66f4737 100644
--- a/usr/src/uts/common/inet/ip/ip.c
+++ b/usr/src/uts/common/inet/ip/ip.c
@@ -722,7 +722,8 @@
static void ip_wput_frag(ire_t *, mblk_t *, ip_pkt_t, uint32_t, uint32_t,
zoneid_t, ip_stack_t *, conn_t *);
-static mblk_t *ip_wput_frag_copyhdr(uchar_t *, int, int, ip_stack_t *);
+static mblk_t *ip_wput_frag_copyhdr(uchar_t *, int, int, ip_stack_t *,
+ mblk_t *);
static void ip_wput_local_options(ipha_t *, ip_stack_t *);
static int ip_wput_options(queue_t *, mblk_t *, ipha_t *, boolean_t,
zoneid_t, ip_stack_t *);
@@ -2153,7 +2154,7 @@
if (nexthop_addr != INADDR_ANY) {
/* nexthop set */
first_ire = ire_ctable_lookup(ipha->ipha_dst,
- nexthop_addr, 0, NULL, ALL_ZONES, MBLK_GETLABEL(mp),
+ nexthop_addr, 0, NULL, ALL_ZONES, msg_getlabel(mp),
MATCH_IRE_MARK_PRIVATE_ADDR | MATCH_IRE_GW, ipst);
} else {
/* nexthop not set */
@@ -3327,6 +3328,7 @@
(void) adjmsg(mp, len_needed - msg_len);
msg_len = len_needed;
}
+ /* Make sure we propagate the cred/label for TX */
mp1 = allocb_tmpl(sizeof (icmp_ipha) + len, mp);
if (mp1 == NULL) {
BUMP_MIB(&ipst->ips_icmp_mib, icmpOutErrors);
@@ -4050,7 +4052,7 @@
ipif->ipif_addr_ready = 1;
ipif_refrele(ipif);
}
- ire = ire_cache_lookup(src, ALL_ZONES, MBLK_GETLABEL(mp), ipst);
+ ire = ire_cache_lookup(src, ALL_ZONES, msg_getlabel(mp), ipst);
if (ire != NULL) {
ire->ire_defense_count = 0;
ire_refrele(ire);
@@ -4212,6 +4214,24 @@
}
/*
+ * Used to determine the most accurate cred_t to use for TX.
+ * First priority is SCM_UCRED having set the label in the message,
+ * which is used for MLP on UDP. Second priority is the peers label (aka
+ * conn_peercred), which is needed for MLP on TCP/SCTP. Last priority is the
+ * open credentials.
+ */
+cred_t *
+ip_best_cred(mblk_t *mp, conn_t *connp)
+{
+ cred_t *cr;
+
+ cr = msg_getcred(mp, NULL);
+ if (cr != NULL && crgetlabel(cr) != NULL)
+ return (cr);
+ return (CONN_CRED(connp));
+}
+
+/*
* Latch in the IPsec state for a stream based on the ipsec_in_t passed in as
* part of the bind request.
*/
@@ -4301,6 +4321,21 @@
int error = 0;
int protocol;
ipa_conn_x_t *acx;
+ cred_t *cr;
+
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ error = EINVAL;
+ goto bad_addr;
+ }
ASSERT(!connp->conn_af_isv6);
connp->conn_pkt_isv6 = B_FALSE;
@@ -4403,7 +4438,7 @@
/* Always verify destination reachability. */
error = ip_bind_connected_v4(connp, &mp1, protocol,
&ac->ac_laddr, ac->ac_lport, ac->ac_faddr, ac->ac_fport,
- B_TRUE, B_TRUE);
+ B_TRUE, B_TRUE, cr);
break;
case sizeof (ipa_conn_x_t):
@@ -4415,7 +4450,7 @@
error = ip_bind_connected_v4(connp, &mp1, protocol,
&acx->acx_conn.ac_laddr, acx->acx_conn.ac_lport,
acx->acx_conn.ac_faddr, acx->acx_conn.ac_fport,
- B_TRUE, (acx->acx_flags & ACX_VERIFY_DST) != 0);
+ B_TRUE, (acx->acx_flags & ACX_VERIFY_DST) != 0, cr);
break;
}
ASSERT(error != EINPROGRESS);
@@ -4664,7 +4699,7 @@
int
ip_bind_connected_v4(conn_t *connp, mblk_t **mpp, uint8_t protocol,
ipaddr_t *src_addrp, uint16_t lport, ipaddr_t dst_addr, uint16_t fport,
- boolean_t fanout_insert, boolean_t verify_dst)
+ boolean_t fanout_insert, boolean_t verify_dst, cred_t *cr)
{
ire_t *src_ire;
@@ -4688,8 +4723,9 @@
if (mp != NULL) {
ire_requested = (DB_TYPE(mp) == IRE_DB_REQ_TYPE);
ipsec_policy_set = (DB_TYPE(mp) == IPSEC_POLICY_SET);
- tsl = MBLK_GETLABEL(mp);
}
+ if (cr != NULL)
+ tsl = crgetlabel(cr);
src_ire = dst_ire = NULL;
@@ -4791,7 +4827,7 @@
*/
if (dst_ire != NULL && is_system_labeled() &&
!IPCL_IS_TCP(connp) &&
- tsol_compute_label(DB_CREDDEF(mp, connp->conn_cred), dst_addr, NULL,
+ tsol_compute_label(cr, dst_addr, NULL,
connp->conn_mac_exempt, ipst) != 0) {
error = EHOSTUNREACH;
if (ip_debug > 2) {
@@ -5142,7 +5178,7 @@
int
ip_proto_bind_connected_v4(conn_t *connp, mblk_t **ire_mpp, uint8_t protocol,
ipaddr_t *src_addrp, uint16_t lport, ipaddr_t dst_addr, uint16_t fport,
- boolean_t fanout_insert, boolean_t verify_dst)
+ boolean_t fanout_insert, boolean_t verify_dst, cred_t *cr)
{
int error;
mblk_t *mp = NULL;
@@ -5160,7 +5196,7 @@
if (lport == 0)
lport = connp->conn_lport;
error = ip_bind_connected_v4(connp, ire_mpp, protocol,
- src_addrp, lport, dst_addr, fport, fanout_insert, verify_dst);
+ src_addrp, lport, dst_addr, fport, fanout_insert, verify_dst, cr);
if (error == 0) {
ip_bind_post_handling(connp, ire_mpp ? *ire_mpp : NULL,
ire_requested);
@@ -7123,7 +7159,7 @@
unlabeled = B_FALSE;
if (is_system_labeled())
/* Cred cannot be null on IPv4 */
- unlabeled = (crgetlabel(DB_CRED(mp))->tsl_flags &
+ unlabeled = (msg_getlabel(mp)->tsl_flags &
TSLF_UNLABELED) != 0;
shared_addr = (zoneid == ALL_ZONES);
if (shared_addr) {
@@ -7851,14 +7887,14 @@
* destination address via the specified nexthop.
*/
ire = ire_cache_lookup(nexthop_addr, zoneid,
- MBLK_GETLABEL(mp), ipst);
+ msg_getlabel(mp), ipst);
if (ire != NULL) {
gw = nexthop_addr;
ire_marks |= IRE_MARK_PRIVATE_ADDR;
} else {
ire = ire_ftable_lookup(nexthop_addr, 0, 0,
IRE_INTERFACE, NULL, NULL, zoneid, 0,
- MBLK_GETLABEL(mp),
+ msg_getlabel(mp),
MATCH_IRE_TYPE | MATCH_IRE_SECATTR,
ipst);
if (ire != NULL) {
@@ -7867,7 +7903,7 @@
}
} else {
ire = ire_ftable_lookup(dst, 0, 0, 0,
- NULL, &sire, zoneid, 0, MBLK_GETLABEL(mp),
+ NULL, &sire, zoneid, 0, msg_getlabel(mp),
MATCH_IRE_RECURSIVE | MATCH_IRE_DEFAULT |
MATCH_IRE_RJ_BHOLE | MATCH_IRE_PARENT |
MATCH_IRE_SECATTR | MATCH_IRE_COMPLETE,
@@ -7912,7 +7948,7 @@
ASSERT(sire != NULL);
multirt_is_resolvable =
ire_multirt_lookup(&ire, &sire, multirt_flags,
- MBLK_GETLABEL(mp), ipst);
+ msg_getlabel(mp), ipst);
ip3dbg(("ip_newroute: multirt_is_resolvable %d, "
"ire %p, sire %p\n",
@@ -9189,7 +9225,7 @@
if ((flags & RTF_MULTIRT) && (copy_mp != NULL)) {
boolean_t need_resolve =
ire_multirt_need_resolve(ipha_dst,
- MBLK_GETLABEL(copy_mp), ipst);
+ msg_getlabel(copy_mp), ipst);
if (!need_resolve) {
MULTIRT_DEBUG_UNTAG(copy_mp);
freemsg(copy_mp);
@@ -9373,7 +9409,7 @@
if ((flags & RTF_MULTIRT) && (copy_mp != NULL)) {
boolean_t need_resolve =
ire_multirt_need_resolve(ipha_dst,
- MBLK_GETLABEL(copy_mp), ipst);
+ msg_getlabel(copy_mp), ipst);
if (!need_resolve) {
MULTIRT_DEBUG_UNTAG(copy_mp);
freemsg(copy_mp);
@@ -9838,9 +9874,24 @@
mp = connp->conn_ipsec_opt_mp;
connp->conn_ipsec_opt_mp = NULL;
connp->conn_state_flags &= ~CONN_IPSEC_LOAD_WAIT;
- cr = DB_CREDDEF(mp, GET_QUEUE_CRED(CONNP_TO_WQ(connp)));
mutex_exit(&connp->conn_lock);
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ mp = mi_tpi_err_ack_alloc(mp, TSYSERR, EINVAL);
+ if (mp != NULL)
+ qreply(connp->conn_wq, mp);
+ return;
+ }
+
ASSERT(DB_TYPE(mp) == M_PROTO || DB_TYPE(mp) == M_PCPROTO);
optreq_prim = ((union T_primitives *)mp->b_rptr)->type;
@@ -11328,7 +11379,7 @@
/*
* This routine gets socket options. For MRT_VERSION and MRT_ASSERT, error
- * checking of GET_QUEUE_CRED(q) and that ip_g_mrouter is set should be done and
+ * checking of cred and that ip_g_mrouter is set should be done and
* isn't. This doesn't matter as the error checking is done properly for the
* other MRT options coming in through ip_opt_set.
*/
@@ -13476,7 +13527,7 @@
DB_CKSUMFLAGS(mp) = 0;
ire = ire_forward(dst, &ret_action, NULL, NULL,
- MBLK_GETLABEL(mp), ipst);
+ msg_getlabel(mp), ipst);
if (ire == NULL && ret_action == Forward_check_multirt) {
/* Let ip_newroute handle CGTP */
@@ -15106,7 +15157,7 @@
if (ire == NULL) {
ire = ire_cache_lookup(dst, ALL_ZONES,
- MBLK_GETLABEL(mp), ipst);
+ msg_getlabel(mp), ipst);
}
if (ire != NULL && ire->ire_stq != NULL &&
@@ -15118,7 +15169,7 @@
*/
ire_refrele(ire);
ire = ire_cache_lookup(dst, GLOBAL_ZONEID,
- MBLK_GETLABEL(mp), ipst);
+ msg_getlabel(mp), ipst);
}
if (ire == NULL) {
@@ -15397,7 +15448,7 @@
ire = NULL;
}
- ire = ire_cache_lookup(dst, ALL_ZONES, MBLK_GETLABEL(mp),
+ ire = ire_cache_lookup(dst, ALL_ZONES, msg_getlabel(mp),
ipst);
if (ire == NULL || ire->ire_type == IRE_BROADCAST ||
ire->ire_stq != NULL) {
@@ -16740,7 +16791,7 @@
if (ipif->ipif_flags & IPIF_POINTOPOINT)
dst = ipif->ipif_pp_dst_addr;
- ire = ire_ctable_lookup(dst, 0, 0, ipif, ALL_ZONES, MBLK_GETLABEL(mp),
+ ire = ire_ctable_lookup(dst, 0, 0, ipif, ALL_ZONES, msg_getlabel(mp),
MATCH_IRE_ILL | MATCH_IRE_SECATTR, ipst);
if (ire == NULL) {
/*
@@ -17059,7 +17110,7 @@
if (ire == NULL) {
ire = ire_cache_lookup(dst, ii->ipsec_in_zoneid,
- MBLK_GETLABEL(mp), ipst);
+ msg_getlabel(mp), ipst);
if (ire == NULL) {
if (ill_need_rele)
ill_refrele(ill);
@@ -18042,7 +18093,7 @@
if (optval == IPOPT_SSRR) {
ire = ire_ftable_lookup(dst, 0, 0,
IRE_INTERFACE, NULL, NULL, ALL_ZONES, 0,
- MBLK_GETLABEL(mp),
+ msg_getlabel(mp),
MATCH_IRE_TYPE | MATCH_IRE_SECATTR, ipst);
if (ire == NULL) {
ip1dbg(("ip_rput_options: SSRR not "
@@ -20463,7 +20514,7 @@
* address, SO_DONTROUTE and IP_NEXTHOP go through the
* standard path.
*/
- ire = ire_cache_lookup(dst, zoneid, MBLK_GETLABEL(mp), ipst);
+ ire = ire_cache_lookup(dst, zoneid, msg_getlabel(mp), ipst);
if ((ire == NULL) || (ire->ire_type &
(IRE_BROADCAST | IRE_LOCAL | IRE_LOOPBACK)) == 0) {
if (ire != NULL) {
@@ -20497,7 +20548,7 @@
*/
if (IP_FLOW_CONTROLLED_ULP(connp->conn_ulp) &&
!connp->conn_fully_bound) {
- ire = ire_cache_lookup(dst, zoneid, MBLK_GETLABEL(mp), ipst);
+ ire = ire_cache_lookup(dst, zoneid, msg_getlabel(mp), ipst);
if (ire == NULL)
goto noirefound;
TRACE_2(TR_FAC_IP, TR_IP_WPUT_END,
@@ -20534,7 +20585,7 @@
*/
multirt_need_resolve =
ire_multirt_need_resolve(ire->ire_addr,
- MBLK_GETLABEL(first_mp), ipst);
+ msg_getlabel(first_mp), ipst);
ip2dbg(("ip_wput[TCP]: ire %p, "
"multirt_need_resolve %d, first_mp %p\n",
(void *)ire, multirt_need_resolve,
@@ -20603,7 +20654,7 @@
if (ire != NULL && sctp_ire == NULL)
IRE_REFRELE_NOTR(ire);
- ire = ire_cache_lookup(dst, zoneid, MBLK_GETLABEL(mp), ipst);
+ ire = ire_cache_lookup(dst, zoneid, msg_getlabel(mp), ipst);
if (ire == NULL)
goto noirefound;
IRE_REFHOLD_NOTR(ire);
@@ -20662,7 +20713,7 @@
* to initiate additional route resolutions.
*/
multirt_need_resolve = ire_multirt_need_resolve(ire->ire_addr,
- MBLK_GETLABEL(first_mp), ipst);
+ msg_getlabel(first_mp), ipst);
ip2dbg(("ip_wput[not TCP]: ire %p, "
"multirt_need_resolve %d, first_mp %p\n",
(void *)ire, multirt_need_resolve, (void *)first_mp));
@@ -21167,7 +21218,7 @@
ire = NULL;
if (xmit_ill == NULL) {
ire = ire_ctable_lookup(dst, 0, 0, ipif,
- zoneid, MBLK_GETLABEL(mp), match_flags, ipst);
+ zoneid, msg_getlabel(mp), match_flags, ipst);
}
if (ire == NULL) {
@@ -21228,7 +21279,7 @@
}
}
} else {
- ire = ire_cache_lookup(dst, zoneid, MBLK_GETLABEL(mp), ipst);
+ ire = ire_cache_lookup(dst, zoneid, msg_getlabel(mp), ipst);
if ((ire != NULL) && (ire->ire_type &
(IRE_BROADCAST | IRE_LOCAL | IRE_LOOPBACK))) {
ignore_dontroute = B_TRUE;
@@ -21326,7 +21377,7 @@
*/
match_flags |= MATCH_IRE_ILL | MATCH_IRE_SECATTR;
ire = ire_ctable_lookup(dst, 0, 0, ipif, zoneid,
- MBLK_GETLABEL(mp), match_flags, ipst);
+ msg_getlabel(mp), match_flags, ipst);
/*
* If an ire exists use it or else create
* an ire but don't add it to the cache.
@@ -21358,9 +21409,9 @@
match_flags = MATCH_IRE_MARK_PRIVATE_ADDR |
MATCH_IRE_GW;
ire = ire_ctable_lookup(dst, nexthop_addr, 0,
- NULL, zoneid, MBLK_GETLABEL(mp), match_flags, ipst);
+ NULL, zoneid, msg_getlabel(mp), match_flags, ipst);
} else {
- ire = ire_cache_lookup(dst, zoneid, MBLK_GETLABEL(mp),
+ ire = ire_cache_lookup(dst, zoneid, msg_getlabel(mp),
ipst);
}
if (!ire) {
@@ -21452,7 +21503,7 @@
* to initiate additional route resolutions.
*/
multirt_need_resolve = ire_multirt_need_resolve(ire->ire_addr,
- MBLK_GETLABEL(first_mp), ipst);
+ msg_getlabel(first_mp), ipst);
ip2dbg(("ip_wput[noirefound]: ire %p, "
"multirt_need_resolve %d, first_mp %p\n",
(void *)ire, multirt_need_resolve, (void *)first_mp));
@@ -24084,7 +24135,8 @@
}
/* Get a copy of the header for the trailing frags */
- hdr_mp = ip_wput_frag_copyhdr((uchar_t *)ipha, hdr_len, offset, ipst);
+ hdr_mp = ip_wput_frag_copyhdr((uchar_t *)ipha, hdr_len, offset, ipst,
+ mp);
if (!hdr_mp) {
BUMP_MIB(mibptr, ipIfStatsOutFragFails);
freemsg(mp);
@@ -24093,8 +24145,6 @@
"couldn't copy hdr");
return;
}
- if (DB_CRED(mp) != NULL)
- mblk_setcred(hdr_mp, DB_CRED(mp));
/* Store the starting offset, with the MoreFrags flag. */
i1 = offset | IPH_MF | frag_flag;
@@ -24309,8 +24359,7 @@
*/
} else {
xmit_mp->b_cont = mp;
- if (DB_CRED(mp) != NULL)
- mblk_setcred(xmit_mp, DB_CRED(mp));
+
/*
* Get priority marking, if any.
* We propagate the CoS marking from the
@@ -24607,8 +24656,6 @@
*/
} else if ((xmit_mp = copyb(ll_hdr_mp)) != NULL) {
xmit_mp->b_cont = mp;
- if (DB_CRED(mp) != NULL)
- mblk_setcred(xmit_mp, DB_CRED(mp));
/* Get priority marking, if any. */
if (DB_TYPE(xmit_mp) == M_DATA)
xmit_mp->b_band = mp->b_band;
@@ -24738,9 +24785,11 @@
/*
* Copy the header plus those options which have the copy bit set
+ * src is the template to make sure we preserve the cred for TX purposes.
*/
static mblk_t *
-ip_wput_frag_copyhdr(uchar_t *rptr, int hdr_len, int offset, ip_stack_t *ipst)
+ip_wput_frag_copyhdr(uchar_t *rptr, int hdr_len, int offset, ip_stack_t *ipst,
+ mblk_t *src)
{
mblk_t *mp;
uchar_t *up;
@@ -24749,7 +24798,7 @@
* Quick check if we need to look for options without the copy bit
* set
*/
- mp = allocb(ipst->ips_ip_wroff_extra + hdr_len, BPRI_HI);
+ mp = allocb_tmpl(ipst->ips_ip_wroff_extra + hdr_len, src);
if (!mp)
return (mp);
mp->b_rptr += ipst->ips_ip_wroff_extra;
@@ -25364,15 +25413,6 @@
mp1->b_band = mp->b_band;
mp1->b_cont = mp;
/*
- * certain system generated traffic may not
- * have cred/label in ip header block. This
- * is true even for a labeled system. But for
- * labeled traffic, inherit the label in the
- * new header.
- */
- if (DB_CRED(mp) != NULL)
- mblk_setcred(mp1, DB_CRED(mp));
- /*
* XXX disable ICK_VALID and compute checksum
* here; can happen if nce_fp_mp changes and
* it can't be copied now due to insufficient
@@ -25392,15 +25432,6 @@
}
UNLOCK_IRE_FP_MP(ire);
mp1->b_cont = mp;
- /*
- * certain system generated traffic may not
- * have cred/label in ip header block. This
- * is true even for a labeled system. But for
- * labeled traffic, inherit the label in the
- * new header.
- */
- if (DB_CRED(mp) != NULL)
- mblk_setcred(mp1, DB_CRED(mp));
if (!qos_done && (proc != 0) && IPP_ENABLED(proc, ipst)) {
ip_process(proc, &mp1, ill_index);
if (mp1 == NULL)
@@ -25490,7 +25521,7 @@
ire = ire_arg;
} else {
ire = ire_ctable_lookup_v6(v6dstp, 0, 0, ipif,
- zoneid, MBLK_GETLABEL(mp), match_flags, ipst);
+ zoneid, msg_getlabel(mp), match_flags, ipst);
ire_need_rele = B_TRUE;
}
if (ire != NULL) {
@@ -25771,7 +25802,7 @@
* an ire to send this downstream.
*/
ire = ire_ctable_lookup(dst, 0, 0, ipif, zoneid,
- MBLK_GETLABEL(mp), match_flags, ipst);
+ msg_getlabel(mp), match_flags, ipst);
if (ire != NULL) {
ill_t *ill1;
/*
@@ -25820,7 +25851,7 @@
ire_need_rele = B_FALSE;
} else {
ire = ire_cache_lookup(dst, zoneid,
- MBLK_GETLABEL(mp), ipst);
+ msg_getlabel(mp), ipst);
}
if (ire != NULL) {
goto send;
@@ -26634,6 +26665,7 @@
opt_restart_t *or;
int err;
conn_t *connp;
+ cred_t *cr;
ASSERT(CONN_Q(q));
connp = Q_TO_CONN(q);
@@ -26641,16 +26673,18 @@
ASSERT(first_mp->b_datap->db_type == M_CTL);
or = (opt_restart_t *)first_mp->b_rptr;
/*
- * We don't need to pass any credentials here since this is just
- * a restart. The credentials are passed in when svr4_optcom_req
- * is called the first time (from ip_wput_nondata).
+ * We checked for a db_credp the first time svr4_optcom_req
+ * was called (from ip_wput_nondata). So we can just ASSERT here.
*/
+ cr = msg_getcred(first_mp, NULL);
+ ASSERT(cr != NULL);
+
if (or->or_type == T_SVR4_OPTMGMT_REQ) {
- err = svr4_optcom_req(q, first_mp, NULL,
+ err = svr4_optcom_req(q, first_mp, cr,
&ip_opt_obj, B_FALSE);
} else {
ASSERT(or->or_type == T_OPTMGMT_REQ);
- err = tpi_optcom_req(q, first_mp, NULL,
+ err = tpi_optcom_req(q, first_mp, cr,
&ip_opt_obj, B_FALSE);
}
if (err != EINPROGRESS) {
@@ -26954,8 +26988,6 @@
ipst = ILLQ_TO_IPST(q);
}
- cr = DB_CREDDEF(mp, GET_QUEUE_CRED(q));
-
switch (DB_TYPE(mp)) {
case M_IOCTL:
/*
@@ -27233,6 +27265,22 @@
goto protonak;
}
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ mp = mi_tpi_err_ack_alloc(mp, TSYSERR, EINVAL);
+ if (mp != NULL)
+ qreply(q, mp);
+ return;
+ }
+
if (!snmpcom_req(q, mp, ip_snmp_set,
ip_snmp_get, cr)) {
/*
@@ -27269,6 +27317,21 @@
goto protonak;
}
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ mp = mi_tpi_err_ack_alloc(mp, TSYSERR, EINVAL);
+ if (mp != NULL)
+ qreply(q, mp);
+ return;
+ }
ASSERT(ipsq == NULL);
/*
* We don't come here for restart. ip_restart_optmgmt
@@ -27742,7 +27805,7 @@
if (optval == IPOPT_SSRR) {
ire = ire_ftable_lookup(dst, 0, 0,
IRE_INTERFACE, NULL, NULL, ALL_ZONES, 0,
- MBLK_GETLABEL(mp),
+ msg_getlabel(mp),
MATCH_IRE_TYPE | MATCH_IRE_SECATTR, ipst);
if (ire == NULL) {
ip1dbg(("ip_wput_options: SSRR not"
diff --git a/usr/src/uts/common/inet/ip/ip6.c b/usr/src/uts/common/inet/ip/ip6.c
index eb541c9..686e2ad 100644
--- a/usr/src/uts/common/inet/ip/ip6.c
+++ b/usr/src/uts/common/inet/ip/ip6.c
@@ -192,7 +192,7 @@
static void icmp_redirect_v6(queue_t *, mblk_t *, ill_t *ill);
static int ip_bind_connected_v6(conn_t *, mblk_t **, uint8_t, in6_addr_t *,
uint16_t, const in6_addr_t *, ip6_pkt_t *, uint16_t,
- boolean_t, boolean_t);
+ boolean_t, boolean_t, cred_t *);
static boolean_t ip_bind_get_ire_v6(mblk_t **, ire_t *, const in6_addr_t *,
iulp_t *, ip_stack_t *);
static void ip_bind_post_handling_v6(conn_t *, mblk_t *, boolean_t,
@@ -1565,7 +1565,7 @@
}
msg_len = len_needed;
}
- mp1 = allocb_cred(IPV6_HDR_LEN + len, DB_CRED(mp));
+ mp1 = allocb_tmpl(IPV6_HDR_LEN + len, mp);
if (mp1 == NULL) {
BUMP_MIB(ill->ill_icmp6_mib, ipv6IfIcmpOutErrors);
freemsg(ipsec_mp);
@@ -1992,6 +1992,21 @@
ipa6_conn_x_t *acx6;
boolean_t verify_dst;
ip_stack_t *ipst = connp->conn_netstack->netstack_ip;
+ cred_t *cr;
+
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ error = EINVAL;
+ goto bad_addr;
+ }
ASSERT(connp->conn_af_isv6);
len = mp->b_wptr - mp->b_rptr;
@@ -2118,7 +2133,7 @@
v6srcp, lport, tbr->ADDR_length != IPV6_ADDR_LEN);
} else {
error = ip_proto_bind_connected_v6(connp, &mp->b_cont, protocol,
- v6srcp, lport, v6dstp, ipp, fport, B_TRUE, verify_dst);
+ v6srcp, lport, v6dstp, ipp, fport, B_TRUE, verify_dst, cr);
}
if (error == 0) {
@@ -2418,7 +2433,7 @@
ip_bind_connected_v6(conn_t *connp, mblk_t **mpp, uint8_t protocol,
in6_addr_t *v6src, uint16_t lport, const in6_addr_t *v6dst,
ip6_pkt_t *ipp, uint16_t fport, boolean_t fanout_insert,
- boolean_t verify_dst)
+ boolean_t verify_dst, cred_t *cr)
{
ire_t *src_ire;
ire_t *dst_ire;
@@ -2442,8 +2457,9 @@
if (mp != NULL) {
ire_requested = (DB_TYPE(mp) == IRE_DB_REQ_TYPE);
ipsec_policy_set = (DB_TYPE(mp) == IPSEC_POLICY_SET);
- tsl = MBLK_GETLABEL(mp);
}
+ if (cr != NULL)
+ tsl = crgetlabel(cr);
src_ire = dst_ire = NULL;
/*
@@ -2546,8 +2562,8 @@
*/
if (dst_ire != NULL && is_system_labeled() &&
!IPCL_IS_TCP(connp) &&
- tsol_compute_label_v6(DB_CREDDEF(mp, connp->conn_cred),
- v6dst, NULL, connp->conn_mac_exempt, ipst) != 0) {
+ tsol_compute_label_v6(cr, v6dst, NULL,
+ connp->conn_mac_exempt, ipst) != 0) {
error = EHOSTUNREACH;
if (ip_debug > 2) {
pr_addr_dbg("ip_bind_connected: no label for dst %s\n",
@@ -2874,7 +2890,7 @@
ip_proto_bind_connected_v6(conn_t *connp, mblk_t **mpp, uint8_t protocol,
in6_addr_t *v6srcp, uint16_t lport, const in6_addr_t *v6dstp,
ip6_pkt_t *ipp, uint16_t fport, boolean_t fanout_insert,
- boolean_t verify_dst)
+ boolean_t verify_dst, cred_t *cr)
{
int error = 0;
boolean_t orig_pkt_isv6 = connp->conn_pkt_isv6;
@@ -2917,7 +2933,7 @@
/* Always verify destination reachability. */
error = ip_bind_connected_v4(connp, mpp, protocol, &v4src,
- lport, v4dst, fport, B_TRUE, B_TRUE);
+ lport, v4dst, fport, B_TRUE, B_TRUE, cr);
if (error != 0)
goto bad_addr;
IN6_IPADDR_TO_V4MAPPED(v4src, v6srcp);
@@ -2928,7 +2944,7 @@
goto bad_addr;
} else {
error = ip_bind_connected_v6(connp, mpp, protocol, v6srcp,
- lport, v6dstp, ipp, fport, B_TRUE, verify_dst);
+ lport, v6dstp, ipp, fport, B_TRUE, verify_dst, cr);
if (error != 0)
goto bad_addr;
connp->conn_pkt_isv6 = B_TRUE;
@@ -4290,7 +4306,7 @@
match_flags = MATCH_IRE_RECURSIVE | MATCH_IRE_DEFAULT |
MATCH_IRE_PARENT | MATCH_IRE_RJ_BHOLE | MATCH_IRE_SECATTR;
ire = ire_ftable_lookup_v6(v6dstp, 0, 0, 0,
- NULL, &sire, zoneid, 0, MBLK_GETLABEL(mp),
+ NULL, &sire, zoneid, 0, msg_getlabel(mp),
match_flags, ipst);
} else {
match_flags = MATCH_IRE_RECURSIVE | MATCH_IRE_DEFAULT |
@@ -4311,7 +4327,7 @@
}
ire = ire_ftable_lookup_v6(v6dstp, NULL, NULL, 0, ill->ill_ipif,
- &sire, zoneid, 0, MBLK_GETLABEL(mp), match_flags, ipst);
+ &sire, zoneid, 0, msg_getlabel(mp), match_flags, ipst);
}
ip3dbg(("ip_newroute_v6: ire_ftable_lookup_v6() "
@@ -4346,7 +4362,7 @@
* the destination contained in sire.
*/
multirt_is_resolvable = ire_multirt_lookup_v6(&ire,
- &sire, multirt_flags, MBLK_GETLABEL(mp), ipst);
+ &sire, multirt_flags, msg_getlabel(mp), ipst);
ip3dbg(("ip_newroute_v6: multirt_is_resolvable %d, "
"ire %p, sire %p\n",
@@ -5773,7 +5789,7 @@
if (copy_mp != NULL) {
boolean_t need_resolve =
ire_multirt_need_resolve_v6(v6dstp,
- MBLK_GETLABEL(copy_mp), ipst);
+ msg_getlabel(copy_mp), ipst);
if (!need_resolve) {
MULTIRT_DEBUG_UNTAG(copy_mp);
freemsg(copy_mp);
@@ -5902,7 +5918,7 @@
if (copy_mp != NULL) {
boolean_t need_resolve =
ire_multirt_need_resolve_v6(v6dstp,
- MBLK_GETLABEL(copy_mp), ipst);
+ msg_getlabel(copy_mp), ipst);
if (!need_resolve) {
MULTIRT_DEBUG_UNTAG(copy_mp);
freemsg(copy_mp);
@@ -5980,7 +5996,7 @@
if (copy_mp != NULL) {
boolean_t need_resolve =
ire_multirt_need_resolve_v6(v6dstp,
- MBLK_GETLABEL(copy_mp), ipst);
+ msg_getlabel(copy_mp), ipst);
if (!need_resolve) {
MULTIRT_DEBUG_UNTAG(copy_mp);
freemsg(copy_mp);
@@ -7212,7 +7228,7 @@
MATCH_IRE_TYPE | MATCH_IRE_ILL, ipst);
} else {
ire = ire_cache_lookup_v6(&ip6h->ip6_dst, ALL_ZONES,
- MBLK_GETLABEL(mp), ipst);
+ msg_getlabel(mp), ipst);
if (ire != NULL && ire->ire_stq != NULL &&
ire->ire_zoneid != GLOBAL_ZONEID &&
@@ -7223,7 +7239,7 @@
*/
ire_refrele(ire);
ire = ire_cache_lookup_v6(&ip6h->ip6_dst,
- GLOBAL_ZONEID, MBLK_GETLABEL(mp), ipst);
+ GLOBAL_ZONEID, msg_getlabel(mp), ipst);
}
}
@@ -9229,13 +9245,14 @@
if (is_system_labeled() && DB_TYPE(mp) == M_DATA &&
(connp == NULL || !connp->conn_ulp_labeled)) {
+ cred_t *cr;
+
if (connp != NULL) {
ASSERT(CONN_CRED(connp) != NULL);
err = tsol_check_label_v6(BEST_CRED(mp, connp),
&mp, connp->conn_mac_exempt, ipst);
- } else if (DB_CRED(mp) != NULL) {
- err = tsol_check_label_v6(DB_CRED(mp),
- &mp, B_FALSE, ipst);
+ } else if ((cr = msg_getcred(mp, NULL)) != NULL) {
+ err = tsol_check_label_v6(cr, &mp, B_FALSE, ipst);
}
if (mctl_present)
first_mp->b_cont = mp;
@@ -9452,7 +9469,7 @@
}
}
if (ip6i->ip6i_flags & IP6I_VERIFY_SRC) {
- cred_t *cr = DB_CREDDEF(mp, GET_QUEUE_CRED(q));
+ cred_t *cr = msg_getcred(mp, NULL);
ASSERT(!IN6_IS_ADDR_UNSPECIFIED(&ip6h->ip6_src));
if (secpolicy_net_rawaccess(cr) != 0) {
@@ -9570,7 +9587,7 @@
* as it does not really have a real destination to
* talk to.
*/
- ire = ire_cache_lookup_v6(v6dstp, zoneid, MBLK_GETLABEL(mp),
+ ire = ire_cache_lookup_v6(v6dstp, zoneid, msg_getlabel(mp),
ipst);
} else {
/*
@@ -9598,7 +9615,7 @@
IRE_REFRELE_NOTR(ire);
ire = ire_cache_lookup_v6(v6dstp, zoneid,
- MBLK_GETLABEL(mp), ipst);
+ msg_getlabel(mp), ipst);
if (ire != NULL) {
IRE_REFHOLD_NOTR(ire);
@@ -9677,7 +9694,7 @@
*/
multirt_need_resolve =
ire_multirt_need_resolve_v6(&ire->ire_addr_v6,
- MBLK_GETLABEL(first_mp), ipst);
+ msg_getlabel(first_mp), ipst);
ip2dbg(("ip_wput_v6: ire %p, "
"multirt_need_resolve %d, first_mp %p\n",
(void *)ire, multirt_need_resolve,
@@ -10040,7 +10057,7 @@
* It is used only when ire_cache_lookup is used above.
*/
ire = ire_ctable_lookup_v6(v6dstp, 0, 0, ill->ill_ipif,
- zoneid, MBLK_GETLABEL(mp), match_flags, ipst);
+ zoneid, msg_getlabel(mp), match_flags, ipst);
if (ire != NULL) {
/*
* Check if the ire has the RTF_MULTIRT flag, inherited
@@ -10080,7 +10097,7 @@
*/
multirt_need_resolve =
ire_multirt_need_resolve_v6(&ire->ire_addr_v6,
- MBLK_GETLABEL(first_mp), ipst);
+ msg_getlabel(first_mp), ipst);
ip2dbg(("ip_wput_v6[send_from_ill]: ire %p, "
"multirt_need_resolve %d, first_mp %p\n",
(void *)ire, multirt_need_resolve,
@@ -11510,8 +11527,8 @@
* fragment header. This (or a copy) will be used as the
* first mblk for each fragment we send.
*/
- hmp = allocb(unfragmentable_len + sizeof (ip6_frag_t) +
- ipst->ips_ip_wroff_extra, BPRI_HI);
+ hmp = allocb_tmpl(unfragmentable_len + sizeof (ip6_frag_t) +
+ ipst->ips_ip_wroff_extra, mp);
if (hmp == NULL) {
BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutFragFails);
freemsg(mp);
diff --git a/usr/src/uts/common/inet/ip/ip_ftable.c b/usr/src/uts/common/inet/ip/ip_ftable.c
index e03b358..77da022 100644
--- a/usr/src/uts/common/inet/ip/ip_ftable.c
+++ b/usr/src/uts/common/inet/ip/ip_ftable.c
@@ -1676,7 +1676,7 @@
match_flags = (MATCH_IRE_DSTONLY | MATCH_IRE_DEFAULT |
MATCH_IRE_RECURSIVE | MATCH_IRE_RJ_BHOLE);
ire = ire_route_lookup(dst,
- 0, 0, 0, NULL, &sire, zoneid, MBLK_GETLABEL(mp),
+ 0, 0, 0, NULL, &sire, zoneid, msg_getlabel(mp),
match_flags, ipst);
} else {
ipif_t *supplied_ipif;
@@ -1704,7 +1704,7 @@
}
ire = ire_route_lookup(dst, 0, 0, 0, supplied_ipif,
- &sire, zoneid, MBLK_GETLABEL(mp), match_flags, ipst);
+ &sire, zoneid, msg_getlabel(mp), match_flags, ipst);
ipif_refrele(supplied_ipif);
ill_refrele(ill);
}
@@ -1763,7 +1763,7 @@
* to the ire cache table
*/
ire_cache = ire_forward(dst, &ret_action, ire, sire,
- MBLK_GETLABEL(mp), ipst);
+ msg_getlabel(mp), ipst);
if (ire_cache == NULL) {
ip1dbg(("ipfil_sendpkt: failed to create the"
" ire cache entry \n"));
diff --git a/usr/src/uts/common/inet/ip/ip_helper_stream.c b/usr/src/uts/common/inet/ip/ip_helper_stream.c
index a3ff2b5..6f5608e 100644
--- a/usr/src/uts/common/inet/ip/ip_helper_stream.c
+++ b/usr/src/uts/common/inet/ip/ip_helper_stream.c
@@ -321,7 +321,8 @@
mblk_t *mp;
size = sizeof (struct T_optmgmt_req) + sizeof (struct opthdr) + optlen;
- mp = allocb_cred(size, cr);
+ /* Not used to generate UCRED, thus don't need correct pid */
+ mp = allocb_cred(size, cr, NOPID);
if (mp == NULL)
return (ENOMEM);
diff --git a/usr/src/uts/common/inet/ip/ip_if.c b/usr/src/uts/common/inet/ip/ip_if.c
index 1fd00aa..64f9789 100644
--- a/usr/src/uts/common/inet/ip/ip_if.c
+++ b/usr/src/uts/common/inet/ip/ip_if.c
@@ -34,6 +34,7 @@
#include <sys/stropts.h>
#include <sys/strsun.h>
#include <sys/sysmacros.h>
+#include <sys/strsubr.h>
#include <sys/strlog.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
@@ -10220,7 +10221,9 @@
* the framework; the caller of ioctl needs to hold the reference
* for the duration of the call).
*/
- cr = DB_CREDDEF(mp, iocp->ioc_cr);
+ cr = msg_getcred(mp, NULL);
+ if (cr == NULL)
+ cr = iocp->ioc_cr;
/* Make sure normal users don't send down privileged ioctls */
if ((ipip->ipi_flags & IPI_PRIV) &&
@@ -12952,7 +12955,9 @@
* prefer credential from mblk over ioctl;
* see ip_sioctl_copyin_setup
*/
- cr = DB_CREDDEF(mp, iocp->ioc_cr);
+ cr = msg_getcred(mp, NULL);
+ if (cr == NULL)
+ cr = iocp->ioc_cr;
/*
* Refhold the conn in case the request gets queued up in some lookup
diff --git a/usr/src/uts/common/inet/ip/ip_ire.c b/usr/src/uts/common/inet/ip/ip_ire.c
index 40e0989..5113405 100644
--- a/usr/src/uts/common/inet/ip/ip_ire.c
+++ b/usr/src/uts/common/inet/ip/ip_ire.c
@@ -32,6 +32,7 @@
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/strsun.h>
+#include <sys/strsubr.h>
#include <sys/ddi.h>
#include <sys/cmn_err.h>
#include <sys/policy.h>
@@ -1255,12 +1256,12 @@
if (ire->ire_ipversion == IPV4_VERSION) {
ipha = (ipha_t *)data_mp->b_rptr;
dst_ire = ire_cache_lookup(ipha->ipha_dst,
- ire->ire_zoneid, MBLK_GETLABEL(mp), ipst);
+ ire->ire_zoneid, msg_getlabel(mp), ipst);
} else {
ASSERT(ire->ire_ipversion == IPV6_VERSION);
ip6h = (ip6_t *)data_mp->b_rptr;
dst_ire = ire_cache_lookup_v6(&ip6h->ip6_dst,
- ire->ire_zoneid, MBLK_GETLABEL(mp), ipst);
+ ire->ire_zoneid, msg_getlabel(mp), ipst);
}
if (dst_ire != NULL) {
if (dst_ire->ire_flags & RTF_MULTIRT) {
diff --git a/usr/src/uts/common/inet/ip/ip_multi.c b/usr/src/uts/common/inet/ip/ip_multi.c
index cbea9be..656080b 100644
--- a/usr/src/uts/common/inet/ip/ip_multi.c
+++ b/usr/src/uts/common/inet/ip/ip_multi.c
@@ -1241,12 +1241,15 @@
if (((mp = allocb(hdrsz, BPRI_MED)) != NULL) &&
(mp_orig = dupmsg(mp_orig)) != NULL) {
+ cred_t *cr;
+
bcopy(mp_orig->b_rptr, mp->b_rptr, hdrsz);
mp->b_wptr += hdrsz;
mp->b_cont = mp_orig;
mp_orig->b_rptr += hdrsz;
- if (is_system_labeled() && DB_CRED(mp_orig) != NULL)
- mblk_setcred(mp, DB_CRED(mp_orig));
+ if (is_system_labeled() &&
+ (cr = msg_getcred(mp_orig, NULL)) != NULL)
+ mblk_setcred(mp, cr, NOPID);
if (MBLKL(mp_orig) == 0) {
mp->b_cont = mp_orig->b_cont;
mp_orig->b_cont = NULL;
diff --git a/usr/src/uts/common/inet/ip/ip_rts.c b/usr/src/uts/common/inet/ip/ip_rts.c
index 77ab2cc..ca39678 100644
--- a/usr/src/uts/common/inet/ip/ip_rts.c
+++ b/usr/src/uts/common/inet/ip/ip_rts.c
@@ -46,6 +46,7 @@
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/ddi.h>
+#include <sys/strsubr.h>
#include <sys/cmn_err.h>
#include <sys/debug.h>
#include <sys/policy.h>
@@ -233,7 +234,7 @@
static void
ip_rts_request_retry(ipsq_t *dummy_sq, queue_t *q, mblk_t *mp, void *dummy)
{
- (void) ip_rts_request(q, mp, DB_CRED(mp));
+ (void) ip_rts_request(q, mp, msg_getcred(mp, NULL));
}
/*
diff --git a/usr/src/uts/common/inet/ip/ipclassifier.c b/usr/src/uts/common/inet/ip/ipclassifier.c
index 5afa701..0aafd8e 100644
--- a/usr/src/uts/common/inet/ip/ipclassifier.c
+++ b/usr/src/uts/common/inet/ip/ipclassifier.c
@@ -672,10 +672,10 @@
DTRACE_PROBE1(conn__destroy, conn_t *, connp);
- if (connp->conn_peercred != NULL &&
- connp->conn_peercred != connp->conn_cred)
+ if (connp->conn_peercred != NULL) {
crfree(connp->conn_peercred);
- connp->conn_peercred = NULL;
+ connp->conn_peercred = NULL;
+ }
if (connp->conn_cred != NULL) {
crfree(connp->conn_cred);
@@ -1568,9 +1568,12 @@
lport = up[1];
unlabeled = B_FALSE;
/* Cred cannot be null on IPv4 */
- if (is_system_labeled())
- unlabeled = (crgetlabel(DB_CRED(mp))->tsl_flags &
+ if (is_system_labeled()) {
+ cred_t *cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ unlabeled = (crgetlabel(cr)->tsl_flags &
TSLF_UNLABELED) != 0;
+ }
shared_addr = (zoneid == ALL_ZONES);
if (shared_addr) {
/*
@@ -1640,9 +1643,12 @@
lport = up[1];
unlabeled = B_FALSE;
/* Cred cannot be null on IPv4 */
- if (is_system_labeled())
- unlabeled = (crgetlabel(DB_CRED(mp))->tsl_flags &
+ if (is_system_labeled()) {
+ cred_t *cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ unlabeled = (crgetlabel(cr)->tsl_flags &
TSLF_UNLABELED) != 0;
+ }
shared_addr = (zoneid == ALL_ZONES);
if (shared_addr) {
/*
@@ -1761,7 +1767,7 @@
unlabeled = B_FALSE;
/* Cred can be null on IPv6 */
if (is_system_labeled()) {
- cred_t *cr = DB_CRED(mp);
+ cred_t *cr = msg_getcred(mp, NULL);
unlabeled = (cr != NULL &&
crgetlabel(cr)->tsl_flags & TSLF_UNLABELED) != 0;
@@ -1834,7 +1840,7 @@
unlabeled = B_FALSE;
/* Cred can be null on IPv6 */
if (is_system_labeled()) {
- cred_t *cr = DB_CRED(mp);
+ cred_t *cr = msg_getcred(mp, NULL);
unlabeled = (cr != NULL &&
crgetlabel(cr)->tsl_flags & TSLF_UNLABELED) != 0;
@@ -1951,7 +1957,7 @@
unlabeled = B_FALSE;
/* Cred can be null on IPv6 */
if (is_system_labeled()) {
- cred_t *cr = DB_CRED(mp);
+ cred_t *cr = msg_getcred(mp, NULL);
unlabeled = (cr != NULL &&
crgetlabel(cr)->tsl_flags & TSLF_UNLABELED) != 0;
diff --git a/usr/src/uts/common/inet/ip/ipsecah.c b/usr/src/uts/common/inet/ip/ipsecah.c
index 65199df..7782f62 100644
--- a/usr/src/uts/common/inet/ip/ipsecah.c
+++ b/usr/src/uts/common/inet/ip/ipsecah.c
@@ -3060,8 +3060,7 @@
return (NULL);
}
- if ((phdr_mp = allocb_cred(hdr_size + ah_data_sz,
- DB_CRED(mp))) == NULL) {
+ if ((phdr_mp = allocb_tmpl(hdr_size + ah_data_sz, mp)) == NULL) {
return (NULL);
}
@@ -3192,7 +3191,7 @@
size += option_length;
}
- if ((phdr_mp = allocb_cred(size, DB_CRED(mp))) == NULL) {
+ if ((phdr_mp = allocb_tmpl(size, mp)) == NULL) {
return (NULL);
}
@@ -4235,6 +4234,11 @@
while (--dest >= mp->b_rptr)
*dest = *(dest - newpos);
}
+ /*
+ * The db_credp should be in mp (if needed) and never in phdr_mp
+ */
+ ASSERT(msg_getcred(phdr_mp, NULL) == NULL);
+
freeb(phdr_mp);
ipsec_in->b_cont = mp;
if (assoc->ipsa_state == IPSA_STATE_IDLE) {
diff --git a/usr/src/uts/common/inet/ip/keysock.c b/usr/src/uts/common/inet/ip/keysock.c
index 67a21f6..ca82eee 100644
--- a/usr/src/uts/common/inet/ip/keysock.c
+++ b/usr/src/uts/common/inet/ip/keysock.c
@@ -912,10 +912,6 @@
freemsg(mp);
return;
}
- cr = zone_get_kcred(netstackid_to_zoneid(
- keystack->keystack_netstack->netstack_stackid));
- ASSERT(cr != NULL);
-
switch (((union T_primitives *)mp->b_rptr)->type) {
case T_CAPABILITY_REQ:
keysock_capability_req(q, mp);
@@ -924,12 +920,28 @@
keysock_info_req(q, mp);
break;
case T_SVR4_OPTMGMT_REQ:
- (void) svr4_optcom_req(q, mp, DB_CREDDEF(mp, cr),
- &keysock_opt_obj, B_FALSE);
- break;
case T_OPTMGMT_REQ:
- (void) tpi_optcom_req(q, mp, DB_CREDDEF(mp, cr),
- &keysock_opt_obj, B_FALSE);
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ keysock_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
+ if (((union T_primitives *)mp->b_rptr)->type ==
+ T_SVR4_OPTMGMT_REQ) {
+ (void) svr4_optcom_req(q, mp, cr,
+ &keysock_opt_obj, B_FALSE);
+ } else {
+ (void) tpi_optcom_req(q, mp, cr,
+ &keysock_opt_obj, B_FALSE);
+ }
break;
case T_DATA_REQ:
case T_EXDATA_REQ:
@@ -943,7 +955,6 @@
keysock_err_ack(q, mp, TNOTSUPPORT, 0);
break;
}
- crfree(cr);
return;
case M_IOCTL:
iocp = (struct iocblk *)mp->b_rptr;
diff --git a/usr/src/uts/common/inet/ip/rts.c b/usr/src/uts/common/inet/ip/rts.c
index 0bc00f6..ce3ac6f 100644
--- a/usr/src/uts/common/inet/ip/rts.c
+++ b/usr/src/uts/common/inet/ip/rts.c
@@ -114,7 +114,7 @@
static void rts_err_ack(queue_t *q, mblk_t *mp, t_scalar_t t_error,
int sys_error);
static void rts_input(void *, mblk_t *, void *);
-static mblk_t *rts_ioctl_alloc(mblk_t *data, cred_t *cr);
+static mblk_t *rts_ioctl_alloc(mblk_t *data);
static int rts_param_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr);
static boolean_t rts_param_register(IDP *ndp, rtsparam_t *rtspa, int cnt);
static int rts_param_set(queue_t *q, mblk_t *mp, char *value, caddr_t cp,
@@ -159,17 +159,17 @@
* user data.
*/
static mblk_t *
-rts_ioctl_alloc(mblk_t *data, cred_t *cr)
+rts_ioctl_alloc(mblk_t *data)
{
mblk_t *mp = NULL;
mblk_t *mp1 = NULL;
ipllc_t *ipllc;
struct iocblk *ioc;
- mp = allocb_cred(sizeof (ipllc_t), cr);
+ mp = allocb_tmpl(sizeof (ipllc_t), data);
if (mp == NULL)
return (NULL);
- mp1 = allocb_cred(sizeof (struct iocblk), cr);
+ mp1 = allocb_tmpl(sizeof (struct iocblk), data);
if (mp1 == NULL) {
freeb(mp);
return (NULL);
@@ -1045,7 +1045,9 @@
}
- mp1 = rts_ioctl_alloc(mp, DB_CRED(mp));
+ ASSERT(msg_getcred(mp, NULL) != NULL);
+
+ mp1 = rts_ioctl_alloc(mp);
if (mp1 == NULL) {
ASSERT(rts != NULL);
freemsg(mp);
@@ -1076,8 +1078,6 @@
rtss = rts->rts_rtss;
- cr = DB_CREDDEF(mp, connp->conn_cred);
-
switch (mp->b_datap->db_type) {
case M_PROTO:
case M_PCPROTO:
@@ -1104,11 +1104,28 @@
rts_info_req(q, mp);
return;
case T_SVR4_OPTMGMT_REQ:
- (void) svr4_optcom_req(q, mp, cr, &rts_opt_obj,
- B_TRUE);
- return;
case T_OPTMGMT_REQ:
- (void) tpi_optcom_req(q, mp, cr, &rts_opt_obj, B_TRUE);
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ rts_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
+ if (((union T_primitives *)rptr)->type ==
+ T_SVR4_OPTMGMT_REQ) {
+ (void) svr4_optcom_req(q, mp, cr,
+ &rts_opt_obj, B_TRUE);
+ } else {
+ (void) tpi_optcom_req(q, mp, cr,
+ &rts_opt_obj, B_TRUE);
+ }
return;
case O_T_CONN_RES:
case T_CONN_RES:
@@ -1537,7 +1554,7 @@
rtm = (rt_msghdr_t *)mp->b_rptr;
rtm->rtm_pid = curproc->p_pid;
- mp1 = rts_ioctl_alloc(mp, DB_CRED(mp));
+ mp1 = rts_ioctl_alloc(mp);
if (mp1 == NULL) {
ASSERT(rts != NULL);
freemsg(mp);
@@ -1567,8 +1584,7 @@
CONN_INC_REF(connp);
- error = ip_rts_request_common(rts->rts_connp->conn_wq, mp1, connp,
- DB_CREDDEF(mp, connp->conn_cred));
+ error = ip_rts_request_common(rts->rts_connp->conn_wq, mp1, connp, cr);
mutex_enter(&rts->rts_send_mutex);
if (error == EINPROGRESS) {
diff --git a/usr/src/uts/common/inet/ip/sadb.c b/usr/src/uts/common/inet/ip/sadb.c
index 189b6ad..eff4dfc 100644
--- a/usr/src/uts/common/inet/ip/sadb.c
+++ b/usr/src/uts/common/inet/ip/sadb.c
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/stropts.h>
+#include <sys/strsubr.h>
#include <sys/errno.h>
#include <sys/ddi.h>
#include <sys/debug.h>
@@ -6175,7 +6176,7 @@
struct T_bind_req *tbr;
mblk_t *mp;
- mp = allocb(sizeof (struct T_bind_req) + 1, BPRI_HI);
+ mp = allocb_cred(sizeof (struct T_bind_req) + 1, kcred, NOPID);
if (mp == NULL) {
/* cmn_err(CE_WARN, */
/* "sadb_t_bind_req(%d): couldn't allocate mblk\n", proto); */
diff --git a/usr/src/uts/common/inet/ip/spdsock.c b/usr/src/uts/common/inet/ip/spdsock.c
index 749db40..a0e63ac 100644
--- a/usr/src/uts/common/inet/ip/spdsock.c
+++ b/usr/src/uts/common/inet/ip/spdsock.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -591,10 +591,13 @@
spdsock_flush_one(iph, ns);
if (audit_active) {
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_FLUSH, DB_CRED(mp), ns,
- ITP_NAME(itp), active, 0, DB_CPID(mp));
+ audit_pf_policy(SPD_FLUSH, cr, ns,
+ ITP_NAME(itp), active, 0, cpid);
}
} else {
active = (iph == ALL_ACTIVE_POLHEADS);
@@ -603,14 +606,23 @@
spdsock_flush_one(active ? ipsec_system_policy(ns) :
ipsec_inactive_policy(ns), ns);
if (audit_active) {
- audit_pf_policy(SPD_FLUSH, DB_CRED(mp), ns, NULL,
- active, 0, DB_CPID(mp));
+ cred_t *cr;
+ pid_t cpid;
+
+ cr = msg_getcred(mp, &cpid);
+ audit_pf_policy(SPD_FLUSH, cr, ns, NULL,
+ active, 0, cpid);
}
/* Then flush every tunnel's appropriate one. */
itp_walk(spdsock_flush_node, (void *)active, ns);
- if (audit_active)
- audit_pf_policy(SPD_FLUSH, DB_CRED(mp), ns,
- "all tunnels", active, 0, DB_CPID(mp));
+ if (audit_active) {
+ cred_t *cr;
+ pid_t cpid;
+
+ cr = msg_getcred(mp, &cpid);
+ audit_pf_policy(SPD_FLUSH, cr, ns,
+ "all tunnels", active, 0, cpid);
+ }
}
spd_echo(q, mp);
@@ -1014,11 +1026,14 @@
spdsock_diag(q, mp, SPD_DIAGNOSTIC_NO_RULE_EXT);
if (audit_active) {
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_ADDRULE, DB_CRED(mp),
+ audit_pf_policy(SPD_ADDRULE, cr,
spds->spds_netstack, ITP_NAME(itp), active,
- SPD_DIAGNOSTIC_NO_RULE_EXT, DB_CPID(mp));
+ SPD_DIAGNOSTIC_NO_RULE_EXT, cpid);
}
return;
}
@@ -1121,10 +1136,13 @@
spd_echo(q, mp);
if (audit_active) {
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_ADDRULE, DB_CRED(mp), spds->spds_netstack,
- ITP_NAME(itp), active, 0, DB_CPID(mp));
+ audit_pf_policy(SPD_ADDRULE, cr, spds->spds_netstack,
+ ITP_NAME(itp), active, 0, cpid);
}
return;
@@ -1143,10 +1161,13 @@
spdsock_error(q, mp, error, diag);
if (audit_active) {
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_ADDRULE, DB_CRED(mp), spds->spds_netstack,
- ITP_NAME(itp), active, error, DB_CPID(mp));
+ audit_pf_policy(SPD_ADDRULE, cr, spds->spds_netstack,
+ ITP_NAME(itp), active, error, cpid);
}
}
@@ -1165,11 +1186,14 @@
if (audit_active) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_DELETERULE, DB_CRED(mp), ns,
+ audit_pf_policy(SPD_DELETERULE, cr, ns,
ITP_NAME(itp), active, SPD_DIAGNOSTIC_NO_RULE_EXT,
- DB_CPID(mp));
+ cpid);
}
return;
}
@@ -1223,10 +1247,13 @@
if (audit_active) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_DELETERULE, DB_CRED(mp), ns, ITP_NAME(itp),
- active, 0, DB_CPID(mp));
+ audit_pf_policy(SPD_DELETERULE, cr, ns, ITP_NAME(itp),
+ active, 0, cpid);
}
return;
fail:
@@ -1236,10 +1263,13 @@
if (audit_active) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_DELETERULE, DB_CRED(mp), ns, ITP_NAME(itp),
- active, err, DB_CPID(mp));
+ audit_pf_policy(SPD_DELETERULE, cr, ns, ITP_NAME(itp),
+ active, err, cpid);
}
}
@@ -1270,19 +1300,25 @@
if (audit_active) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_FLIP, DB_CRED(mp),
- ns, NULL, active, 0, DB_CPID(mp));
+ audit_pf_policy(SPD_FLIP, cr, ns,
+ NULL, active, 0, cpid);
}
itp_walk(spdsock_flip_node, NULL, ns);
if (audit_active) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_FLIP, DB_CRED(mp), ns,
- "all tunnels", active, 0, DB_CPID(mp));
+ audit_pf_policy(SPD_FLIP, cr, ns,
+ "all tunnels", active, 0, cpid);
}
} else {
itp = get_tunnel_policy(tname, ns);
@@ -1293,12 +1329,15 @@
boolean_t active;
spd_msg_t *spmsg =
(spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid ==
SPD_ACTIVE);
- audit_pf_policy(SPD_FLIP, DB_CRED(mp),
- ns, ITP_NAME(itp), active,
- ESRCH, DB_CPID(mp));
+ audit_pf_policy(SPD_FLIP, cr, ns,
+ ITP_NAME(itp), active,
+ ESRCH, cpid);
}
return;
}
@@ -1306,10 +1345,13 @@
if (audit_active) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_FLIP, DB_CRED(mp), ns,
- ITP_NAME(itp), active, 0, DB_CPID(mp));
+ audit_pf_policy(SPD_FLIP, cr, ns,
+ ITP_NAME(itp), active, 0, cpid);
}
ITP_REFRELE(itp, ns);
}
@@ -1318,10 +1360,13 @@
if (audit_active) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_FLIP, DB_CRED(mp),
- ns, NULL, active, 0, DB_CPID(mp));
+ audit_pf_policy(SPD_FLIP, cr,
+ ns, NULL, active, 0, cpid);
}
}
spd_echo(q, mp);
@@ -2059,10 +2104,13 @@
if (audit_active) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_CLONE, DB_CRED(mp), ns,
- NULL, active, error, DB_CPID(mp));
+ audit_pf_policy(SPD_CLONE, cr, ns,
+ NULL, active, error, cpid);
}
if (error == 0) {
itp_walk(spdsock_clone_node, &error, ns);
@@ -2070,12 +2118,15 @@
boolean_t active;
spd_msg_t *spmsg =
(spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid ==
SPD_ACTIVE);
- audit_pf_policy(SPD_CLONE, DB_CRED(mp),
+ audit_pf_policy(SPD_CLONE, cr,
ns, "all tunnels", active, 0,
- DB_CPID(mp));
+ cpid);
}
}
} else {
@@ -2086,12 +2137,15 @@
boolean_t active;
spd_msg_t *spmsg =
(spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid ==
SPD_ACTIVE);
- audit_pf_policy(SPD_CLONE, DB_CRED(mp),
+ audit_pf_policy(SPD_CLONE, cr,
ns, ITP_NAME(itp), active, ENOENT,
- DB_CPID(mp));
+ cpid);
}
return;
}
@@ -2100,10 +2154,13 @@
if (audit_active) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_CLONE, DB_CRED(mp), ns,
- ITP_NAME(itp), active, error, DB_CPID(mp));
+ audit_pf_policy(SPD_CLONE, cr, ns,
+ ITP_NAME(itp), active, error, cpid);
}
}
} else {
@@ -2111,10 +2168,13 @@
if (audit_active) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+ cred_t *cr;
+ pid_t cpid;
+ cr = msg_getcred(mp, &cpid);
active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
- audit_pf_policy(SPD_CLONE, DB_CRED(mp), ns, NULL,
- active, error, DB_CPID(mp));
+ audit_pf_policy(SPD_CLONE, cr, ns, NULL,
+ active, error, cpid);
}
}
@@ -2658,10 +2718,15 @@
spds->spds_mp_algs = mp;
spds->spds_algs_pending = B_TRUE;
mutex_exit(&spds->spds_alg_lock);
- if (audit_active)
- audit_pf_policy(SPD_UPDATEALGS, DB_CRED(mp),
+ if (audit_active) {
+ cred_t *cr;
+ pid_t cpid;
+
+ cr = msg_getcred(mp, &cpid);
+ audit_pf_policy(SPD_UPDATEALGS, cr,
spds->spds_netstack, NULL, B_TRUE, EAGAIN,
- DB_CPID(mp));
+ cpid);
+ }
spd_echo(q, new_mp);
} else {
/*
@@ -2674,16 +2739,26 @@
mutex_exit(&spds->spds_alg_lock);
if (diag == -1) {
spd_echo(q, mp);
- if (audit_active)
- audit_pf_policy(SPD_UPDATEALGS, DB_CRED(mp),
- spds->spds_netstack, NULL, B_TRUE, 0,
- DB_CPID(mp));
+ if (audit_active) {
+ cred_t *cr;
+ pid_t cpid;
+
+ cr = msg_getcred(mp, &cpid);
+ audit_pf_policy(SPD_UPDATEALGS, cr,
+ spds->spds_netstack, NULL, B_TRUE, 0,
+ cpid);
+ }
} else {
spdsock_diag(q, mp, diag);
- if (audit_active)
- audit_pf_policy(SPD_UPDATEALGS, DB_CRED(mp),
- spds->spds_netstack, NULL, B_TRUE, diag,
- DB_CPID(mp));
+ if (audit_active) {
+ cred_t *cr;
+ pid_t cpid;
+
+ cr = msg_getcred(mp, &cpid);
+ audit_pf_policy(SPD_UPDATEALGS, cr,
+ spds->spds_netstack, NULL, B_TRUE, diag,
+ cpid);
+ }
}
}
}
@@ -3228,10 +3303,6 @@
freemsg(mp);
return;
}
- cr = zone_get_kcred(netstackid_to_zoneid(
- spds->spds_netstack->netstack_stackid));
- ASSERT(cr != NULL);
-
switch (((union T_primitives *)mp->b_rptr)->type) {
case T_CAPABILITY_REQ:
spdsock_capability_req(q, mp);
@@ -3240,12 +3311,28 @@
spdsock_info_req(q, mp);
break;
case T_SVR4_OPTMGMT_REQ:
- (void) svr4_optcom_req(q, mp, DB_CREDDEF(mp, cr),
- &spdsock_opt_obj, B_FALSE);
- break;
case T_OPTMGMT_REQ:
- (void) tpi_optcom_req(q, mp, DB_CREDDEF(mp, cr),
- &spdsock_opt_obj, B_FALSE);
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ spdsock_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
+ if (((union T_primitives *)mp->b_rptr)->type ==
+ T_SVR4_OPTMGMT_REQ) {
+ (void) svr4_optcom_req(q, mp, cr,
+ &spdsock_opt_obj, B_FALSE);
+ } else {
+ (void) tpi_optcom_req(q, mp, cr,
+ &spdsock_opt_obj, B_FALSE);
+ }
break;
case T_DATA_REQ:
case T_EXDATA_REQ:
@@ -3259,7 +3346,6 @@
spdsock_err_ack(q, mp, TNOTSUPPORT, 0);
break;
}
- crfree(cr);
return;
case M_IOCTL:
iocp = (struct iocblk *)mp->b_rptr;
diff --git a/usr/src/uts/common/inet/ip/tn_ipopt.c b/usr/src/uts/common/inet/ip/tn_ipopt.c
index 7c6f713..c187c8c 100644
--- a/usr/src/uts/common/inet/ip/tn_ipopt.c
+++ b/usr/src/uts/common/inet/ip/tn_ipopt.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/kmem.h>
@@ -211,6 +209,8 @@
tsol_ire_gw_secattr_t *attrp;
zoneid_t zoneid, ip_zoneid;
+ ASSERT(credp != NULL);
+
if (opt_storage != NULL)
opt_storage[IPOPT_OLEN] = 0;
@@ -674,8 +674,8 @@
copylen = MBLKL(mp);
if (copylen > 256)
copylen = 256;
- new_mp = allocb_cred(hlen + copylen +
- (mp->b_rptr - mp->b_datap->db_base), DB_CRED(mp));
+ new_mp = allocb_tmpl(hlen + copylen +
+ (mp->b_rptr - mp->b_datap->db_base), mp);
if (new_mp == NULL)
return (ENOMEM);
@@ -744,6 +744,8 @@
tsol_ire_gw_secattr_t *attrp;
boolean_t compute_label;
+ ASSERT(credp != NULL);
+
if (ip6opt_ls == 0)
return (EINVAL);
@@ -1249,8 +1251,8 @@
copylen = 256;
if (copylen < hdr_len)
copylen = hdr_len;
- new_mp = allocb_cred(hlen + copylen +
- (mp->b_rptr - mp->b_datap->db_base), DB_CRED(mp));
+ new_mp = allocb_tmpl(hlen + copylen +
+ (mp->b_rptr - mp->b_datap->db_base), mp);
if (new_mp == NULL)
return (ENOMEM);
diff --git a/usr/src/uts/common/inet/ip/tnet.c b/usr/src/uts/common/inet/ip/tnet.c
index 84fce1b..57104e5 100644
--- a/usr/src/uts/common/inet/ip/tnet.c
+++ b/usr/src/uts/common/inet/ip/tnet.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/strsubr.h>
@@ -684,6 +682,8 @@
const cipso_option_t *co;
const void *src;
const ip6_t *ip6h;
+ cred_t *credp;
+ pid_t cpid;
ASSERT(DB_TYPE(mp) == M_DATA);
@@ -824,33 +824,36 @@
/* Make sure no other thread is messing with this mblk */
ASSERT(DB_REF(mp) == 1);
- if (DB_CRED(mp) == NULL) {
- DB_CRED(mp) = newcred_from_bslabel(&sl, doi, KM_NOSLEEP);
- if (DB_CRED(mp) == NULL)
+ /* Preserve db_cpid */
+ credp = msg_extractcred(mp, &cpid);
+ if (credp == NULL) {
+ credp = newcred_from_bslabel(&sl, doi, KM_NOSLEEP);
+ if (credp == NULL)
return (B_FALSE);
+ mblk_setcred(mp, credp, cpid);
} else {
cred_t *newcr;
- newcr = copycred_from_bslabel(DB_CRED(mp), &sl, doi,
+ newcr = copycred_from_bslabel(credp, &sl, doi,
KM_NOSLEEP);
+ crfree(credp);
if (newcr == NULL)
return (B_FALSE);
- crfree(DB_CRED(mp));
- DB_CRED(mp) = newcr;
+ mblk_setcred(mp, newcr, cpid);
+ credp = newcr;
}
/*
* If the source was unlabeled, then flag as such,
* while remembering that CIPSO routers add headers.
*/
- if (label_type == OPT_NONE)
- crgetlabel(DB_CRED(mp))->tsl_flags |= TSLF_UNLABELED;
- else if (label_type == OPT_CIPSO) {
+ if (label_type == OPT_NONE) {
+ crgetlabel(credp)->tsl_flags |= TSLF_UNLABELED;
+ } else if (label_type == OPT_CIPSO) {
if ((src_rhtp = find_tpc(src, version, B_FALSE)) == NULL)
return (B_FALSE);
if (src_rhtp->tpc_tp.host_type == UNLABELED)
- crgetlabel(DB_CRED(mp))->tsl_flags |=
- TSLF_UNLABELED;
+ crgetlabel(credp)->tsl_flags |= TSLF_UNLABELED;
TPC_RELE(src_rhtp);
}
@@ -882,7 +885,7 @@
* We trust that all valid paths in the code set the cred pointer when
* needed.
*/
- if ((credp = DB_CRED(mp)) == NULL)
+ if ((credp = msg_getcred(mp, NULL)) == NULL)
return (B_TRUE);
/*
@@ -1020,9 +1023,11 @@
ts_label_t *plabel = NULL;
tsol_tpc_t *src_rhtp, *dst_rhtp;
boolean_t retv;
+ cred_t *credp;
- if (DB_CRED(mp) != NULL)
- plabel = crgetlabel(DB_CRED(mp));
+ credp = msg_getcred(mp, NULL);
+ if (credp != NULL)
+ plabel = crgetlabel(credp);
/* We are bootstrapping or the internal template was never deleted */
if (plabel == NULL)
@@ -1119,6 +1124,7 @@
const ip6_t *ip6h;
boolean_t retv;
bslabel_t *pktbs;
+ cred_t *credp;
/* Caller must pull up at least the IP header */
ASSERT(MBLKL(mp) >= (IPH_HDR_VERSION(mp->b_rptr) == IPV4_VERSION ?
@@ -1127,8 +1133,9 @@
if (!tsol_strict_error)
return (B_TRUE);
- if (DB_CRED(mp) != NULL)
- plabel = crgetlabel(DB_CRED(mp));
+ credp = msg_getcred(mp, NULL);
+ if (credp != NULL)
+ plabel = crgetlabel(credp);
/* We are bootstrapping or the internal template was never deleted */
if (plabel == NULL)
@@ -1196,7 +1203,7 @@
zoneid_t
tsol_packet_to_zoneid(const mblk_t *mp)
{
- cred_t *cr = DB_CRED(mp);
+ cred_t *cr = msg_getcred(mp, NULL);
zone_t *zone;
ts_label_t *label;
@@ -1471,6 +1478,7 @@
boolean_t need_tpc_rele = B_FALSE;
ipaddr_t *gw;
ip_stack_t *ipst = ire->ire_ipst;
+ cred_t *credp;
ASSERT(ire != NULL && mp != NULL);
ASSERT(ire->ire_stq != NULL);
@@ -1517,7 +1525,7 @@
off_link = !IN6_IS_ADDR_UNSPECIFIED(&ire->ire_gateway_addr_v6);
}
- if ((tsl = MBLK_GETLABEL(mp)) == NULL)
+ if ((tsl = msg_getlabel(mp)) == NULL)
return (mp);
label_type = tsol_get_option(mp, &opt_ptr);
@@ -1669,10 +1677,12 @@
(!off_link || gw_rhtp->tpc_tp.host_type == UNLABELED))
goto keep_label;
+
+ credp = msg_getcred(mp, NULL);
if ((af == AF_INET &&
- tsol_check_label(DB_CRED(mp), &mp, B_FALSE, ipst) != 0) ||
+ tsol_check_label(credp, &mp, B_FALSE, ipst) != 0) ||
(af == AF_INET6 &&
- tsol_check_label_v6(DB_CRED(mp), &mp, B_FALSE, ipst) != 0)) {
+ tsol_check_label_v6(credp, &mp, B_FALSE, ipst) != 0)) {
mp = NULL;
goto keep_label;
}
diff --git a/usr/src/uts/common/inet/ip/tun.c b/usr/src/uts/common/inet/ip/tun.c
index 632601b..dc5af5e 100644
--- a/usr/src/uts/common/inet/ip/tun.c
+++ b/usr/src/uts/common/inet/ip/tun.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,6 +35,7 @@
#include <sys/stream.h>
#include <sys/dlpi.h>
#include <sys/stropts.h>
+#include <sys/strsubr.h>
#include <sys/strlog.h>
#include <sys/tihdr.h>
#include <sys/tiuser.h>
@@ -396,6 +397,8 @@
atp->tun_dev = *devp;
atp->tun_zoneid = zoneid;
atp->tun_netstack = ns;
+ atp->tun_cred = credp;
+ crhold(credp);
/*
* Based on the lower version of IP, initialize stuff that
@@ -429,6 +432,7 @@
atp->tun_ip6h.ip6_hops = IPV6_DEFAULT_HOPS;
} else {
netstack_rele(ns);
+ crfree(credp);
kmem_free(atp, sizeof (tun_t));
return (ENXIO);
}
@@ -449,6 +453,7 @@
} else {
/* Error. */
netstack_rele(ns);
+ crfree(credp);
kmem_free(atp, sizeof (tun_t));
return (ENXIO);
}
@@ -463,6 +468,7 @@
} else {
/* Error. */
netstack_rele(ns);
+ crfree(credp);
kmem_free(atp, sizeof (tun_t));
return (ENXIO);
}
@@ -501,6 +507,9 @@
qprocsoff(q);
+ crfree(atp->tun_cred);
+ atp->tun_cred = NULL;
+
/* NOTE: tun_rem_ppa_list() may unlink tun_itp from its AVL tree. */
if (atp->tun_stats != NULL)
tun_rem_ppa_list(atp);
@@ -4734,8 +4743,7 @@
if ((mp->b_rptr - mp->b_datap->db_base) < hdrlen) {
/* no */
- nmp = allocb_cred(hdrlen + atp->tun_extra_offset,
- DB_CRED(mp));
+ nmp = allocb_tmpl(hdrlen + atp->tun_extra_offset, mp);
if (nmp == NULL) {
atomic_add_32(&atp->tun_OutDiscard, 1);
atomic_add_32(&atp->tun_allocbfail, 1);
@@ -4779,8 +4787,7 @@
if ((mp->b_rptr - mp->b_datap->db_base) < hdrlen) {
/* no */
- nmp = allocb_cred(hdrlen + atp->tun_extra_offset,
- DB_CRED(mp));
+ nmp = allocb_tmpl(hdrlen + atp->tun_extra_offset, mp);
if (nmp == NULL) {
atomic_add_32(&atp->tun_OutDiscard, 1);
atomic_add_32(&atp->tun_allocbfail, 1);
@@ -5257,8 +5264,8 @@
if ((mp->b_rptr - mp->b_datap->db_base) < sizeof (ipha_t)) {
/* no */
- nmp = allocb_cred(sizeof (ipha_t) +
- atp->tun_extra_offset, DB_CRED(mp));
+ nmp = allocb_tmpl(sizeof (ipha_t) +
+ atp->tun_extra_offset, mp);
if (nmp == NULL) {
atomic_add_32(&atp->tun_OutDiscard, 1);
atomic_add_32(&atp->tun_allocbfail, 1);
@@ -5444,8 +5451,7 @@
if ((mp->b_rptr - mp->b_datap->db_base) < hdrlen) {
/* no */
- nmp = allocb_cred(hdrlen + atp->tun_extra_offset,
- DB_CRED(mp));
+ nmp = allocb_tmpl(hdrlen + atp->tun_extra_offset, mp);
if (nmp == NULL) {
atomic_add_32(&atp->tun_OutDiscard, 1);
atomic_add_32(&atp->tun_allocbfail, 1);
@@ -5568,6 +5574,7 @@
freeb(mp);
return (ENOMEM);
}
+ mblk_setcred(mp, atp->tun_cred, NOPID);
mp->b_cont->b_datap->db_type = IRE_DB_REQ_TYPE;
tbr = (struct T_bind_req *)mp->b_rptr;
tbr->CONIND_number = 0;
diff --git a/usr/src/uts/common/inet/ip6.h b/usr/src/uts/common/inet/ip6.h
index cc425db..5408ab9 100644
--- a/usr/src/uts/common/inet/ip6.h
+++ b/usr/src/uts/common/inet/ip6.h
@@ -392,7 +392,7 @@
const in6_addr_t *, uint16_t, boolean_t);
extern int ip_proto_bind_connected_v6(conn_t *, mblk_t **,
uint8_t, in6_addr_t *, uint16_t, const in6_addr_t *, ip6_pkt_t *,
- uint16_t, boolean_t, boolean_t);
+ uint16_t, boolean_t, boolean_t, cred_t *);
#endif /* _KERNEL */
diff --git a/usr/src/uts/common/inet/ipclassifier.h b/usr/src/uts/common/inet/ipclassifier.h
index d80123a..2ecc445 100644
--- a/usr/src/uts/common/inet/ipclassifier.h
+++ b/usr/src/uts/common/inet/ipclassifier.h
@@ -135,7 +135,6 @@
#define IPCL_IS_RTS(connp) \
((connp)->conn_flags & IPCL_RTSCONN)
-/* FIXME: Isn't it sufficient to check IPCL_IPTUN? */
#define IPCL_IS_IPTUN(connp) \
(((connp)->conn_ulp == IPPROTO_ENCAP || \
(connp)->conn_ulp == IPPROTO_IPV6) && \
@@ -316,7 +315,7 @@
in6_addr_t conn_nexthop_v6; /* nexthop IP address */
uchar_t conn_broadcast_ttl; /* IP_BROADCAST_TTL */
#define conn_nexthop_v4 V4_PART_OF_V6(conn_nexthop_v6)
- cred_t *conn_peercred; /* Peer credentials, if any */
+ cred_t *conn_peercred; /* Peer TX label, if any */
int conn_rtaware; /* RT_AWARE sockopt value */
kcondvar_t conn_sq_cv; /* For non-STREAMS socket IO */
kthread_t *conn_sq_caller; /* Caller of squeue sync ops */
@@ -341,10 +340,17 @@
#endif
};
+/*
+ * These two macros are used by TX. First priority is SCM_UCRED having
+ * set the label in the mblk. Second priority is the peers label (aka
+ * conn_peercred). Last priority is the open credentials.
+ * BEST_CRED takes all three into account in the above order.
+ * CONN_CRED is for connection-oriented cases when we don't need to look
+ * at the mblk.
+ */
#define CONN_CRED(connp) ((connp)->conn_peercred == NULL ? \
(connp)->conn_cred : (connp)->conn_peercred)
-#define BEST_CRED(mp, connp) ((DB_CRED(mp) != NULL && \
- crgetlabel(DB_CRED(mp)) != NULL) ? DB_CRED(mp) : CONN_CRED(connp))
+#define BEST_CRED(mp, connp) ip_best_cred(mp, connp)
/*
* connf_t - connection fanout data.
diff --git a/usr/src/uts/common/inet/optcom.c b/usr/src/uts/common/inet/optcom.c
index f241599..e35b7f6 100644
--- a/usr/src/uts/common/inet/optcom.c
+++ b/usr/src/uts/common/inet/optcom.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1990 Mentat Inc. */
@@ -444,7 +444,7 @@
*/
max_optbuf_len = optcom_max_optbuf_len(opt_arr,
opt_arr_cnt);
- mp1 = allocb_cred(max_optbuf_len, cr);
+ mp1 = allocb_tmpl(max_optbuf_len, mp);
if (!mp1)
goto no_mem;
/* Initialize the header. */
@@ -694,7 +694,7 @@
* the operation.
*/
- toa_mp = allocb_cred(toa_len, cr);
+ toa_mp = allocb_tmpl(toa_len, mp);
if (!toa_mp) {
optcom_err_ack(q, mp, TSYSERR, ENOMEM);
return (0);
@@ -2210,7 +2210,7 @@
int
process_auxiliary_options(conn_t *connp, void *control, t_uscalar_t controllen,
void *optbuf, optdb_obj_t *dbobjp, int (*opt_set_fn)(conn_t *, uint_t, int,
- int, uint_t, uchar_t *, uint_t *, uchar_t *, void *, cred_t *))
+ int, uint_t, uchar_t *, uint_t *, uchar_t *, void *, cred_t *), cred_t *cr)
{
struct cmsghdr *cmsg;
opdes_t *optd;
@@ -2231,10 +2231,10 @@
if (optd == NULL) {
return (EINVAL);
}
- if (OA_READONLY_PERMISSION(optd, connp->conn_cred)) {
+ if (OA_READONLY_PERMISSION(optd, cr)) {
return (EACCES);
}
- if (OA_MATCHED_PRIV(optd, connp->conn_cred)) {
+ if (OA_MATCHED_PRIV(optd, cr)) {
/*
* For privileged options, we DO perform
* access checks as is common sense
@@ -2254,8 +2254,7 @@
}
error = opt_set_fn(connp, SETFN_UD_NEGOTIATE, optd->opdes_level,
optd->opdes_name, len, (uchar_t *)CMSG_CONTENT(cmsg),
- &outlen, (uchar_t *)CMSG_CONTENT(cmsg), (void *)optbuf,
- connp->conn_cred);
+ &outlen, (uchar_t *)CMSG_CONTENT(cmsg), (void *)optbuf, cr);
if (error > 0) {
return (error);
} else if (outlen > len) {
diff --git a/usr/src/uts/common/inet/optcom.h b/usr/src/uts/common/inet/optcom.h
index 07cb7cf..df4f227 100644
--- a/usr/src/uts/common/inet/optcom.h
+++ b/usr/src/uts/common/inet/optcom.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1990 Mentat Inc. */
@@ -222,7 +222,7 @@
extern int process_auxiliary_options(conn_t *, void *, t_uscalar_t,
void *, optdb_obj_t *, int (*)(conn_t *, uint_t, int, int, uint_t,
- uchar_t *, uint_t *, uchar_t *, void *, cred_t *));
+ uchar_t *, uint_t *, uchar_t *, void *, cred_t *), cred_t *);
#endif /* defined(_KERNEL) && defined(__STDC__) */
diff --git a/usr/src/uts/common/inet/sctp/sctp.c b/usr/src/uts/common/inet/sctp/sctp.c
index 1dc96a6..7a64587 100644
--- a/usr/src/uts/common/inet/sctp/sctp.c
+++ b/usr/src/uts/common/inet/sctp/sctp.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -242,6 +242,8 @@
connp->conn_allzones = pconnp->conn_allzones;
connp->conn_zoneid = pconnp->conn_zoneid;
+ sctp->sctp_cpid = psctp->sctp_cpid;
+ sctp->sctp_open_time = lbolt64;
sctp->sctp_mss = psctp->sctp_mss;
sctp->sctp_detached = B_TRUE;
@@ -1484,6 +1486,9 @@
sctp->sctp_zoneid = zoneid;
}
+ sctp->sctp_cpid = curproc->p_pid;
+ sctp->sctp_open_time = lbolt64;
+
sctp_connp->conn_cred = credp;
crhold(credp);
diff --git a/usr/src/uts/common/inet/sctp/sctp_common.c b/usr/src/uts/common/inet/sctp/sctp_common.c
index 7c00010..82b7113 100644
--- a/usr/src/uts/common/inet/sctp/sctp_common.c
+++ b/usr/src/uts/common/inet/sctp/sctp_common.c
@@ -342,7 +342,7 @@
}
mp = allocb_cred(ipsctplen + sctps->sctps_wroff_xtra + trailer,
- CONN_CRED(sctp->sctp_connp));
+ CONN_CRED(sctp->sctp_connp), sctp->sctp_cpid);
if (mp == NULL) {
ip1dbg(("sctp_make_mp: error making mp..\n"));
return (NULL);
diff --git a/usr/src/uts/common/inet/sctp/sctp_conn.c b/usr/src/uts/common/inet/sctp/sctp_conn.c
index b4a9b56..7f0522b 100644
--- a/usr/src/uts/common/inet/sctp/sctp_conn.c
+++ b/usr/src/uts/common/inet/sctp/sctp_conn.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -86,7 +86,7 @@
aconnp = acceptor->sctp_connp;
lconnp = listener->sctp_connp;
if (lconnp->conn_mlp_type != mlptSingle) {
- cr = aconnp->conn_peercred = DB_CRED(cr_pkt);
+ cr = aconnp->conn_peercred = msg_getcred(cr_pkt, NULL);
if (cr != NULL)
crhold(cr);
}
@@ -171,6 +171,8 @@
conn_t *connp, *econnp;
sctp_stack_t *sctps;
struct sock_proto_props sopp;
+ cred_t *cr;
+ pid_t cpid;
/*
* No need to check for duplicate as this is the listener
@@ -252,6 +254,9 @@
return (NULL);
}
+ /* Save for getpeerucred */
+ cr = msg_getcred(mp, &cpid);
+
err = sctp_accept_comm(sctp, eager, mp, ip_hdr_len, iack);
if (err) {
sctp_close_eager(eager);
@@ -294,7 +299,7 @@
/* Connection established, so send up the conn_ind */
if ((eager->sctp_ulpd = sctp->sctp_ulp_newconn(sctp->sctp_ulpd,
- (sock_lower_handle_t)eager, NULL, NULL, 0,
+ (sock_lower_handle_t)eager, NULL, cr, cpid,
&eager->sctp_upcalls)) == NULL) {
sctp_close_eager(eager);
BUMP_MIB(&sctps->sctps_mib, sctpListenDrop);
diff --git a/usr/src/uts/common/inet/sctp/sctp_cookie.c b/usr/src/uts/common/inet/sctp/sctp_cookie.c
index 3fe6f68..e3a6cc4 100644
--- a/usr/src/uts/common/inet/sctp/sctp_cookie.c
+++ b/usr/src/uts/common/inet/sctp/sctp_cookie.c
@@ -586,8 +586,10 @@
* added to cover this possibility.
*/
if (sctp->sctp_connp->conn_mlp_type != mlptSingle) {
- initlabel = MBLK_GETLABEL(initmp);
- if (initlabel == NULL) {
+ pid_t cpid;
+
+ cr = msg_getcred(initmp, &cpid);
+ if (cr == NULL || (initlabel = crgetlabel(cr)) == NULL) {
sctp_send_abort(sctp, sctp_init2vtag(ch),
SCTP_ERR_UNKNOWN, NULL, 0, initmp, 0, B_FALSE);
return;
@@ -599,11 +601,12 @@
SCTP_ERR_NO_RESOURCES, NULL, 0, initmp, 0, B_FALSE);
return;
}
- iackmp = allocb_cred(ipsctplen + sctps->sctps_wroff_xtra, cr);
+ iackmp = allocb_cred(ipsctplen + sctps->sctps_wroff_xtra,
+ cr, cpid);
crfree(cr);
} else {
iackmp = allocb_cred(ipsctplen + sctps->sctps_wroff_xtra,
- CONN_CRED(sctp->sctp_connp));
+ CONN_CRED(sctp->sctp_connp), sctp->sctp_cpid);
}
if (iackmp == NULL) {
sctp_send_abort(sctp, sctp_init2vtag(ch),
@@ -767,7 +770,7 @@
iackmp->b_cont = errmp; /* OK if NULL */
- if (is_system_labeled() && (cr = DB_CRED(iackmp)) != NULL &&
+ if (is_system_labeled() && (cr = msg_getcred(iackmp, NULL)) != NULL &&
crgetlabel(cr) != NULL) {
conn_t *connp = sctp->sctp_connp;
int err;
@@ -897,8 +900,8 @@
else
hdrlen = sctp->sctp_hdr6_len;
- cemp = allocb(sctps->sctps_wroff_xtra + hdrlen + ceclen + pad,
- BPRI_MED);
+ cemp = allocb_cred(sctps->sctps_wroff_xtra + hdrlen + ceclen + pad,
+ CONN_CRED(sctp->sctp_connp), sctp->sctp_cpid);
if (cemp == NULL) {
SCTP_FADDR_TIMER_RESTART(sctp, sctp->sctp_current,
sctp->sctp_current->rto);
diff --git a/usr/src/uts/common/inet/sctp/sctp_error.c b/usr/src/uts/common/inet/sctp/sctp_error.c
index 9e8daf5..02db60c 100644
--- a/usr/src/uts/common/inet/sctp/sctp_error.c
+++ b/usr/src/uts/common/inet/sctp/sctp_error.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -193,7 +193,7 @@
return;
hmp = allocb_cred(sctps->sctps_wroff_xtra + ahlen,
- CONN_CRED(sctp->sctp_connp));
+ CONN_CRED(sctp->sctp_connp), sctp->sctp_cpid);
if (hmp == NULL) {
/* XXX no resources */
return;
@@ -262,7 +262,7 @@
ipst = sctps->sctps_netstack->netstack_ip;
connp = sctp->sctp_connp;
- if (is_system_labeled() && (cr = DB_CRED(inmp)) != NULL &&
+ if (is_system_labeled() && (cr = msg_getcred(inmp, NULL)) != NULL &&
crgetlabel(cr) != NULL) {
int err;
boolean_t exempt = connp->conn_mac_exempt;
diff --git a/usr/src/uts/common/inet/sctp/sctp_impl.h b/usr/src/uts/common/inet/sctp/sctp_impl.h
index 5a137ec..35e5e12 100644
--- a/usr/src/uts/common/inet/sctp/sctp_impl.h
+++ b/usr/src/uts/common/inet/sctp/sctp_impl.h
@@ -935,6 +935,9 @@
int sctp_pd_point; /* Partial delivery point */
mblk_t *sctp_err_chunks; /* Error chunks */
uint32_t sctp_err_len; /* Total error chunks length */
+
+ pid_t sctp_cpid; /* Process id when this was opened */
+ uint64_t sctp_open_time; /* time when this was opened */
} sctp_t;
#define SCTP_TXQ_LEN(sctp) ((sctp)->sctp_unsent + (sctp)->sctp_unacked)
diff --git a/usr/src/uts/common/inet/sctp/sctp_input.c b/usr/src/uts/common/inet/sctp/sctp_input.c
index 87c79ee..749b9cf 100644
--- a/usr/src/uts/common/inet/sctp/sctp_input.c
+++ b/usr/src/uts/common/inet/sctp/sctp_input.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -3522,6 +3522,8 @@
sctp_stack_t *sctps = sctp->sctp_sctps;
ip_stack_t *ipst = sctps->sctps_netstack->netstack_ip;
boolean_t hb_already = B_FALSE;
+ cred_t *cr;
+ pid_t cpid;
if (DB_TYPE(mp) != M_DATA) {
ASSERT(DB_TYPE(mp) == M_CTL);
@@ -3879,7 +3881,8 @@
if (mlen > ntohs(ch->sch_len)) {
eager->sctp_cookie_mp = dupb(mp);
mblk_setcred(eager->sctp_cookie_mp,
- CONN_CRED(eager->sctp_connp));
+ CONN_CRED(eager->sctp_connp),
+ eager->sctp_cpid);
/*
* If no mem, just let
* the peer retransmit.
@@ -3950,6 +3953,8 @@
sctp_send_initack(sctp, sctph, ch, mp);
break;
case CHUNK_COOKIE:
+ cr = msg_getcred(mp, &cpid);
+
if (sctp_process_cookie(sctp, ch, mp, &iack,
sctph, &recv_adaptation, NULL) == -1) {
BUMP_MIB(&sctps->sctps_mib,
@@ -3960,8 +3965,9 @@
sctp_stop_faddr_timers(sctp);
if (!SCTP_IS_DETACHED(sctp)) {
sctp->sctp_ulp_connected(
- sctp->sctp_ulpd, 0, NULL, -1);
+ sctp->sctp_ulpd, 0, cr, cpid);
sctp_set_ulp_prop(sctp);
+
}
sctp->sctp_state = SCTPS_ESTABLISHED;
sctp->sctp_assoc_start_time = (uint32_t)lbolt;
@@ -3994,9 +4000,11 @@
case SCTPS_COOKIE_ECHOED:
switch (ch->sch_id) {
case CHUNK_COOKIE_ACK:
+ cr = msg_getcred(mp, &cpid);
+
if (!SCTP_IS_DETACHED(sctp)) {
sctp->sctp_ulp_connected(
- sctp->sctp_ulpd, 0, NULL, -1);
+ sctp->sctp_ulpd, 0, cr, cpid);
sctp_set_ulp_prop(sctp);
}
if (sctp->sctp_unacked == 0)
@@ -4023,6 +4031,8 @@
sctp_process_abort(sctp, ch, ECONNREFUSED);
goto done;
case CHUNK_COOKIE:
+ cr = msg_getcred(mp, &cpid);
+
if (sctp_process_cookie(sctp, ch, mp, &iack,
sctph, &recv_adaptation, NULL) == -1) {
BUMP_MIB(&sctps->sctps_mib,
@@ -4033,8 +4043,9 @@
if (!SCTP_IS_DETACHED(sctp)) {
sctp->sctp_ulp_connected(
- sctp->sctp_ulpd, 0, NULL, -1);
+ sctp->sctp_ulpd, 0, cr, cpid);
sctp_set_ulp_prop(sctp);
+
}
if (sctp->sctp_unacked == 0)
sctp_stop_faddr_timers(sctp);
diff --git a/usr/src/uts/common/inet/sctp/sctp_ioc.c b/usr/src/uts/common/inet/sctp/sctp_ioc.c
index 53512c7..d92be9b 100644
--- a/usr/src/uts/common/inet/sctp/sctp_ioc.c
+++ b/usr/src/uts/common/inet/sctp/sctp_ioc.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/strsubr.h>
@@ -129,7 +127,14 @@
}
iocp = (struct iocblk *)mp->b_rptr;
- cr = DB_CREDDEF(mp, iocp->ioc_cr);
+ /*
+ * prefer credential from mblk over ioctl;
+ * see ip_sioctl_copyin_setup
+ */
+ cr = msg_getcred(mp, NULL);
+ if (cr == NULL)
+ cr = iocp->ioc_cr;
+
switch (iocp->ioc_cmd) {
case SCTP_IOC_DEFAULT_Q:
/* Wants to be the default wq. */
diff --git a/usr/src/uts/common/inet/sctp/sctp_output.c b/usr/src/uts/common/inet/sctp/sctp_output.c
index 938573b..540177d 100644
--- a/usr/src/uts/common/inet/sctp/sctp_output.c
+++ b/usr/src/uts/common/inet/sctp/sctp_output.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -589,7 +589,7 @@
* or things like snoop is running.
*/
nmp = allocb_cred(sctps->sctps_wroff_xtra + hdrlen + sacklen,
- CONN_CRED(sctp->sctp_connp));
+ CONN_CRED(sctp->sctp_connp), sctp->sctp_cpid);
if (nmp == NULL) {
if (error != NULL)
*error = ENOMEM;
@@ -601,7 +601,7 @@
mp = nmp;
} else {
mp->b_rptr -= (hdrlen + sacklen);
- mblk_setcred(mp, CONN_CRED(sctp->sctp_connp));
+ mblk_setcred(mp, CONN_CRED(sctp->sctp_connp), sctp->sctp_cpid);
}
bcopy(hdr, mp->b_rptr, hdrlen);
if (sacklen) {
@@ -1381,7 +1381,8 @@
xtralen = sctp->sctp_hdr_len + sctps->sctps_wroff_xtra;
else
xtralen = sctp->sctp_hdr6_len + sctps->sctps_wroff_xtra;
- ftsn_mp = allocb_cred(xtralen + seglen, CONN_CRED(sctp->sctp_connp));
+ ftsn_mp = allocb_cred(xtralen + seglen, CONN_CRED(sctp->sctp_connp),
+ sctp->sctp_cpid);
if (ftsn_mp == NULL)
return (NULL);
ftsn_mp->b_rptr += xtralen;
diff --git a/usr/src/uts/common/inet/sockmods/socksctp.c b/usr/src/uts/common/inet/sockmods/socksctp.c
index 39bec0b..48cbe1b 100644
--- a/usr/src/uts/common/inet/sockmods/socksctp.c
+++ b/usr/src/uts/common/inet/sockmods/socksctp.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -672,7 +672,8 @@
* packets, each mblk will have the extra space before
* data to accommodate what SCTP wants to put in there.
*/
- while ((mp = allocb_cred(size + wroff, cr)) == NULL) {
+ while ((mp = allocb_cred(size + wroff, cr,
+ curproc->p_pid)) == NULL) {
if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) ||
(flags & MSG_DONTWAIT)) {
return (EAGAIN);
@@ -1530,6 +1531,28 @@
(mode & (int)FKIOCTL)))
return (EFAULT);
return (0);
+ case _I_GETPEERCRED: {
+ int error = 0;
+
+ if ((mode & FKIOCTL) == 0)
+ return (EINVAL);
+
+ mutex_enter(&so->so_lock);
+ if ((so->so_mode & SM_CONNREQUIRED) == 0) {
+ error = ENOTSUP;
+ } else if ((so->so_state & SS_ISCONNECTED) == 0) {
+ error = ENOTCONN;
+ } else if (so->so_peercred != NULL) {
+ k_peercred_t *kp = (k_peercred_t *)arg;
+ kp->pc_cr = so->so_peercred;
+ kp->pc_cpid = so->so_cpid;
+ crhold(so->so_peercred);
+ } else {
+ error = EINVAL;
+ }
+ mutex_exit(&so->so_lock);
+ return (error);
+ }
case SIOCSCTPGOPT:
STRUCT_INIT(opt, mode);
diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c
index f7d078b..95b2551 100644
--- a/usr/src/uts/common/inet/tcp/tcp.c
+++ b/usr/src/uts/common/inet/tcp/tcp.c
@@ -3052,6 +3052,21 @@
socklen_t len;
sin_t *sin;
sin6_t *sin6;
+ cred_t *cr;
+
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ tcp_err_ack(tcp, mp, TSYSERR, EINVAL);
+ return;
+ }
ASSERT((uintptr_t)(mp->b_wptr - mp->b_rptr) <= (uintptr_t)INT_MAX);
if ((mp->b_wptr - mp->b_rptr) < sizeof (*tbr)) {
@@ -3118,7 +3133,7 @@
return;
}
- error = tcp_bind_check(connp, sa, len, DB_CRED(mp),
+ error = tcp_bind_check(connp, sa, len, cr,
tbr->PRIM_type != O_T_BIND_REQ);
if (error == 0) {
if (tcp->tcp_family == AF_INET) {
@@ -3130,7 +3145,7 @@
}
if (backlog > 0) {
- error = tcp_do_listen(connp, backlog, DB_CRED(mp));
+ error = tcp_do_listen(connp, backlog, cr);
}
}
done:
@@ -4397,7 +4412,6 @@
mblk_t *mp;
char *optp = NULL;
int optlen = 0;
- cred_t *cr;
if (defermp != NULL)
*defermp = NULL;
@@ -4458,17 +4472,18 @@
if (!mp)
return (B_FALSE);
- if ((cr = DB_CRED(idmp)) != NULL) {
- mblk_setcred(mp, cr);
- DB_CPID(mp) = DB_CPID(idmp);
- }
+ mblk_copycred(mp, idmp);
if (defermp == NULL) {
conn_t *connp = tcp->tcp_connp;
if (IPCL_IS_NONSTR(connp)) {
+ cred_t *cr;
+ pid_t cpid;
+
+ cr = msg_getcred(mp, &cpid);
(*connp->conn_upcalls->su_connected)
(connp->conn_upper_handle, tcp->tcp_connid, cr,
- DB_CPID(mp));
+ cpid);
freemsg(mp);
} else {
putnext(tcp->tcp_rq, mp);
@@ -4560,7 +4575,6 @@
in6_addr_t v6dst;
int err;
int ifindex = 0;
- cred_t *cr;
tcp_stack_t *tcps = tcp->tcp_tcps;
if (ipvers == IPV4_VERSION) {
@@ -4796,10 +4810,8 @@
* If the SYN contains a credential, it's a loopback packet; attach
* the credential to the TPI message.
*/
- if ((cr = DB_CRED(idmp)) != NULL) {
- mblk_setcred(tpi_mp, cr);
- DB_CPID(tpi_mp) = DB_CPID(idmp);
- }
+ mblk_copycred(tpi_mp, idmp);
+
tcp->tcp_conn.tcp_eager_conn_ind = tpi_mp;
/* Inherit the listener's SSL protection state */
@@ -4827,7 +4839,6 @@
sin_t sin;
mblk_t *tpi_mp = NULL;
int err;
- cred_t *cr;
tcp_stack_t *tcps = tcp->tcp_tcps;
sin = sin_null;
@@ -4923,10 +4934,8 @@
* If the SYN contains a credential, it's a loopback packet; attach
* the credential to the TPI message.
*/
- if ((cr = DB_CRED(idmp)) != NULL) {
- mblk_setcred(tpi_mp, cr);
- DB_CPID(tpi_mp) = DB_CPID(idmp);
- }
+ mblk_copycred(tpi_mp, idmp);
+
tcp->tcp_conn.tcp_eager_conn_ind = tpi_mp;
/* Inherit the listener's SSL protection state */
@@ -5519,7 +5528,7 @@
cred_t *cr;
if (connp->conn_mlp_type != mlptSingle) {
- cr = econnp->conn_peercred = DB_CRED(mp);
+ cr = econnp->conn_peercred = msg_getcred(mp, NULL);
if (cr != NULL)
crhold(cr);
else
@@ -5708,8 +5717,17 @@
goto error;
}
- DB_CPID(mp1) = tcp->tcp_cpid;
- mblk_setcred(mp1, CONN_CRED(eager->tcp_connp));
+ /*
+ * Note that in theory this should use the current pid
+ * so that getpeerucred on the client returns the actual listener
+ * that does accept. But accept() hasn't been called yet. We could use
+ * the pid of the process that did bind/listen on the server.
+ * However, with common usage like inetd() the bind/listen can be done
+ * by a different process than the accept().
+ * Hence we do the simple thing of using the open pid here.
+ * Note that db_credp is set later in tcp_send_data().
+ */
+ mblk_setcred(mp1, credp, tcp->tcp_cpid);
eager->tcp_cpid = tcp->tcp_cpid;
eager->tcp_open_time = lbolt64;
@@ -5924,6 +5942,22 @@
struct sockaddr *sa;
socklen_t len;
int error;
+ cred_t *cr;
+ pid_t cpid;
+
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, &cpid);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ tcp_err_ack(tcp, mp, TSYSERR, EINVAL);
+ return;
+ }
tcr = (struct T_conn_req *)mp->b_rptr;
@@ -6103,8 +6137,7 @@
}
/* call the non-TPI version */
- error = tcp_do_connect(tcp->tcp_connp, sa, len, DB_CRED(mp),
- DB_CPID(mp));
+ error = tcp_do_connect(tcp->tcp_connp, sa, len, cr, cpid);
if (error < 0) {
mp = mi_tpi_err_ack_alloc(mp, -error, 0);
} else if (error > 0) {
@@ -6255,7 +6288,7 @@
if (tcp->tcp_family == AF_INET) {
error = ip_proto_bind_connected_v4(tcp->tcp_connp, &mp,
IPPROTO_TCP, &tcp->tcp_ipha->ipha_src, tcp->tcp_lport,
- tcp->tcp_remote, tcp->tcp_fport, B_TRUE, B_TRUE);
+ tcp->tcp_remote, tcp->tcp_fport, B_TRUE, B_TRUE, cr);
} else {
in6_addr_t v6src;
if (tcp->tcp_ipversion == IPV4_VERSION) {
@@ -6265,7 +6298,7 @@
}
error = ip_proto_bind_connected_v6(tcp->tcp_connp, &mp,
IPPROTO_TCP, &v6src, tcp->tcp_lport, &tcp->tcp_remote_v6,
- &tcp->tcp_sticky_ipp, tcp->tcp_fport, B_TRUE, B_TRUE);
+ &tcp->tcp_sticky_ipp, tcp->tcp_fport, B_TRUE, B_TRUE, cr);
}
BUMP_MIB(&tcps->tcps_mib, tcpActiveOpens);
tcp->tcp_active_open = 1;
@@ -6445,7 +6478,7 @@
}
error = ip_proto_bind_connected_v6(connp, &mp, IPPROTO_TCP,
&v6src, tcp->tcp_lport, &tcp->tcp_remote_v6,
- &tcp->tcp_sticky_ipp, tcp->tcp_fport, B_TRUE, B_TRUE);
+ &tcp->tcp_sticky_ipp, tcp->tcp_fport, B_TRUE, B_TRUE, cr);
BUMP_MIB(&tcps->tcps_mib, tcpActiveOpens);
tcp->tcp_active_open = 1;
@@ -12713,6 +12746,11 @@
tcp_ulp_newconn(conn_t *lconnp, conn_t *econnp, mblk_t *mp)
{
if (IPCL_IS_NONSTR(lconnp)) {
+ cred_t *cr;
+ pid_t cpid;
+
+ cr = msg_getcred(mp, &cpid);
+
ASSERT(econnp->conn_tcp->tcp_listener == lconnp->conn_tcp);
ASSERT(econnp->conn_tcp->tcp_saved_listener ==
lconnp->conn_tcp);
@@ -12732,7 +12770,7 @@
if ((*lconnp->conn_upcalls->su_newconn)
(lconnp->conn_upper_handle,
(sock_lower_handle_t)econnp,
- &sock_tcp_downcalls, DB_CRED(mp), DB_CPID(mp),
+ &sock_tcp_downcalls, cr, cpid,
&econnp->conn_upcalls) == NULL) {
/* Failed to allocate a socket */
BUMP_MIB(&lconnp->conn_tcp->tcp_tcps->tcps_mib,
@@ -13220,12 +13258,14 @@
/* Send up T_CONN_CON */
putnext(tcp->tcp_rq, mp1);
} else {
+ cred_t *cr;
+ pid_t cpid;
+
+ cr = msg_getcred(mp1, &cpid);
(*connp->conn_upcalls->
su_connected)
(connp->conn_upper_handle,
- tcp->tcp_connid,
- DB_CRED(mp1),
- DB_CPID(mp1));
+ tcp->tcp_connid, cr, cpid);
freemsg(mp1);
}
@@ -13244,10 +13284,13 @@
if (!IPCL_IS_NONSTR(connp)) {
putnext(tcp->tcp_rq, mp1);
} else {
+ cred_t *cr;
+ pid_t cpid;
+
+ cr = msg_getcred(mp1, &cpid);
(*connp->conn_upcalls->su_connected)
(connp->conn_upper_handle,
- tcp->tcp_connid, DB_CRED(mp1),
- DB_CPID(mp1));
+ tcp->tcp_connid, cr, cpid);
freemsg(mp1);
}
}
@@ -13275,6 +13318,10 @@
mp1 = tcp_xmit_mp(tcp, tcp->tcp_xmit_head, tcp->tcp_mss,
NULL, NULL, tcp->tcp_iss, B_FALSE, NULL, B_FALSE);
if (mp1) {
+ /*
+ * See comment in tcp_conn_request() for why we use
+ * the open() time pid here.
+ */
DB_CPID(mp1) = tcp->tcp_cpid;
tcp_send_data(tcp, tcp->tcp_wq, mp1);
TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
@@ -17275,10 +17322,14 @@
if (mp == NULL) {
return;
}
- /* Attach credentials to retransmitted initial SYNs. */
+ /*
+ * Attach credentials to retransmitted initial SYNs.
+ * In theory we should use the credentials from the connect()
+ * call to ensure that getpeerucred() on the peer will be correct.
+ * But we assume that SYN's are not dropped for loopback connections.
+ */
if (tcp->tcp_state == TCPS_SYN_SENT) {
- mblk_setcred(mp, tcp->tcp_cred);
- DB_CPID(mp) = tcp->tcp_cpid;
+ mblk_setcred(mp, tcp->tcp_cred, tcp->tcp_cpid);
}
tcp->tcp_csuna = tcp->tcp_snxt;
@@ -18486,9 +18537,25 @@
struct T_ok_ack *ok;
t_scalar_t PRIM_type;
conn_t *econnp;
+ cred_t *cr;
ASSERT(DB_TYPE(mp) == M_PROTO);
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ mp = mi_tpi_err_ack_alloc(mp, TSYSERR, EINVAL);
+ if (mp != NULL)
+ putnext(rq, mp);
+ return;
+ }
conn_res = (struct T_conn_res *)mp->b_rptr;
ASSERT((uintptr_t)(mp->b_wptr - mp->b_rptr) <= (uintptr_t)INT_MAX);
if ((mp->b_wptr - mp->b_rptr) < sizeof (struct T_conn_res)) {
@@ -18535,7 +18602,7 @@
*/
eager->tcp_sodirect = SOD_QTOSODP(eager->tcp_rq);
if (tcp_accept_common(listener->tcp_connp,
- econnp, CRED()) < 0) {
+ econnp, cr) < 0) {
mp = mi_tpi_err_ack_alloc(mp, TPROTO, 0);
if (mp != NULL)
putnext(rq, mp);
@@ -18769,7 +18836,20 @@
return;
}
if (type == T_SVR4_OPTMGMT_REQ) {
- cred_t *cr = DB_CREDDEF(mp, tcp->tcp_cred);
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cred_t *cr = msg_getcred(mp, NULL);
+
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ tcp_err_ack(tcp, mp, TSYSERR, EINVAL);
+ return;
+ }
if (snmpcom_req(q, mp, tcp_snmp_set, ip_snmp_get,
cr)) {
/*
@@ -19194,11 +19274,24 @@
uint_t ire_fp_mp_len;
tcp_stack_t *tcps = tcp->tcp_tcps;
ip_stack_t *ipst = tcps->tcps_netstack->netstack_ip;
+ cred_t *cr;
+ pid_t cpid;
ASSERT(DB_TYPE(mp) == M_DATA);
- if (is_system_labeled() && DB_CRED(mp) == NULL)
- mblk_setcred(mp, CONN_CRED(tcp->tcp_connp));
+ /*
+ * Here we need to handle the overloading of the cred_t for
+ * both getpeerucred and TX.
+ * If this is a SYN then the caller already set db_credp so
+ * that getpeerucred will work. But if TX is in use we might have
+ * a conn_peercred which is different, and we need to use that cred
+ * to make TX use the correct label and label dependent route.
+ */
+ if (is_system_labeled()) {
+ cr = msg_getcred(mp, &cpid);
+ if (cr == NULL || connp->conn_peercred != NULL)
+ mblk_setcred(mp, CONN_CRED(connp), cpid);
+ }
ipha = (ipha_t *)mp->b_rptr;
src = ipha->ipha_src;
@@ -22329,7 +22422,7 @@
union T_primitives *tprim = (union T_primitives *)mp->b_rptr;
uchar_t *rptr;
t_scalar_t type;
- cred_t *cr = DB_CREDDEF(mp, tcp->tcp_cred);
+ cred_t *cr;
/*
* Try and ASSERT the minimum possible references on the
@@ -22417,29 +22510,41 @@
tcp_info_req(tcp, mp);
break;
case T_SVR4_OPTMGMT_REQ: /* manage options req */
+ case T_OPTMGMT_REQ:
+ /*
+ * Note: no support for snmpcom_req() through new
+ * T_OPTMGMT_REQ. See comments in ip.c
+ */
+
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ tcp_err_ack(tcp, mp, TSYSERR, EINVAL);
+ return;
+ }
/*
* If EINPROGRESS is returned, the request has been queued
* for subsequent processing by ip_restart_optmgmt(), which
* will do the CONN_DEC_REF().
*/
CONN_INC_REF(connp);
- if (svr4_optcom_req(tcp->tcp_wq, mp, cr, &tcp_opt_obj,
- B_TRUE) != EINPROGRESS) {
- CONN_DEC_REF(connp);
- }
- break;
- case T_OPTMGMT_REQ:
- /*
- * Note: no support for snmpcom_req() through new
- * T_OPTMGMT_REQ. See comments in ip.c
- *
- * see comments above in T_SVR4_OPTMGMT_REQ for conn
- * reference changes.
- */
- CONN_INC_REF(connp);
- if (tpi_optcom_req(tcp->tcp_wq, mp, cr, &tcp_opt_obj,
- B_TRUE) != EINPROGRESS) {
- CONN_DEC_REF(connp);
+ if ((int)tprim->type == T_SVR4_OPTMGMT_REQ) {
+ if (svr4_optcom_req(tcp->tcp_wq, mp, cr, &tcp_opt_obj,
+ B_TRUE) != EINPROGRESS) {
+ CONN_DEC_REF(connp);
+ }
+ } else {
+ if (tpi_optcom_req(tcp->tcp_wq, mp, cr, &tcp_opt_obj,
+ B_TRUE) != EINPROGRESS) {
+ CONN_DEC_REF(connp);
+ }
}
break;
@@ -22878,7 +22983,7 @@
}
/* IP trusts us to set up labels when required. */
- if (is_system_labeled() && (cr = DB_CRED(mp)) != NULL &&
+ if (is_system_labeled() && (cr = msg_getcred(mp, NULL)) != NULL &&
crgetlabel(cr) != NULL) {
int err;
@@ -24344,7 +24449,17 @@
struct T_conn_res *tcresp;
cred_t *cr;
- cr = DB_CREDDEF(mp, tcp->tcp_cred);
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL)
+ return (-1);
prim_type = ((union T_primitives *)mp->b_rptr)->type;
ASSERT(prim_type == T_CONN_REQ || prim_type == O_T_CONN_RES ||
@@ -26648,8 +26763,7 @@
cr = tcp->tcp_cred;
pid = tcp->tcp_cpid;
}
- mblk_setcred(syn_mp, cr);
- DB_CPID(syn_mp) = pid;
+ mblk_setcred(syn_mp, cr, pid);
tcp_send_data(tcp, tcp->tcp_wq, syn_mp);
}
after_syn_sent:
@@ -26914,10 +27028,9 @@
boolean_t bind_to_req_port_only)
{
tcp_t *tcp = connp->conn_tcp;
-
sin_t *sin;
sin6_t *sin6;
- sin6_t sin6addr;
+ sin6_t sin6addr;
in_port_t requested_port;
ipaddr_t v4addr;
in6_addr_t v6addr;
@@ -27091,6 +27204,9 @@
conn_t *connp = (conn_t *)proto_handle;
squeue_t *sqp = connp->conn_sqp;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
ASSERT(sqp != NULL);
ASSERT(connp->conn_upper_handle != NULL);
@@ -27259,6 +27375,9 @@
ASSERT(connp->conn_upper_handle != NULL);
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
error = proto_verify_ip_addr(tcp->tcp_family, sa, len);
if (error != 0) {
return (error);
@@ -27352,6 +27471,9 @@
ASSERT(connp->conn_upper_handle == NULL);
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
sopp.sopp_flags = SOCKOPT_RCVHIWAT | SOCKOPT_RCVLOWAT |
SOCKOPT_MAXPSZ | SOCKOPT_MAXBLK | SOCKOPT_RCVTIMER |
SOCKOPT_RCVTHRESH | SOCKOPT_MAXADDRLEN | SOCKOPT_MINPSZ;
@@ -27380,6 +27502,9 @@
ASSERT(connp->conn_upper_handle != NULL);
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
tcp_close_common(connp, flags);
ip_free_helper_stream(connp);
@@ -27410,6 +27535,9 @@
conn_t *connp = (conn_t *)proto_handle;
int32_t tcpstate;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
ASSERT(connp->conn_ref >= 2);
ASSERT(connp->conn_upper_handle != NULL);
@@ -27516,6 +27644,9 @@
tcp_t *tcp = connp->conn_tcp;
ASSERT(connp->conn_upper_handle != NULL);
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
ASSERT(tcp != NULL);
return (tcp_do_getpeername(tcp, addr, addrlenp));
@@ -27529,6 +27660,9 @@
conn_t *connp = (conn_t *)proto_handle;
tcp_t *tcp = connp->conn_tcp;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
ASSERT(connp->conn_upper_handle != NULL);
return (tcp_do_getsockname(tcp, addr, addrlenp));
@@ -27779,6 +27913,9 @@
ASSERT(connp->conn_upper_handle != NULL);
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
/*
* X/Open requires that we check the connected state.
*/
@@ -27819,6 +27956,9 @@
ASSERT(connp->conn_upper_handle != NULL);
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
error = squeue_synch_enter(sqp, connp, 0);
if (error != 0) {
/* failed to enter */
@@ -27848,6 +27988,9 @@
int error = 0;
tcp_stack_t *tcps = tcp->tcp_tcps;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (tcp->tcp_state >= TCPS_BOUND) {
if ((tcp->tcp_state == TCPS_BOUND ||
tcp->tcp_state == TCPS_LISTEN) && backlog > 0) {
@@ -27981,6 +28124,9 @@
ASSERT(connp->conn_upper_handle != NULL);
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
switch (cmd) {
case ND_SET:
case ND_GET:
diff --git a/usr/src/uts/common/inet/tun.h b/usr/src/uts/common/inet/tun.h
index 6175e82..8154c0f 100644
--- a/usr/src/uts/common/inet/tun.h
+++ b/usr/src/uts/common/inet/tun.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -27,8 +27,6 @@
#ifndef _INET_TUN_H
#define _INET_TUN_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -202,6 +200,7 @@
uint64_t tun_HCOutUcastPkts; /* # Packets requested */
uint64_t tun_HCOutMulticastPkts; /* Multicast Packets requested */
netstack_t *tun_netstack;
+ cred_t *tun_cred;
} tun_t;
diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c
index 662c162..30c876b 100644
--- a/usr/src/uts/common/inet/udp/udp.c
+++ b/usr/src/uts/common/inet/udp/udp.c
@@ -241,7 +241,8 @@
struct sockaddr *, socklen_t *, cred_t *);
int udp_getpeername(sock_lower_handle_t,
struct sockaddr *, socklen_t *, cred_t *);
-static int udp_do_connect(conn_t *, const struct sockaddr *, socklen_t);
+static int udp_do_connect(conn_t *, const struct sockaddr *, socklen_t,
+ cred_t *cr);
static int udp_post_ip_bind_connect(udp_t *, mblk_t *, int);
#define UDP_RECV_HIWATER (56 * 1024)
@@ -640,6 +641,21 @@
udp_t *udp;
int error;
struct sockaddr *sa;
+ cred_t *cr;
+
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ udp_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
connp = Q_TO_CONN(q);
udp = connp->conn_udp;
@@ -728,8 +744,6 @@
return;
}
-
- cred_t *cr = DB_CREDDEF(mp, connp->conn_cred);
error = udp_do_bind(connp, sa, tbr->ADDR_length, cr,
tbr->PRIM_type != O_T_BIND_REQ);
@@ -771,6 +785,21 @@
socklen_t len;
struct sockaddr *sa;
struct T_conn_req *tcr;
+ cred_t *cr;
+
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ udp_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
udp = connp->conn_udp;
tcr = (struct T_conn_req *)mp->b_rptr;
@@ -842,7 +871,7 @@
return;
}
- error = udp_do_connect(connp, sa, len);
+ error = udp_do_connect(connp, sa, len, cr);
if (error != 0) {
freeb(mp1);
if (error < 0)
@@ -2469,11 +2498,12 @@
return (EINVAL);
if (!checkonly) {
mblk_t *mb;
+ pid_t cpid;
if (attrs == NULL ||
(mb = attrs->udpattr_mb) == NULL)
return (EINVAL);
- if ((cr = DB_CRED(mb)) == NULL)
+ if ((cr = msg_getcred(mb, &cpid)) == NULL)
cr = udp->udp_connp->conn_cred;
ASSERT(cr != NULL);
if ((tsl = crgetlabel(cr)) == NULL)
@@ -2482,7 +2512,7 @@
tsl->tsl_doi, KM_NOSLEEP);
if (newcr == NULL)
return (ENOSR);
- mblk_setcred(mb, newcr);
+ mblk_setcred(mb, newcr, cpid);
attrs->udpattr_credset = B_TRUE;
crfree(newcr);
}
@@ -3858,7 +3888,7 @@
}
- /* Walk past the headers unless IP_RECVHDR was set. */
+ /* Walk past the headers unless UDP_RCVHDR was set. */
if (!udp_bits.udpb_rcvhdr) {
mp->b_rptr = rptr + hdr_length;
mp_len -= hdr_length;
@@ -3916,9 +3946,8 @@
}
if ((udp_bits.udpb_recvucred) &&
- (cr = DB_CRED(mp)) != NULL) {
+ (cr = msg_getcred(mp, &cpid)) != NULL) {
udi_size += sizeof (struct T_opthdr) + ucredsize;
- cpid = DB_CPID(mp);
UDP_STAT(us, udp_in_recvucred);
}
@@ -4191,9 +4220,8 @@
}
if ((udp_bits.udpb_recvucred) &&
- (cr = DB_CRED(mp)) != NULL) {
+ (cr = msg_getcred(mp, &cpid)) != NULL) {
udi_size += sizeof (struct T_opthdr) + ucredsize;
- cpid = DB_CPID(mp);
UDP_STAT(us, udp_in_recvucred);
}
@@ -4980,8 +5008,21 @@
uchar_t opt_storage[IP_MAX_OPT_LENGTH];
udp_t *udp = Q_TO_UDP(wq);
udp_stack_t *us = udp->udp_us;
+ cred_t *cr;
- err = tsol_compute_label(DB_CREDDEF(mp, udp->udp_connp->conn_cred), dst,
+ /*
+ * All Solaris components should pass a db_credp
+ * for this message, hence we ASSERT.
+ * On production kernels we return an error to be robust against
+ * random streams modules sitting on top of us.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL)
+ return (EINVAL);
+
+ /* Note that we use the cred/label from the message to handle MLP */
+ err = tsol_compute_label(cr, dst,
opt_storage, udp->udp_connp->conn_mac_exempt,
us->us_netstack->netstack_ip);
if (err == 0) {
@@ -5049,7 +5090,7 @@
rw_enter(&udp->udp_rwlock, RW_WRITER);
*error = process_auxiliary_options(connp,
msg->msg_control, msg->msg_controllen,
- &attrs, &udp_opt_obj, udp_opt_set);
+ &attrs, &udp_opt_obj, udp_opt_set, cr);
rw_exit(&udp->udp_rwlock);
if (*error)
goto done;
@@ -5081,13 +5122,15 @@
/*
* Determine whether we need to mark the mblk with the user's
* credentials.
+ * If labeled then sockfs would have already done this.
*/
+ ASSERT(!is_system_labeled() || msg_getcred(mp, NULL) != NULL);
+
ire = connp->conn_ire_cache;
- if (is_system_labeled() || CLASSD(v4dst) || (ire == NULL) ||
- (ire->ire_addr != v4dst) ||
+ if (CLASSD(v4dst) || (ire == NULL) || (ire->ire_addr != v4dst) ||
(ire->ire_type & (IRE_BROADCAST | IRE_LOCAL | IRE_LOOPBACK))) {
- if (cr != NULL && DB_CRED(mp) == NULL)
- msg_setcredpid(mp, cr, pid);
+ if (cr != NULL && msg_getcred(mp, NULL) == NULL)
+ mblk_setcred(mp, cr, pid);
}
rw_enter(&udp->udp_rwlock, RW_READER);
@@ -5336,10 +5379,19 @@
ASSERT(!lock_held);
/* Set UDP length and checksum */
*((uint32_t *)&udpha->uha_length) = ip_len;
- if (DB_CRED(mp) != NULL)
- mblk_setcred(mp1, DB_CRED(mp));
if (DB_TYPE(mp) != M_DATA) {
+ cred_t *cr;
+ pid_t cpid;
+
+ /* Move any cred from the T_UNITDATA_REQ to the packet */
+ cr = msg_extractcred(mp, &cpid);
+ if (cr != NULL) {
+ if (mp1->b_datap->db_credp != NULL)
+ crfree(mp1->b_datap->db_credp);
+ mp1->b_datap->db_credp = cr;
+ mp1->b_datap->db_cpid = cpid;
+ }
ASSERT(mp != mp1);
freeb(mp);
}
@@ -5446,12 +5498,12 @@
if (CLASSD(dst)) {
ASSERT(ipif != NULL);
ire = ire_ctable_lookup(dst, 0, 0, ipif,
- connp->conn_zoneid, MBLK_GETLABEL(mp),
+ connp->conn_zoneid, msg_getlabel(mp),
MATCH_IRE_ILL, ipst);
} else {
ASSERT(ipif == NULL);
ire = ire_cache_lookup(dst, connp->conn_zoneid,
- MBLK_GETLABEL(mp), ipst);
+ msg_getlabel(mp), ipst);
}
if (ire == NULL) {
@@ -5691,8 +5743,21 @@
int err;
uchar_t opt_storage[TSOL_MAX_IPV6_OPTION];
udp_stack_t *us = udp->udp_us;
+ cred_t *cr;
- err = tsol_compute_label_v6(DB_CREDDEF(mp, udp->udp_connp->conn_cred),
+ /*
+ * All Solaris components should pass a db_credp
+ * for this message, hence we ASSERT.
+ * On production kernels we return an error to be robust against
+ * random streams modules sitting on top of us.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL)
+ return (EINVAL);
+
+ /* Note that we use the cred/label from the message to handle MLP */
+ err = tsol_compute_label_v6(cr,
dst, opt_storage, udp->udp_connp->conn_mac_exempt,
us->us_netstack->netstack_ip);
if (err == 0) {
@@ -6065,7 +6130,7 @@
rw_enter(&udp->udp_rwlock, RW_WRITER);
*error = process_auxiliary_options(connp,
msg->msg_control, msg->msg_controllen,
- &attrs, &udp_opt_obj, udp_opt_set);
+ &attrs, &udp_opt_obj, udp_opt_set, cr);
rw_exit(&udp->udp_rwlock);
if (*error)
goto done;
@@ -6092,14 +6157,15 @@
/*
* Determine whether we need to mark the mblk with the user's
* credentials.
+ * If labeled then sockfs would have already done this.
*/
+ ASSERT(!is_system_labeled() || msg_getcred(mp, NULL) != NULL);
ire = connp->conn_ire_cache;
- if (is_system_labeled() || IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) ||
- (ire == NULL) ||
+ if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) || (ire == NULL) ||
(!IN6_ARE_ADDR_EQUAL(&ire->ire_addr_v6, &sin6->sin6_addr)) ||
(ire->ire_type & (IRE_LOCAL | IRE_LOOPBACK))) {
- if (cr != NULL && DB_CRED(mp) == NULL)
- msg_setcredpid(mp, cr, pid);
+ if (cr != NULL && msg_getcred(mp, NULL) == NULL)
+ mblk_setcred(mp, cr, pid);
}
rw_enter(&udp->udp_rwlock, RW_READER);
@@ -6653,10 +6719,20 @@
ip_len = htons(ip_len);
#endif
ip6h->ip6_plen = ip_len;
- if (DB_CRED(mp) != NULL)
- mblk_setcred(mp1, DB_CRED(mp));
if (DB_TYPE(mp) != M_DATA) {
+ cred_t *cr;
+ pid_t cpid;
+
+ /* Move any cred from the T_UNITDATA_REQ to the packet */
+ cr = msg_extractcred(mp, &cpid);
+ if (cr != NULL) {
+ if (mp1->b_datap->db_credp != NULL)
+ crfree(mp1->b_datap->db_credp);
+ mp1->b_datap->db_credp = cr;
+ mp1->b_datap->db_cpid = cpid;
+ }
+
ASSERT(mp != mp1);
freeb(mp);
}
@@ -6853,8 +6929,6 @@
us = udp->udp_us;
db = mp->b_datap;
- cr = DB_CREDDEF(mp, connp->conn_cred);
-
switch (db->db_type) {
case M_CMD:
udp_wput_cmdblk(q, mp);
@@ -6911,6 +6985,19 @@
"udp_wput_other_end: q %p (%S)", q, "unbindreq");
return;
case T_SVR4_OPTMGMT_REQ:
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ udp_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
if (!snmpcom_req(q, mp, udp_snmp_set, ip_snmp_get,
cr)) {
(void) svr4_optcom_req(q,
@@ -6921,6 +7008,19 @@
return;
case T_OPTMGMT_REQ:
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ udp_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
(void) tpi_optcom_req(q, mp, cr, &udp_opt_obj, B_TRUE);
TRACE_2(TR_FAC_UDP, TR_UDP_WPUT_OTHER_END,
"udp_wput_other_end: q %p (%S)", q, "optmgmtreq");
@@ -7140,12 +7240,22 @@
struct T_unitdata_req *udreqp;
int is_absreq_failure;
cred_t *cr;
- conn_t *connp = Q_TO_CONN(q);
ASSERT(((t_primp_t)mp->b_rptr)->type);
- cr = DB_CREDDEF(mp, connp->conn_cred);
-
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we should ASSERT.
+ * However, RPC (svc_clts_ksend) does this odd thing where it
+ * passes the options from a T_UNITDATA_IND unchanged in a
+ * T_UNITDATA_REQ. While that is the right thing to do for
+ * some options, SCM_UCRED being the key one, this also makes it
+ * pass down IP_RECVDSTADDR. Hence we can't ASSERT here.
+ */
+ cr = msg_getcred(mp, NULL);
+ if (cr == NULL) {
+ cr = Q_TO_CONN(q)->conn_cred;
+ }
udreqp = (struct T_unitdata_req *)mp->b_rptr;
*errorp = tpi_optcom_buf(q, mp, &udreqp->OPT_length,
@@ -7882,6 +7992,9 @@
udp_stack_t *us = udp->udp_us;
struct sock_proto_props sopp;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
connp->conn_upcalls = sock_upcalls;
connp->conn_upper_handle = sock_handle;
@@ -7959,6 +8072,9 @@
{
conn_t *connp = (conn_t *)proto_handle;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
udp_do_close(connp);
return (0);
}
@@ -8394,7 +8510,6 @@
if (is_system_labeled() && (!connp->conn_anon_port ||
connp->conn_anon_mlp)) {
uint16_t mlpport;
- cred_t *cr = connp->conn_cred;
zone_t *zone;
zone = crgetzone(cr);
@@ -8520,6 +8635,9 @@
int error;
conn_t *connp;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
connp = (conn_t *)proto_handle;
if (sa == NULL)
@@ -8542,6 +8660,9 @@
{
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
error = udp_do_bind(connp, NULL, 0, cr, B_FALSE);
return ((error < 0) ? proto_tlitosyserr(-error) : error);
}
@@ -8698,7 +8819,8 @@
* It associates a default destination address with the stream.
*/
static int
-udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len)
+udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
+ cred_t *cr)
{
sin6_t *sin6;
sin_t *sin;
@@ -8897,11 +9019,11 @@
error = ip_proto_bind_connected_v4(connp, &ire_mp, IPPROTO_UDP,
&V4_PART_OF_V6(udp->udp_v6src), udp->udp_port,
V4_PART_OF_V6(udp->udp_v6dst), udp->udp_dstport,
- B_TRUE, B_TRUE);
+ B_TRUE, B_TRUE, cr);
} else {
error = ip_proto_bind_connected_v6(connp, &ire_mp, IPPROTO_UDP,
&udp->udp_v6src, udp->udp_port, &udp->udp_v6dst,
- &udp->udp_sticky_ipp, udp->udp_dstport, B_TRUE, B_TRUE);
+ &udp->udp_sticky_ipp, udp->udp_dstport, B_TRUE, B_TRUE, cr);
}
return (udp_post_ip_bind_connect(udp, ire_mp, error));
@@ -8917,6 +9039,9 @@
int error;
boolean_t did_bind = B_FALSE;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (sa == NULL) {
/*
* Disconnect
@@ -8950,7 +9075,7 @@
*/
udp->udp_dgram_errind = B_TRUE;
- error = udp_do_connect(connp, sa, len);
+ error = udp_do_connect(connp, sa, len, cr);
if (error != 0 && did_bind) {
int unbind_err;
@@ -8991,6 +9116,12 @@
ASSERT(DB_TYPE(mp) == M_DATA);
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
+ /* If labeled then sockfs should have already set db_credp */
+ ASSERT(!is_system_labeled() || msg_getcred(mp, NULL) != NULL);
+
/*
* If the socket is connected and no change in destination
*/
@@ -9145,9 +9276,9 @@
laddrlen = faddrlen = sizeof (sin6_t);
(void) udp_getsockname((sock_lower_handle_t)connp,
- (struct sockaddr *)&laddr, &laddrlen, NULL);
+ (struct sockaddr *)&laddr, &laddrlen, CRED());
error = udp_getpeername((sock_lower_handle_t)connp,
- (struct sockaddr *)&faddr, &faddrlen, NULL);
+ (struct sockaddr *)&faddr, &faddrlen, CRED());
if (error != 0)
faddrlen = 0;
@@ -9241,6 +9372,9 @@
udp_t *udp = connp->conn_udp;
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
ASSERT(udp != NULL);
rw_enter(&udp->udp_rwlock, RW_READER);
@@ -9329,6 +9463,9 @@
udp_t *udp = connp->conn_udp;
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
ASSERT(udp != NULL);
rw_enter(&udp->udp_rwlock, RW_READER);
@@ -9350,6 +9487,9 @@
void *optvalp_buf;
int len;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
error = proto_opt_check(level, option_name, *optlen, &max_optbuf_len,
udp_opt_obj.odb_opt_des_arr,
udp_opt_obj.odb_opt_arr_cnt,
@@ -9394,6 +9534,9 @@
udp_t *udp = connp->conn_udp;
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
error = proto_opt_check(level, option_name, optlen, NULL,
udp_opt_obj.odb_opt_des_arr,
udp_opt_obj.odb_opt_arr_cnt,
@@ -9440,6 +9583,9 @@
{
conn_t *connp = (conn_t *)proto_handle;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
/* shut down the send side */
if (how != SHUT_RD)
(*connp->conn_upcalls->su_opctl)(connp->conn_upper_handle,
@@ -9458,6 +9604,9 @@
conn_t *connp = (conn_t *)proto_handle;
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
switch (cmd) {
case ND_SET:
case ND_GET:
diff --git a/usr/src/uts/common/io/ib/clients/rds/rdsddi.c b/usr/src/uts/common/io/ib/clients/rds/rdsddi.c
index 877e56f..a4a9c6c 100644
--- a/usr/src/uts/common/io/ib/clients/rds/rdsddi.c
+++ b/usr/src/uts/common/io/ib/clients/rds/rdsddi.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -608,12 +608,10 @@
static void
rds_wput_other(queue_t *q, mblk_t *mp)
{
- rds_t *rds = (rds_t *)q->q_ptr;
uchar_t *rptr = mp->b_rptr;
struct datab *db;
cred_t *cr;
- cr = DB_CREDDEF(mp, rds->rds_cred);
db = mp->b_datap;
switch (db->db_type) {
case M_DATA:
@@ -640,11 +638,28 @@
rds_bind(q, mp);
return;
case T_SVR4_OPTMGMT_REQ:
- (void) svr4_optcom_req(q, mp, cr, &rds_opt_obj,
- B_FALSE);
- return;
case T_OPTMGMT_REQ:
- (void) tpi_optcom_req(q, mp, cr, &rds_opt_obj, B_FALSE);
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ rds_err_ack(q, mp, TSYSERR, EINVAL);
+ return;
+ }
+ if (((union T_primitives *)(uintptr_t)rptr)->type ==
+ T_SVR4_OPTMGMT_REQ) {
+ (void) svr4_optcom_req(q, mp, cr, &rds_opt_obj,
+ B_FALSE);
+ } else {
+ (void) tpi_optcom_req(q, mp, cr, &rds_opt_obj,
+ B_FALSE);
+ }
return;
case T_CONN_REQ:
/*
diff --git a/usr/src/uts/common/io/ksocket/ksocket.c b/usr/src/uts/common/io/ksocket/ksocket.c
index 512cab5..28b4f71 100644
--- a/usr/src/uts/common/io/ksocket/ksocket.c
+++ b/usr/src/uts/common/io/ksocket/ksocket.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -52,6 +52,9 @@
struct sonode *so;
*ksp = NULL;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (domain == AF_NCA || domain == AF_UNIX)
return (EAFNOSUPPORT);
@@ -99,6 +102,9 @@
{
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks))
return (ENOTSOCK);
@@ -110,6 +116,9 @@
int
ksocket_listen(ksocket_t ks, int backlog, struct cred *cr)
{
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks))
return (ENOTSOCK);
@@ -123,6 +132,9 @@
int error;
struct sonode *nso = NULL;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
*nks = NULL;
if (!KSOCKET_VALID(ks))
@@ -157,6 +169,9 @@
ksocket_connect(ksocket_t ks, const struct sockaddr *addr, socklen_t addrlen,
struct cred *cr)
{
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks))
return (ENOTSOCK);
@@ -173,6 +188,9 @@
struct uio auio;
struct iovec iov;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks)) {
if (sent != NULL)
*sent = 0;
@@ -222,6 +240,9 @@
struct uio auio;
struct iovec iov;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks)) {
if (sent != NULL)
*sent = 0;
@@ -272,6 +293,9 @@
int i;
struct uio auio;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks)) {
if (sent != NULL)
*sent = 0;
@@ -323,6 +347,9 @@
struct uio auio;
struct iovec iov;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks)) {
if (recv != NULL)
*recv = 0;
@@ -373,6 +400,9 @@
struct uio auio;
struct iovec iov;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks)) {
if (recv != NULL)
*recv = 0;
@@ -425,6 +455,9 @@
int i;
struct uio auio;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks)) {
if (recv != NULL)
*recv = 0;
@@ -473,6 +506,9 @@
{
struct sonode *so;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks))
return (ENOTSOCK);
@@ -487,6 +523,9 @@
struct sonode *so;
so = KSTOSO(ks);
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
mutex_enter(&so->so_lock);
if (!KSOCKET_VALID(ks)) {
@@ -525,6 +564,9 @@
{
struct sonode *so;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks))
return (ENOTSOCK);
@@ -542,6 +584,9 @@
{
struct sonode *so;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks))
return (ENOTSOCK);
@@ -559,6 +604,9 @@
{
struct sonode *so;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks))
return (ENOTSOCK);
@@ -579,6 +627,9 @@
{
struct sonode *so;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks))
return (ENOTSOCK);
@@ -598,6 +649,9 @@
{
struct sonode *so;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks))
return (ENOTSOCK);
@@ -633,6 +687,9 @@
struct sonode *so;
int rval;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks))
return (ENOTSOCK);
@@ -670,6 +727,9 @@
mblk_t *mp = *mpp;
int error;
+ /* All Solaris components should pass a cred for this operation. */
+ ASSERT(cr != NULL);
+
if (!KSOCKET_VALID(ks))
return (ENOTSOCK);
@@ -677,7 +737,7 @@
if (flags & MSG_MBLK_QUICKRELE) {
error = socket_getsockopt(so, SOL_SOCKET, SO_SND_COPYAVOID,
- &i_val, &val_len, 0, CRED());
+ &i_val, &val_len, 0, cr);
if (error != 0)
return (error);
diff --git a/usr/src/uts/common/io/log.c b/usr/src/uts/common/io/log.c
index 9acd4c6..735283f 100644
--- a/usr/src/uts/common/io/log.c
+++ b/usr/src/uts/common/io/log.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,6 +32,7 @@
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/stropts.h>
+#include <sys/strsubr.h>
#include <sys/stream.h>
#include <sys/strsun.h>
#include <sys/debug.h>
@@ -160,7 +161,7 @@
log_t *lp = (log_t *)q->q_ptr;
struct iocblk *iocp;
mblk_t *mp2;
- cred_t *cr = DB_CRED(mp);
+ cred_t *cr = msg_getcred(mp, NULL);
zoneid_t zoneid;
/*
diff --git a/usr/src/uts/common/io/stream.c b/usr/src/uts/common/io/stream.c
index fb3941e..50dfbd3 100644
--- a/usr/src/uts/common/io/stream.c
+++ b/usr/src/uts/common/io/stream.c
@@ -447,43 +447,182 @@
return (mp);
}
+/*
+ * Allocate an mblk taking db_credp and db_cpid from the template.
+ * Allow the cred to be NULL.
+ */
mblk_t *
allocb_tmpl(size_t size, const mblk_t *tmpl)
{
mblk_t *mp = allocb(size, 0);
if (mp != NULL) {
- cred_t *cr = DB_CRED(tmpl);
+ dblk_t *src = tmpl->b_datap;
+ dblk_t *dst = mp->b_datap;
+ cred_t *cr = src->db_credp;
+
if (cr != NULL)
- crhold(mp->b_datap->db_credp = cr);
- DB_CPID(mp) = DB_CPID(tmpl);
- DB_TYPE(mp) = DB_TYPE(tmpl);
+ crhold(dst->db_credp = cr);
+ dst->db_cpid = src->db_cpid;
+ dst->db_type = src->db_type;
}
return (mp);
}
mblk_t *
-allocb_cred(size_t size, cred_t *cr)
+allocb_cred(size_t size, cred_t *cr, pid_t cpid)
{
mblk_t *mp = allocb(size, 0);
- if (mp != NULL && cr != NULL)
- crhold(mp->b_datap->db_credp = cr);
+ ASSERT(cr != NULL);
+ if (mp != NULL) {
+ dblk_t *dbp = mp->b_datap;
+ crhold(dbp->db_credp = cr);
+ dbp->db_cpid = cpid;
+ }
return (mp);
}
mblk_t *
-allocb_cred_wait(size_t size, uint_t flags, int *error, cred_t *cr)
+allocb_cred_wait(size_t size, uint_t flags, int *error, cred_t *cr, pid_t cpid)
{
mblk_t *mp = allocb_wait(size, 0, flags, error);
- if (mp != NULL && cr != NULL)
- crhold(mp->b_datap->db_credp = cr);
+ ASSERT(cr != NULL);
+ if (mp != NULL) {
+ dblk_t *dbp = mp->b_datap;
+
+ crhold(dbp->db_credp = cr);
+ dbp->db_cpid = cpid;
+ }
return (mp);
}
+/*
+ * Extract the db_cred (and optionally db_cpid) from a message.
+ * We find the first mblk which has a non-NULL db_cred and use that.
+ * If none found we return NULL.
+ * Does NOT get a hold on the cred.
+ */
+cred_t *
+msg_getcred(const mblk_t *mp, pid_t *cpidp)
+{
+ cred_t *cr = NULL;
+ cred_t *cr2;
+
+ while (mp != NULL) {
+ dblk_t *dbp = mp->b_datap;
+
+ cr = dbp->db_credp;
+ if (cr == NULL) {
+ mp = mp->b_cont;
+ continue;
+ }
+ if (cpidp != NULL)
+ *cpidp = dbp->db_cpid;
+
+#ifdef DEBUG
+ /*
+ * Normally there should at most one db_credp in a message.
+ * But if there are multiple (as in the case of some M_IOC*
+ * and some internal messages in TCP/IP bind logic) then
+ * they must be identical in the normal case.
+ * However, a socket can be shared between different uids
+ * in which case data queued in TCP would be from different
+ * creds. Thus we can only assert for the zoneid being the
+ * same. Due to Multi-level Level Ports for TX, some
+ * cred_t can have a NULL cr_zone, and we skip the comparison
+ * in that case.
+ */
+ cr2 = msg_getcred(mp->b_cont, NULL);
+ if (cr2 != NULL) {
+ DTRACE_PROBE2(msg__getcred,
+ cred_t *, cr, cred_t *, cr2);
+ ASSERT(crgetzoneid(cr) == crgetzoneid(cr2) ||
+ crgetzone(cr) == NULL ||
+ crgetzone(cr2) == NULL);
+ }
+#endif
+ return (cr);
+ }
+ if (cpidp != NULL)
+ *cpidp = NOPID;
+ return (NULL);
+}
+
+/*
+ * Variant of msg_getcred which, when a cred is found
+ * 1. Returns with a hold on the cred
+ * 2. Clears the first cred in the mblk.
+ * This is more efficient to use than a msg_getcred() + crhold() when
+ * the message is freed after the cred has been extracted.
+ *
+ * The caller is responsible for ensuring that there is no other reference
+ * on the message since db_credp can not be cleared when there are other
+ * references.
+ */
+cred_t *
+msg_extractcred(mblk_t *mp, pid_t *cpidp)
+{
+ cred_t *cr = NULL;
+ cred_t *cr2;
+
+ while (mp != NULL) {
+ dblk_t *dbp = mp->b_datap;
+
+ cr = dbp->db_credp;
+ if (cr == NULL) {
+ mp = mp->b_cont;
+ continue;
+ }
+ ASSERT(dbp->db_ref == 1);
+ dbp->db_credp = NULL;
+ if (cpidp != NULL)
+ *cpidp = dbp->db_cpid;
+#ifdef DEBUG
+ /*
+ * Normally there should at most one db_credp in a message.
+ * But if there are multiple (as in the case of some M_IOC*
+ * and some internal messages in TCP/IP bind logic) then
+ * they must be identical in the normal case.
+ * However, a socket can be shared between different uids
+ * in which case data queued in TCP would be from different
+ * creds. Thus we can only assert for the zoneid being the
+ * same. Due to Multi-level Level Ports for TX, some
+ * cred_t can have a NULL cr_zone, and we skip the comparison
+ * in that case.
+ */
+ cr2 = msg_getcred(mp->b_cont, NULL);
+ if (cr2 != NULL) {
+ DTRACE_PROBE2(msg__extractcred,
+ cred_t *, cr, cred_t *, cr2);
+ ASSERT(crgetzoneid(cr) == crgetzoneid(cr2) ||
+ crgetzone(cr) == NULL ||
+ crgetzone(cr2) == NULL);
+ }
+#endif
+ return (cr);
+ }
+ return (NULL);
+}
+/*
+ * Get the label for a message. Uses the first mblk in the message
+ * which has a non-NULL db_credp.
+ * Returns NULL if there is no credp.
+ */
+extern struct ts_label_s *
+msg_getlabel(const mblk_t *mp)
+{
+ cred_t *cr = msg_getcred(mp, NULL);
+
+ if (cr == NULL)
+ return (NULL);
+
+ return (crgetlabel(cr));
+}
+
void
freeb(mblk_t *mp)
{
diff --git a/usr/src/uts/common/io/strsun.c b/usr/src/uts/common/io/strsun.c
index 23389c0..db6e4aa 100644
--- a/usr/src/uts/common/io/strsun.c
+++ b/usr/src/uts/common/io/strsun.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Solaris DDI STREAMS utility routines (PSARC/2003/648).
*
@@ -281,13 +278,12 @@
blocksize = MIN(iosize, maxblk);
ASSERT(blocksize >= 0);
if ((mp = allocb_cred(offset + blocksize + tail_len,
- CRED())) == NULL) {
+ CRED(), curproc->p_pid)) == NULL) {
*errorp = ENOMEM;
return (head);
}
mp->b_rptr += offset;
mp->b_wptr = mp->b_rptr + blocksize;
- DB_CPID(mp) = curproc->p_pid;
*tail = mp;
tail = &mp->b_cont;
diff --git a/usr/src/uts/common/io/timod.c b/usr/src/uts/common/io/timod.c
index 1f99017..4d9e4ea 100644
--- a/usr/src/uts/common/io/timod.c
+++ b/usr/src/uts/common/io/timod.c
@@ -20,15 +20,13 @@
*/
/* ONC_PLUS EXTRACT START */
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Transport Interface Library cooperating module - issue 2
*/
@@ -662,7 +660,7 @@
tp = (struct tim_tim *)q->q_ptr;
if (!tp)
- return;
+ return;
while ((mp = getq(q)) != NULL) {
if (timodrproc(q, mp)) {
@@ -852,9 +850,8 @@
if (ntp->tim_peercred != NULL)
crfree(ntp->tim_peercred);
ntp->tim_peercred =
- DB_CRED(tp->tim_iocsave->b_cont);
- ntp->tim_cpid =
- DB_CPID(tp->tim_iocsave->b_cont);
+ msg_getcred(tp->tim_iocsave->b_cont,
+ &ntp->tim_cpid);
if (ntp->tim_peercred != NULL)
crhold(ntp->tim_peercred);
@@ -922,7 +919,7 @@
if (((tp->tim_flags & WAITIOCACK) == 0) ||
((tp->tim_saved_prim != O_T_BIND_REQ) &&
- (tp->tim_saved_prim != T_BIND_REQ))) {
+ (tp->tim_saved_prim != T_BIND_REQ))) {
putnext(q, mp);
break;
}
@@ -970,7 +967,7 @@
}
/* ONC_PLUS EXTRACT END */
- case T_OPTMGMT_ACK:
+ case T_OPTMGMT_ACK:
tilog("timodrproc: Got T_OPTMGMT_ACK\n", 0);
@@ -992,23 +989,23 @@
break;
case T_INFO_ACK: {
- struct T_info_ack *tia = (struct T_info_ack *)pptr;
+ struct T_info_ack *tia = (struct T_info_ack *)pptr;
- /* Restore db_type - recover() might have changed it */
- mp->b_datap->db_type = M_PCPROTO;
+ /* Restore db_type - recover() might have changed it */
+ mp->b_datap->db_type = M_PCPROTO;
- if (blen < sizeof (*tia)) {
+ if (blen < sizeof (*tia)) {
putnext(q, mp);
break;
- }
+ }
- tilog("timodrproc: Got T_INFO_ACK, flags = %x\n",
- tp->tim_flags);
+ tilog("timodrproc: Got T_INFO_ACK, flags = %x\n",
+ tp->tim_flags);
- timodprocessinfo(q, tp, tia);
+ timodprocessinfo(q, tp, tia);
- TILOG("timodrproc: flags = %x\n", tp->tim_flags);
- if ((tp->tim_flags & WAITIOCACK) != 0) {
+ TILOG("timodrproc: flags = %x\n", tp->tim_flags);
+ if ((tp->tim_flags & WAITIOCACK) != 0) {
size_t expected_ack_size;
ssize_t deficit;
int ioc_cmd;
@@ -1100,7 +1097,7 @@
}
expected_ack_size =
- sizeof (struct T_info_ack); /* TI_GETINFO */
+ sizeof (struct T_info_ack); /* TI_GETINFO */
if (iocbp->ioc_cmd == TI_SYNC) {
expected_ack_size = 2 * sizeof (uint32_t) +
sizeof (struct ti_sync_ack);
@@ -1110,8 +1107,8 @@
if (deficit != 0) {
if (mp->b_datap->db_lim - mp->b_wptr <
deficit) {
- mblk_t *tmp = allocb(expected_ack_size,
- BPRI_HI);
+ mblk_t *tmp = allocb(expected_ack_size,
+ BPRI_HI);
if (tmp == NULL) {
ASSERT(MBLKSIZE(mp) >=
sizeof (struct T_error_ack));
@@ -1121,7 +1118,7 @@
mp->b_rptr = mp->b_datap->db_base;
pptr = (union T_primitives *)
- mp->b_rptr;
+ mp->b_rptr;
pptr->error_ack.ERROR_prim = T_INFO_REQ;
pptr->error_ack.TLI_error = TSYSERR;
pptr->error_ack.UNIX_error = EAGAIN;
@@ -1190,7 +1187,7 @@
tp->tim_flags &= ~(WAITIOCACK | WAIT_IOCINFOACK |
TI_CAP_RECVD | CAP_WANTS_INFO);
break;
- }
+ }
}
putnext(q, mp);
@@ -1233,10 +1230,9 @@
mutex_enter(&tp->tim_mutex);
if (tp->tim_peercred != NULL)
crfree(tp->tim_peercred);
- tp->tim_peercred = DB_CRED(mp);
+ tp->tim_peercred = msg_getcred(mp, &tp->tim_cpid);
if (tp->tim_peercred != NULL)
crhold(tp->tim_peercred);
- tp->tim_cpid = DB_CPID(mp);
mutex_exit(&tp->tim_mutex);
tilog("timodrproc: Got T_CONN_CON\n", 0);
@@ -1261,23 +1257,23 @@
disp = (struct T_discon_ind *)mp->b_rptr;
tilog("timodrproc: Got T_DISCON_IND Reason: %d\n",
- disp->DISCON_reason);
+ disp->DISCON_reason);
tp->tim_flags &= ~(CONNWAIT|LOCORDREL|REMORDREL);
tim_clear_peer(tp);
for (nbp = tp->tim_consave; nbp; nbp = nbp->b_next) {
- conp = (struct T_conn_ind *)nbp->b_rptr;
- if (conp->SEQ_number == disp->SEQ_number)
- break;
- pbp = nbp;
+ conp = (struct T_conn_ind *)nbp->b_rptr;
+ if (conp->SEQ_number == disp->SEQ_number)
+ break;
+ pbp = nbp;
}
if (nbp) {
- if (pbp)
- pbp->b_next = nbp->b_next;
- else
- tp->tim_consave = nbp->b_next;
- nbp->b_next = NULL;
- freemsg(nbp);
+ if (pbp)
+ pbp->b_next = nbp->b_next;
+ else
+ tp->tim_consave = nbp->b_next;
+ nbp->b_next = NULL;
+ freemsg(nbp);
}
putnext(q, mp);
break;
@@ -1596,7 +1592,7 @@
ASSERT(q != NULL);
if (q->q_ptr == NULL)
- return;
+ return;
while ((mp = getq(q)) != NULL) {
if (timodwproc(q, mp)) {
@@ -1688,7 +1684,7 @@
if (cmp != NULL &&
iocbp->ioc_flag == IOC_NATIVE &&
(tp->tim_flags &
- (CONNWAIT|LOCORDREL|REMORDREL)) == 0 &&
+ (CONNWAIT|LOCORDREL|REMORDREL)) == 0 &&
tp->tim_peercred != NULL &&
DB_TYPE(cmp) == M_DATA &&
MBLKL(cmp) == sizeof (k_peercred_t)) {
@@ -2675,9 +2671,9 @@
*/
if ((bp->b_datap->db_type == M_PROTO) &&
((bp->b_wptr - bp->b_rptr) >=
- sizeof (struct T_exdata_ind)) &&
+ sizeof (struct T_exdata_ind)) &&
(((struct T_exdata_ind *)bp->b_rptr)->PRIM_type
- == T_EXDATA_IND)) {
+ == T_EXDATA_IND)) {
/* bp is T_EXDATA_IND */
mutex_exit(QLOCK(rq));
releasestr(q); /* decrement sd_refcnt */
@@ -3012,6 +3008,8 @@
/* Verify credentials in STREAM */
ASSERT(iocb->ioc_cr == NULL || iocb->ioc_cr == DB_CRED(tmp));
+ ASSERT(DB_CRED(tmp) != NULL);
+
TILOG("timodwproc: sending down %d\n", tp->tim_saved_prim);
putnext(q, tmp);
}
diff --git a/usr/src/uts/common/io/tl.c b/usr/src/uts/common/io/tl.c
index 97da83a..7ddb24c 100644
--- a/usr/src/uts/common/io/tl.c
+++ b/usr/src/uts/common/io/tl.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -674,8 +674,6 @@
#define IS_COTSORD(x) (((x)->te_flag & TL_TICOTSORD) != 0)
#define IS_SOCKET(x) (((x)->te_flag & TL_SOCKET) != 0)
-#define TLPID(mp, tep) (DB_CPID(mp) == -1 ? (tep)->te_cpid : DB_CPID(mp))
-
/*
* Certain operations are always used together. These macros reduce the chance
* of missing a part of a combination.
@@ -2742,10 +2740,25 @@
tl_endpt_t *tep;
mblk_t *ackmp;
union T_primitives *prim;
+ cred_t *cr;
tep = (tl_endpt_t *)wq->q_ptr;
prim = (union T_primitives *)mp->b_rptr;
+ /*
+ * All Solaris components should pass a db_credp
+ * for this TPI message, hence we ASSERT.
+ * But in case there is some other M_PROTO that looks
+ * like a TPI message sent by some other kernel
+ * component, we check and return an error.
+ */
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+ if (cr == NULL) {
+ tl_error_ack(wq, mp, TSYSERR, EINVAL, prim->type);
+ return;
+ }
+
/* all states OK for AF_UNIX options ? */
if (!IS_SOCKET(tep) && tep->te_state != TS_IDLE &&
prim->type == T_SVR4_OPTMGMT_REQ) {
@@ -2776,11 +2789,11 @@
* call common option management routine from drv/ip
*/
if (prim->type == T_SVR4_OPTMGMT_REQ) {
- (void) svr4_optcom_req(wq, mp, tep->te_credp, &tl_opt_obj,
+ (void) svr4_optcom_req(wq, mp, cr, &tl_opt_obj,
B_FALSE);
} else {
ASSERT(prim->type == T_OPTMGMT_REQ);
- (void) tpi_optcom_req(wq, mp, tep->te_credp, &tl_opt_obj,
+ (void) tpi_optcom_req(wq, mp, cr, &tl_opt_obj,
B_FALSE);
}
}
@@ -3199,8 +3212,7 @@
if (peer_tep != NULL && peer_tep->te_credp != NULL &&
confmp != NULL) {
- mblk_setcred(confmp, peer_tep->te_credp);
- DB_CPID(confmp) = peer_tep->te_cpid;
+ mblk_setcred(confmp, peer_tep->te_credp, peer_tep->te_cpid);
}
tl_ok_ack(wq, ackmp, T_CONN_REQ);
@@ -3238,12 +3250,16 @@
addr_startp = cimp->b_rptr + ci->SRC_offset;
bcopy(tep->te_abuf, addr_startp, tep->te_alen);
if (peer_tep->te_flag & (TL_SETCRED|TL_SETUCRED)) {
+ cred_t *cr;
+ pid_t cpid;
+
ci->OPT_offset = (t_scalar_t)T_ALIGN(ci->SRC_offset +
ci->SRC_length);
ci->OPT_length = olen; /* because only 1 option */
+ cr = msg_getcred(cimp, &cpid);
+ ASSERT(cr != NULL);
tl_fill_option(cimp->b_rptr + ci->OPT_offset,
- DB_CREDDEF(cimp, tep->te_credp),
- TLPID(cimp, tep),
+ cr, cpid,
peer_tep->te_flag, peer_tep->te_credp);
} else if (ooff != 0) {
/* Copy option from T_CONN_REQ */
@@ -3735,8 +3751,7 @@
* Forward the credential in the packet so it can be picked up
* at the higher layers for more complete credential processing
*/
- mblk_setcred(ccmp, acc_ep->te_credp);
- DB_CPID(ccmp) = acc_ep->te_cpid;
+ mblk_setcred(ccmp, acc_ep->te_credp, acc_ep->te_cpid);
} else {
freemsg(respmp);
respmp = NULL;
@@ -5205,15 +5220,20 @@
(t_scalar_t)T_ALIGN(udind->SRC_offset + udind->SRC_length);
udind->OPT_length = olen;
if (peer_tep->te_flag & (TL_SETCRED|TL_SETUCRED|TL_SOCKUCRED)) {
+ cred_t *cr;
+ pid_t cpid;
+
if (oldolen != 0) {
bcopy((void *)((uintptr_t)udreq + ooff),
(void *)((uintptr_t)udind +
udind->OPT_offset),
oldolen);
}
+ cr = msg_getcred(mp, &cpid);
+ ASSERT(cr != NULL);
+
tl_fill_option(ui_mp->b_rptr + udind->OPT_offset +
- oldolen,
- DB_CREDDEF(mp, tep->te_credp), TLPID(mp, tep),
+ oldolen, cr, cpid,
peer_tep->te_flag, peer_tep->te_credp);
} else {
bcopy((void *)((uintptr_t)udreq + ooff),
@@ -5941,6 +5961,8 @@
static void
tl_fill_option(uchar_t *buf, cred_t *cr, pid_t cpid, int flag, cred_t *pcr)
{
+ ASSERT(cr != NULL);
+
if (flag & TL_SETCRED) {
struct opthdr *opt = (struct opthdr *)buf;
tl_credopt_t *tlcred;
diff --git a/usr/src/uts/common/ipp/flowacct/flowacct.c b/usr/src/uts/common/ipp/flowacct/flowacct.c
index 7249c74..ad20861 100644
--- a/usr/src/uts/common/ipp/flowacct/flowacct.c
+++ b/usr/src/uts/common/ipp/flowacct/flowacct.c
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/kmem.h>
#include <sys/conf.h>
@@ -41,6 +39,7 @@
#include <inet/ip6.h>
#include <sys/ddi.h>
#include <sys/strsun.h>
+#include <sys/strsubr.h>
#include <ipp/flowacct/flowacct_impl.h>
/*
@@ -212,10 +211,8 @@
{
cred_t *cr;
- while (DB_CRED(mp) == NULL && mp->b_cont != NULL)
- mp = mp->b_cont;
-
- if ((cr = DB_CRED(mp)) != NULL) {
+ cr = msg_getcred(mp, NULL);
+ if (cr != NULL) {
header->uid = crgetuid(cr);
header->projid = crgetprojid(cr);
} else {
diff --git a/usr/src/uts/common/ipp/ipgpc/classifier.c b/usr/src/uts/common/ipp/ipgpc/classifier.c
index 9137fcb..5d6906e 100644
--- a/usr/src/uts/common/ipp/ipgpc/classifier.c
+++ b/usr/src/uts/common/ipp/ipgpc/classifier.c
@@ -27,6 +27,7 @@
#include <sys/kmem.h>
#include <sys/systm.h>
#include <sys/socket.h>
+#include <sys/strsubr.h>
#include <sys/strsun.h>
#include <netinet/in.h>
#include <ipp/ipgpc/classifier.h>
@@ -588,10 +589,8 @@
{
cred_t *cr;
- while (DB_CRED(mp) == NULL && mp->b_cont != NULL)
- mp = mp->b_cont;
-
- if ((cr = DB_CRED(mp)) != NULL) {
+ cr = msg_getcred(mp, NULL);
+ if (cr != NULL) {
packet->uid = crgetuid(cr);
packet->projid = crgetprojid(cr);
} else {
diff --git a/usr/src/uts/common/ktli/t_kconnect.c b/usr/src/uts/common/ktli/t_kconnect.c
index cf8dbf4..af7fdaa 100644
--- a/usr/src/uts/common/ktli/t_kconnect.c
+++ b/usr/src/uts/common/ktli/t_kconnect.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,8 +36,6 @@
* contributors.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Kernel TLI-like function to allow a trasnport endpoint to initiate a
* connection to another transport endpoint. This function will wait for
@@ -85,8 +83,20 @@
fp = tiptr->fp;
msgsz = (int)TCONNREQSZ;
- while (!(bp = allocb(msgsz + sndcall->addr.len + sndcall->opt.len,
- BPRI_LO))) {
+ /*
+ * Usually connect()s are performed with the credential of the caller;
+ * in this particular case we specifically use the credential of
+ * the opener as this call is typically done in the context of a user
+ * process but on behalf of the kernel, e.g., a client connection
+ * to a server which is later shared by different users.
+ * At open time, we make sure to set fp->f_cred to kcred if such is
+ * the case.
+ *
+ * Note: if the receiver uses SCM_UCRED/getpeerucred the pid will
+ * appear as -1.
+ */
+ while (!(bp = allocb_cred(msgsz + sndcall->addr.len + sndcall->opt.len,
+ fp->f_cred, NOPID))) {
if (strwaitbuf(msgsz + sndcall->addr.len + sndcall->opt.len,
BPRI_LO))
return (ENOSR);
diff --git a/usr/src/uts/common/ktli/t_ksndudat.c b/usr/src/uts/common/ktli/t_ksndudat.c
index 24a258f..c5d4435 100644
--- a/usr/src/uts/common/ktli/t_ksndudat.c
+++ b/usr/src/uts/common/ktli/t_ksndudat.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,8 +36,6 @@
* contributors.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* TLI-like function to send datagrams over a specified
* transport endpoint.
@@ -131,8 +128,20 @@
*/
gotdp:
msgsz = (int)TUNITDATAREQSZ;
- while (!(bp = allocb(msgsz + unitdata->addr.len + unitdata->opt.len,
- BPRI_LO))) {
+ /*
+ * Usually sendto()s are performed with the credential of the caller;
+ * in this particular case we specifically use the credential of
+ * the opener as this call is typically done in the context of a user
+ * process but on behalf of the kernel, e.g., a client connection
+ * to a server which is later shared by different users.
+ * At open time, we make sure to set fp->f_cred to kcred if such is
+ * the case.
+ *
+ * Note: if the receiver uses SCM_UCRED/getpeerucred the pid will
+ * appear as -1.
+ */
+ while (!(bp = allocb_cred(msgsz + unitdata->addr.len +
+ unitdata->opt.len, fp->f_cred, NOPID))) {
if (strwaitbuf(msgsz + unitdata->addr.len + unitdata->opt.len,
BPRI_LO)) {
if (dbp && (dbp != unitdata->udata.udata_mp))
diff --git a/usr/src/uts/common/os/driver_lyr.c b/usr/src/uts/common/os/driver_lyr.c
index b08efe1..217e289 100644
--- a/usr/src/uts/common/os/driver_lyr.c
+++ b/usr/src/uts/common/os/driver_lyr.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Layered driver support.
*/
@@ -2170,6 +2168,13 @@
return (ENOTSUP);
}
+ /*
+ * If we don't have db_credp, set it. Note that we can not be called
+ * from interrupt context.
+ */
+ if (msg_getcred(smp, NULL) == NULL)
+ mblk_setcred(smp, CRED(), curproc->p_pid);
+
/* Send message while honoring flow control */
ret = kstrputmsg(handlep->lh_vp, smp, NULL, 0, 0,
MSG_BAND | MSG_HOLDSIG | MSG_IGNERROR, 0);
diff --git a/usr/src/uts/common/os/streamio.c b/usr/src/uts/common/os/streamio.c
index 2b7daaa..e4744da 100644
--- a/usr/src/uts/common/os/streamio.c
+++ b/usr/src/uts/common/os/streamio.c
@@ -2566,7 +2566,7 @@
/*
* Copyin and send data down a stream.
* The caller will allocate and copyin any control part that precedes the
- * message and pass than in as mctl.
+ * message and pass that in as mctl.
*
* Caller should *not* hold sd_lock.
* When EWOULDBLOCK is returned the caller has to redo the canputnext
@@ -2591,7 +2591,6 @@
queue_t *wqp = stp->sd_wrq;
int error = 0;
ssize_t count = *iosize;
- cred_t *cr;
ASSERT(MUTEX_NOT_HELD(&stp->sd_lock));
@@ -2634,14 +2633,6 @@
else if (mp != NULL)
linkb(mctl, mp);
mp = mctl;
- /*
- * Note that for interrupt thread, the CRED() is
- * NULL. Don't bother with the pid either.
- */
- if ((cr = CRED()) != NULL) {
- mblk_setcred(mp, cr);
- DB_CPID(mp) = curproc->p_pid;
- }
} else if (mp == NULL)
return (0);
@@ -2680,14 +2671,6 @@
else if (mp != NULL)
linkb(mctl, mp);
mp = mctl;
- /*
- * Note that for interrupt thread, the CRED() is
- * NULL. Don't bother with the pid either.
- */
- if ((cr = CRED()) != NULL) {
- mblk_setcred(mp, cr);
- DB_CPID(mp) = curproc->p_pid;
- }
} else if (mp == NULL) {
return (0);
}
@@ -5961,7 +5944,7 @@
return (EINVAL);
if ((bp = allocb_cred_wait(sizeof (union ioctypes), sigflag, &error,
- crp)) == NULL)
+ crp, curproc->p_pid)) == NULL)
return (error);
bzero(bp->b_wptr, sizeof (union ioctypes));
@@ -5974,7 +5957,6 @@
crhold(crp);
iocbp->ioc_cr = crp;
DB_TYPE(bp) = M_IOCTL;
- DB_CPID(bp) = curproc->p_pid;
bp->b_wptr += sizeof (struct iocblk);
if (flag & STR_NOERROR)
@@ -6320,8 +6302,7 @@
bp->b_wptr = bp->b_rptr + sizeof (struct copyresp);
bp->b_datap->db_type = M_IOCDATA;
- mblk_setcred(bp, crp);
- DB_CPID(bp) = curproc->p_pid;
+ mblk_setcred(bp, crp, curproc->p_pid);
resp = (struct copyresp *)bp->b_rptr;
resp->cp_rval = (caddr_t)(uintptr_t)error;
resp->cp_flag = (fflags & FMODELS);
@@ -6365,8 +6346,7 @@
bp->b_wptr = bp->b_rptr + sizeof (struct copyresp);
bp->b_datap->db_type = M_IOCDATA;
- mblk_setcred(bp, crp);
- DB_CPID(bp) = curproc->p_pid;
+ mblk_setcred(bp, crp, curproc->p_pid);
resp = (struct copyresp *)bp->b_rptr;
resp->cp_rval = (caddr_t)(uintptr_t)error;
resp->cp_flag = (fflags & FMODELS);
@@ -6421,7 +6401,8 @@
if (scp->sc_timeout > 0)
timeout = scp->sc_timeout * MILLISEC;
- if ((mp = allocb_cred(sizeof (struct cmdblk), crp)) == NULL)
+ if ((mp = allocb_cred(sizeof (struct cmdblk), crp,
+ curproc->p_pid)) == NULL)
return (ENOMEM);
crhold(crp);
@@ -6440,7 +6421,8 @@
* Copy in the payload.
*/
if (cmdp->cb_len > 0) {
- mp->b_cont = allocb_cred(sizeof (scp->sc_buf), crp);
+ mp->b_cont = allocb_cred(sizeof (scp->sc_buf), crp,
+ curproc->p_pid);
if (mp->b_cont == NULL) {
error = ENOMEM;
goto out;
diff --git a/usr/src/uts/common/os/strsubr.c b/usr/src/uts/common/os/strsubr.c
index 0ae1dd9..61e8ca1 100644
--- a/usr/src/uts/common/os/strsubr.c
+++ b/usr/src/uts/common/os/strsubr.c
@@ -1464,8 +1464,8 @@
*/
ASSERT(count >= 0);
- if ((tmp = allocb_cred_wait(count, (flag & STR_NOSIG), &error, cr)) ==
- NULL) {
+ if ((tmp = allocb_cred_wait(count, (flag & STR_NOSIG), &error, cr,
+ curproc->p_pid)) == NULL) {
return (error);
}
error = strcopyin(arg, tmp->b_wptr, count, flag & (U_TO_K|K_TO_K));
@@ -2793,6 +2793,10 @@
mblk_t *bp = NULL;
unsigned char msgtype;
int error = 0;
+ cred_t *cr = CRED();
+
+ /* We do not support interrupt threads using the stream head to send */
+ ASSERT(cr != NULL);
*mpp = NULL;
/*
@@ -2821,7 +2825,8 @@
* Range checking has already been done; simply try
* to allocate a message block for the ctl part.
*/
- while (!(bp = allocb(allocsz, BPRI_MED))) {
+ while ((bp = allocb_cred(allocsz, cr,
+ curproc->p_pid)) == NULL) {
if (fflag & (FNDELAY|FNONBLOCK))
return (EAGAIN);
if (error = strwaitbuf(allocsz, BPRI_MED))
@@ -2864,12 +2869,16 @@
int error = 0;
ssize_t maxblk;
ssize_t count = *iosize;
- cred_t *cr = CRED();
+ cred_t *cr;
*mpp = NULL;
if (count < 0)
return (0);
+ /* We do not support interrupt threads using the stream head to send */
+ cr = CRED();
+ ASSERT(cr != NULL);
+
maxblk = stp->sd_maxblk;
if (maxblk == INFPSZ)
maxblk = count;
@@ -2885,7 +2894,8 @@
size = MIN(count, maxblk);
- while ((bp = allocb_cred(size + extra, cr)) == NULL) {
+ while ((bp = allocb_cred(size + extra, cr,
+ curproc->p_pid)) == NULL) {
error = EAGAIN;
if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) ||
(error = strwaitbuf(size + extra, BPRI_MED)) != 0) {
@@ -8383,34 +8393,51 @@
/*
* Replace the cred currently in the mblk with a different one.
+ * Also update db_cpid.
*/
void
-mblk_setcred(mblk_t *mp, cred_t *cr)
+mblk_setcred(mblk_t *mp, cred_t *cr, pid_t cpid)
{
- cred_t *ocr = DB_CRED(mp);
+ dblk_t *dbp = mp->b_datap;
+ cred_t *ocr = dbp->db_credp;
ASSERT(cr != NULL);
if (cr != ocr) {
- crhold(mp->b_datap->db_credp = cr);
+ crhold(dbp->db_credp = cr);
if (ocr != NULL)
crfree(ocr);
}
+ /* Don't overwrite with NOPID */
+ if (cpid != NOPID)
+ dbp->db_cpid = cpid;
}
/*
- * Set the cred and pid for each mblk in the message. It is assumed that
- * the message passed in does not already have a cred.
+ * If the src message has a cred, then replace the cred currently in the mblk
+ * with it.
+ * Also update db_cpid.
*/
void
-msg_setcredpid(mblk_t *mp, cred_t *cr, pid_t pid)
+mblk_copycred(mblk_t *mp, const mblk_t *src)
{
- while (mp != NULL) {
- ASSERT(DB_CRED(mp) == NULL);
- mblk_setcred(mp, cr);
- DB_CPID(mp) = pid;
- mp = mp->b_cont;
+ dblk_t *dbp = mp->b_datap;
+ cred_t *cr, *ocr;
+ pid_t cpid;
+
+ cr = msg_getcred(src, &cpid);
+ if (cr == NULL)
+ return;
+
+ ocr = dbp->db_credp;
+ if (cr != ocr) {
+ crhold(dbp->db_credp = cr);
+ if (ocr != NULL)
+ crfree(ocr);
}
+ /* Don't overwrite with NOPID */
+ if (cpid != NOPID)
+ dbp->db_cpid = cpid;
}
int
diff --git a/usr/src/uts/common/rpc/clnt_clts.c b/usr/src/uts/common/rpc/clnt_clts.c
index 70c16c6..e42d156 100644
--- a/usr/src/uts/common/rpc/clnt_clts.c
+++ b/usr/src/uts/common/rpc/clnt_clts.c
@@ -172,7 +172,7 @@
* Request dipatching function.
*/
static int clnt_clts_dispatch_send(queue_t *q, mblk_t *, struct netbuf *addr,
- calllist_t *, uint_t);
+ calllist_t *, uint_t, cred_t *);
/*
* The size of the preserialized RPC header information.
@@ -582,7 +582,7 @@
round_trip = lbolt;
error = clnt_clts_dispatch_send(p->cku_endpnt->e_wq, mp,
- &p->cku_addr, call, p->cku_xid);
+ &p->cku_addr, call, p->cku_xid, p->cku_cred);
if (error != 0) {
freemsg(mp);
@@ -2058,7 +2058,7 @@
*/
static int
clnt_clts_dispatch_send(queue_t *q, mblk_t *mp, struct netbuf *addr,
- calllist_t *cp, uint_t xid)
+ calllist_t *cp, uint_t xid, cred_t *cr)
{
mblk_t *bp;
int msgsz;
@@ -2082,7 +2082,11 @@
* Construct the datagram
*/
msgsz = (int)TUNITDATAREQSZ;
- while (!(bp = allocb(msgsz + addr->len, BPRI_LO))) {
+ /*
+ * Note: if the receiver uses SCM_UCRED/getpeerucred the pid will
+ * appear as -1.
+ */
+ while (!(bp = allocb_cred(msgsz + addr->len, cr, NOPID))) {
if (strwaitbuf(msgsz + addr->len, BPRI_LO))
return (ENOSR);
}
diff --git a/usr/src/uts/common/rpc/clnt_cots.c b/usr/src/uts/common/rpc/clnt_cots.c
index 8cb5672..3bbf31e 100644
--- a/usr/src/uts/common/rpc/clnt_cots.c
+++ b/usr/src/uts/common/rpc/clnt_cots.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -375,13 +375,13 @@
static struct cm_xprt *connmgr_wrapconnect(struct cm_xprt *,
const struct timeval *, struct netbuf *, int, struct netbuf *,
- struct rpc_err *, bool_t, bool_t);
+ struct rpc_err *, bool_t, bool_t, cred_t *);
static bool_t connmgr_connect(struct cm_xprt *, queue_t *, struct netbuf *,
int, calllist_t *, int *, bool_t reconnect,
- const struct timeval *, bool_t);
+ const struct timeval *, bool_t, cred_t *);
-static bool_t connmgr_setopt(queue_t *, int, int, calllist_t *);
+static bool_t connmgr_setopt(queue_t *, int, int, calllist_t *, cred_t *cr);
static void connmgr_sndrel(struct cm_xprt *);
static void connmgr_snddis(struct cm_xprt *);
static void connmgr_close(struct cm_xprt *);
@@ -391,7 +391,7 @@
static struct cm_xprt *connmgr_get(struct netbuf *, const struct timeval *,
struct netbuf *, int, struct netbuf *, struct rpc_err *, dev_t,
- bool_t, int);
+ bool_t, int, cred_t *);
static void connmgr_cancelconn(struct cm_xprt *);
static enum clnt_stat connmgr_cwait(struct cm_xprt *, const struct timeval *,
@@ -1708,7 +1708,7 @@
cm_entry = connmgr_get(retryaddr, waitp, &p->cku_addr, p->cku_addrfmly,
&p->cku_srcaddr, &p->cku_err, p->cku_device,
- p->cku_client.cl_nosignal, p->cku_useresvport);
+ p->cku_client.cl_nosignal, p->cku_useresvport, p->cku_cred);
if (cm_entry == NULL) {
/*
@@ -1745,7 +1745,8 @@
struct rpc_err *rpcerr,
dev_t device,
bool_t nosignal,
- int useresvport)
+ int useresvport,
+ cred_t *cr)
{
struct cm_xprt *cm_entry;
struct cm_xprt *lru_entry;
@@ -1840,7 +1841,7 @@
*/
return (connmgr_wrapconnect(cm_entry,
waitp, destaddr, addrfmly, srcaddr,
- rpcerr, TRUE, nosignal));
+ rpcerr, TRUE, nosignal, cr));
}
i++;
if (cm_entry->x_time - prev_time <= 0 ||
@@ -1941,7 +1942,7 @@
if (cm_entry->x_connected == FALSE) {
return (connmgr_wrapconnect(cm_entry,
waitp, destaddr, addrfmly, NULL,
- rpcerr, TRUE, nosignal));
+ rpcerr, TRUE, nosignal, cr));
} else {
CONN_HOLD(cm_entry);
@@ -2127,7 +2128,7 @@
* This is a bound end-point so don't close it's stream.
*/
connected = connmgr_connect(cm_entry, wq, destaddr, addrfmly,
- &call, &tidu_size, FALSE, waitp, nosignal);
+ &call, &tidu_size, FALSE, waitp, nosignal, cr);
*rpcerr = call.call_err;
cv_destroy(&call.call_cv);
@@ -2214,7 +2215,8 @@
struct netbuf *srcaddr,
struct rpc_err *rpcerr,
bool_t reconnect,
- bool_t nosignal)
+ bool_t nosignal,
+ cred_t *cr)
{
ASSERT(MUTEX_HELD(&connmgr_lock));
/*
@@ -2261,7 +2263,7 @@
connected = connmgr_connect(cm_entry, cm_entry->x_wq,
destaddr, addrfmly, &call, &cm_entry->x_tidu_size,
- reconnect, waitp, nosignal);
+ reconnect, waitp, nosignal, cr);
*rpcerr = call.call_err;
cv_destroy(&call.call_cv);
@@ -2484,7 +2486,8 @@
int *tidu_ptr,
bool_t reconnect,
const struct timeval *waitp,
- bool_t nosignal)
+ bool_t nosignal,
+ cred_t *cr)
{
mblk_t *mp;
struct T_conn_req *tcr;
@@ -2496,7 +2499,11 @@
if (reconnect)
(void) putctl1(wq, M_FLUSH, FLUSHRW);
- mp = allocb(sizeof (*tcr) + addr->len, BPRI_LO);
+ /*
+ * Note: if the receiver uses SCM_UCRED/getpeerucred the pid will
+ * appear as -1.
+ */
+ mp = allocb_cred(sizeof (*tcr) + addr->len, cr, NOPID);
if (mp == NULL) {
/*
* This is unfortunate, but we need to look up the stats for
@@ -2625,7 +2632,7 @@
* lots of retries and terrible performance.
*/
if (addrfmly == AF_INET || addrfmly == AF_INET6) {
- (void) connmgr_setopt(wq, IPPROTO_TCP, TCP_NODELAY, e);
+ (void) connmgr_setopt(wq, IPPROTO_TCP, TCP_NODELAY, e, cr);
if (e->call_status == RPC_XPRTFAILED)
return (FALSE);
}
@@ -2673,7 +2680,7 @@
* Called by connmgr_connect to set an option on the new stream.
*/
static bool_t
-connmgr_setopt(queue_t *wq, int level, int name, calllist_t *e)
+connmgr_setopt(queue_t *wq, int level, int name, calllist_t *e, cred_t *cr)
{
mblk_t *mp;
struct opthdr *opt;
@@ -2681,8 +2688,8 @@
struct timeval waitp;
int error;
- mp = allocb(sizeof (struct T_optmgmt_req) + sizeof (struct opthdr) +
- sizeof (int), BPRI_LO);
+ mp = allocb_cred(sizeof (struct T_optmgmt_req) +
+ sizeof (struct opthdr) + sizeof (int), cr, NOPID);
if (mp == NULL) {
RPCLOG0(1, "connmgr_setopt: cannot alloc mp for option "
"request\n");
diff --git a/usr/src/uts/common/rpc/rpcmod.c b/usr/src/uts/common/rpc/rpcmod.c
index 69eac32..e3576c9 100644
--- a/usr/src/uts/common/rpc/rpcmod.c
+++ b/usr/src/uts/common/rpc/rpcmod.c
@@ -35,6 +35,7 @@
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/stropts.h>
+#include <sys/strsubr.h>
#include <sys/tihdr.h>
#include <sys/timod.h>
#include <sys/tiuser.h>
@@ -482,8 +483,8 @@
/*
* Allocate the required messages upfront.
*/
- if ((bp = allocb(sizeof (struct T_info_req) +
- sizeof (struct T_info_ack), BPRI_LO)) == (mblk_t *)NULL) {
+ if ((bp = allocb_cred(sizeof (struct T_info_req) +
+ sizeof (struct T_info_ack), crp, curproc->p_pid)) == NULL) {
return (ENOBUFS);
}
diff --git a/usr/src/uts/common/rpc/svc.c b/usr/src/uts/common/rpc/svc.c
index 4f8878d..e33b77b 100644
--- a/usr/src/uts/common/rpc/svc.c
+++ b/usr/src/uts/common/rpc/svc.c
@@ -1299,7 +1299,7 @@
"svc_getreq_start:");
ASSERT(clone_xprt->xp_master != NULL);
- ASSERT(!is_system_labeled() || DB_CRED(mp) != NULL ||
+ ASSERT(!is_system_labeled() || msg_getcred(mp, NULL) != NULL ||
mp->b_datap->db_type != M_DATA);
/*
@@ -1327,17 +1327,13 @@
* get the label from the raw mblk data now.
*/
if (is_system_labeled()) {
- mblk_t *lmp;
+ cred_t *cr;
r.rq_label = kmem_alloc(sizeof (bslabel_t), KM_SLEEP);
- if (DB_CRED(mp) != NULL)
- lmp = mp;
- else {
- ASSERT(mp->b_cont != NULL);
- lmp = mp->b_cont;
- ASSERT(DB_CRED(lmp) != NULL);
- }
- bcopy(label2bslabel(crgetlabel(DB_CRED(lmp))), r.rq_label,
+ cr = msg_getcred(mp, NULL);
+ ASSERT(cr != NULL);
+
+ bcopy(label2bslabel(crgetlabel(cr)), r.rq_label,
sizeof (bslabel_t));
} else {
r.rq_label = NULL;
@@ -2381,7 +2377,7 @@
TRACE_0(TR_FAC_KRPC, TR_SVC_QUEUEREQ_START, "svc_queuereq_start");
- ASSERT(!is_system_labeled() || DB_CRED(mp) != NULL ||
+ ASSERT(!is_system_labeled() || msg_getcred(mp, NULL) != NULL ||
mp->b_datap->db_type != M_DATA);
/*
diff --git a/usr/src/uts/common/rpc/svc_clts.c b/usr/src/uts/common/rpc/svc_clts.c
index 4929a3d..56355ea 100644
--- a/usr/src/uts/common/rpc/svc_clts.c
+++ b/usr/src/uts/common/rpc/svc_clts.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -244,6 +244,7 @@
struct rpc_clts_server *stats = CLONE2STATS(clone_xprt);
union T_primitives *pptr;
int hdrsz;
+ cred_t *cr;
TRACE_0(TR_FAC_KRPC, TR_SVC_CLTS_KRECV_START,
"svc_clts_krecv_start:");
@@ -322,6 +323,9 @@
* Save the first mblk which contains the T_unidata_ind in
* ud_resp. It will be used to generate the T_unitdata_req
* during the reply.
+ * We reuse any options in the T_unitdata_ind for the T_unitdata_req
+ * since we must pass any SCM_UCRED across in order for TX to
+ * work. We also make sure any cred_t is carried across.
*/
if (ud->ud_resp) {
if (ud->ud_resp->b_cont != NULL) {
@@ -331,6 +335,11 @@
}
freeb(ud->ud_resp);
}
+ /* Move any cred_t to the first mblk in the message */
+ cr = msg_getcred(mp, NULL);
+ if (cr != NULL)
+ mblk_setcred(mp, cr, NOPID);
+
ud->ud_resp = mp;
mp = mp->b_cont;
ud->ud_resp->b_cont = NULL;
@@ -479,10 +488,15 @@
* Construct the T_unitdata_req. We take advantage
* of the fact that T_unitdata_ind looks just like
* T_unitdata_req, except for the primitive type.
+ * Reusing it means we preserve any options, and we must preserve
+ * the SCM_UCRED option for TX to work.
+ * This has the side effect of also passing certain receive-side
+ * options like IP_RECVDSTADDR back down the send side. This
+ * implies that we can not ASSERT on a non-NULL db_credp when
+ * we have send-side options in UDP.
*/
udreq = (struct T_unitdata_req *)ud->ud_resp->b_rptr;
udreq->PRIM_type = T_UNITDATA_REQ;
-
put(clone_xprt->xp_wq, ud->ud_resp);
stat = TRUE;
ud->ud_resp = NULL;
diff --git a/usr/src/uts/common/sys/stream.h b/usr/src/uts/common/sys/stream.h
index 8d1ac45..1b5380f 100644
--- a/usr/src/uts/common/sys/stream.h
+++ b/usr/src/uts/common/sys/stream.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -356,16 +356,12 @@
*/
#define DB_CPID(mp) ((mp)->b_datap->db_cpid)
#define DB_CRED(mp) ((mp)->b_datap->db_credp)
-#define DB_CREDDEF(mp, cr) (DB_CRED(mp) != NULL ? DB_CRED(mp) : (cr))
#define DB_FTHDR(mp) ((mp)->b_datap->db_fthdr)
/*
* Used by GLDv2 to store the TCI information.
*/
#define DB_TCI(mp) ((mp)->b_datap->db_struioun.cksum.pad)
-#define MBLK_GETLABEL(mp) \
- (DB_CRED(mp) != NULL ? crgetlabel(DB_CRED(mp)) : NULL)
-
/*
* Message block descriptor
*/
diff --git a/usr/src/uts/common/sys/strsubr.h b/usr/src/uts/common/sys/strsubr.h
index a678650..f13f521 100644
--- a/usr/src/uts/common/sys/strsubr.h
+++ b/usr/src/uts/common/sys/strsubr.h
@@ -1215,12 +1215,15 @@
extern queue_t *strvp2wq(vnode_t *);
extern vnode_t *strq2vp(queue_t *);
extern mblk_t *allocb_wait(size_t, uint_t, uint_t, int *);
-extern mblk_t *allocb_cred(size_t, cred_t *);
-extern mblk_t *allocb_cred_wait(size_t, uint_t, int *, cred_t *);
+extern mblk_t *allocb_cred(size_t, cred_t *, pid_t);
+extern mblk_t *allocb_cred_wait(size_t, uint_t, int *, cred_t *, pid_t);
extern mblk_t *allocb_tmpl(size_t, const mblk_t *);
extern mblk_t *allocb_tryhard(size_t);
-extern void mblk_setcred(mblk_t *, cred_t *);
-extern void msg_setcredpid(mblk_t *, cred_t *, pid_t);
+extern void mblk_copycred(mblk_t *, const mblk_t *);
+extern void mblk_setcred(mblk_t *, cred_t *, pid_t);
+extern cred_t *msg_getcred(const mblk_t *, pid_t *);
+extern struct ts_label_s *msg_getlabel(const mblk_t *);
+extern cred_t *msg_extractcred(mblk_t *, pid_t *);
extern void strpollwakeup(vnode_t *, short);
extern int putnextctl_wait(queue_t *, int);