diff options
Diffstat (limited to 'usr/src/uts/common/inet/ip/tn_ipopt.c')
| -rw-r--r-- | usr/src/uts/common/inet/ip/tn_ipopt.c | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/usr/src/uts/common/inet/ip/tn_ipopt.c b/usr/src/uts/common/inet/ip/tn_ipopt.c index dba9b8c98a..359b8d4623 100644 --- a/usr/src/uts/common/inet/ip/tn_ipopt.c +++ b/usr/src/uts/common/inet/ip/tn_ipopt.c @@ -272,7 +272,7 @@ tsol_get_option_v6(mblk_t *mp, tsol_ip_label_t *label_type, uchar_t **buffer) * * This routine verifies if a destination is allowed to recieve messages * based on the message cred's security label. If any adjustments to - * the cred are needed due to the connection's MAC-exempt status or + * the cred are needed due to the connection's MAC mode or * the destination's ability to receive labels, an "effective cred" * will be returned. * @@ -287,7 +287,7 @@ tsol_get_option_v6(mblk_t *mp, tsol_ip_label_t *label_type, uchar_t **buffer) */ int tsol_check_dest(const cred_t *credp, const void *dst, uchar_t version, - boolean_t mac_exempt, cred_t **effective_cred) + uint_t mac_mode, cred_t **effective_cred) { ts_label_t *tsl, *newtsl = NULL; tsol_tpc_t *dst_rhtp; @@ -307,6 +307,14 @@ tsol_check_dest(const cred_t *credp, const void *dst, uchar_t version, return (0); } + if (tsl->tsl_flags & TSLF_IMPLICIT_IN) { + DTRACE_PROBE3(tx__tnopt__log__info__labeling__unresolved__label, + char *, + "implicit-in packet to ip(1) reached tsol_check_dest " + "with implied security label sl(2)", + ipaddr_t, dst, ts_label_t *, tsl); + } + /* Always pass multicast */ if (version == IPV4_VERSION && CLASSD(*(ipaddr_t *)dst)) { @@ -335,8 +343,10 @@ tsol_check_dest(const cred_t *credp, const void *dst, uchar_t version, /* * Can talk to unlabeled hosts if * (1) zone's label matches the default label, or - * (2) SO_MAC_EXEMPT is on and we dominate the peer's label - * (3) SO_MAC_EXEMPT is on and this is the global zone + * (2) SO_MAC_EXEMPT is on and we + * dominate the peer's label, or + * (3) SO_MAC_EXEMPT is on and + * this is the global zone */ if (dst_rhtp->tpc_tp.tp_doi != tsl->tsl_doi) { DTRACE_PROBE4(tx__tnopt__log__info__labeling__doi, @@ -349,7 +359,7 @@ tsol_check_dest(const cred_t *credp, const void *dst, uchar_t version, if (!blequal(&dst_rhtp->tpc_tp.tp_def_label, &tsl->tsl_label)) { zoneid = crgetzoneid(credp); - if (!mac_exempt || + if (mac_mode != CONN_MAC_AWARE || !(zoneid == GLOBAL_ZONEID || bldominates(&tsl->tsl_label, &dst_rhtp->tpc_tp.tp_def_label))) { @@ -403,16 +413,22 @@ tsol_check_dest(const cred_t *credp, const void *dst, uchar_t version, TPC_RELE(dst_rhtp); return (EHOSTUNREACH); } - if (tsl->tsl_flags & TSLF_UNLABELED) { + if ((tsl->tsl_flags & TSLF_UNLABELED) || + (mac_mode == CONN_MAC_IMPLICIT)) { /* - * The security label is a match but we need to - * clear the unlabeled flag for this remote node. + * Copy label so we can modify the flags */ if ((newtsl = labeldup(tsl, KM_NOSLEEP)) == NULL) { TPC_RELE(dst_rhtp); return (ENOMEM); } - newtsl->tsl_flags ^= TSLF_UNLABELED; + /* + * The security label is a match but we need to + * clear the unlabeled flag for this remote node. + */ + newtsl->tsl_flags &= ~TSLF_UNLABELED; + if (mac_mode == CONN_MAC_IMPLICIT) + newtsl->tsl_flags |= TSLF_IMPLICIT_OUT; } break; @@ -473,6 +489,9 @@ tsol_compute_label(const cred_t *credp, ipaddr_t dst, uchar_t *opt_storage, if (CLASSD(dst)) return (0); + if (tsl->tsl_flags & TSLF_IMPLICIT_OUT) + return (0); + if (tsl->tsl_flags & TSLF_UNLABELED) { /* @@ -807,7 +826,7 @@ tsol_prepend_option(uchar_t *optbuf, ipha_t *ipha, int buflen) * EINVAL Label cannot be computed */ int -tsol_check_label(const cred_t *credp, mblk_t **mpp, boolean_t isexempt, +tsol_check_label(const cred_t *credp, mblk_t **mpp, uint_t mac_mode, ip_stack_t *ipst, pid_t pid) { mblk_t *mp = *mpp; @@ -832,7 +851,7 @@ tsol_check_label(const cred_t *credp, mblk_t **mpp, boolean_t isexempt, * for use in future routing decisions. */ retv = tsol_check_dest(credp, &ipha->ipha_dst, IPV4_VERSION, - isexempt, &effective_cred); + mac_mode, &effective_cred); if (retv != 0) return (retv); @@ -871,6 +890,10 @@ tsol_check_label(const cred_t *credp, mblk_t **mpp, boolean_t isexempt, return (0); } + if (msg_getcred(mp, NULL) == NULL) { + mblk_setcred(mp, (cred_t *)credp, NOPID); + } + /* * If there is an option there, then it must be the wrong one; delete. */ @@ -983,6 +1006,9 @@ tsol_compute_label_v6(const cred_t *credp, const in6_addr_t *dst, * that the maximum size of this label is reflected in sys/tsol/tnet.h * as TSOL_MAX_IPV6_OPTION. */ + if (tsl->tsl_flags & TSLF_IMPLICIT_OUT) + return (0); + if (tsl->tsl_flags & TSLF_UNLABELED) { /* * The destination is unlabeled. Only add a label if the @@ -1352,7 +1378,7 @@ tsol_prepend_option_v6(uchar_t *optbuf, ip6_t *ip6h, int buflen) * ENOMEM Memory allocation failure. */ int -tsol_check_label_v6(const cred_t *credp, mblk_t **mpp, boolean_t isexempt, +tsol_check_label_v6(const cred_t *credp, mblk_t **mpp, uint_t mode, ip_stack_t *ipst, pid_t pid) { mblk_t *mp = *mpp; @@ -1382,7 +1408,7 @@ tsol_check_label_v6(const cred_t *credp, mblk_t **mpp, boolean_t isexempt, */ ip6h = (ip6_t *)mp->b_rptr; retv = tsol_check_dest(credp, &ip6h->ip6_dst, IPV6_VERSION, - isexempt, &effective_cred); + mode, &effective_cred); if (retv != 0) return (retv); @@ -1430,6 +1456,11 @@ tsol_check_label_v6(const cred_t *credp, mblk_t **mpp, boolean_t isexempt, */ return (0); } + + if (msg_getcred(mp, NULL) == NULL) { + mblk_setcred(mp, (cred_t *)credp, NOPID); + } + if (secopt != NULL && sec_opt_len != 0 && (bcmp(opt_storage, secopt, sec_opt_len + 2) == 0)) { /* The packet has the correct label already */ |
