summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/inet/ip/ipsecah.c66
-rw-r--r--usr/src/uts/common/inet/ip/ipsecesp.c118
-rw-r--r--usr/src/uts/common/inet/ip/spd.c114
-rw-r--r--usr/src/uts/common/inet/ipsec_impl.h3
-rw-r--r--usr/src/uts/common/inet/tcp/tcp.c7
5 files changed, 160 insertions, 148 deletions
diff --git a/usr/src/uts/common/inet/ip/ipsecah.c b/usr/src/uts/common/inet/ip/ipsecah.c
index 445816dafa..adcffc7c64 100644
--- a/usr/src/uts/common/inet/ip/ipsecah.c
+++ b/usr/src/uts/common/inet/ip/ipsecah.c
@@ -35,6 +35,7 @@
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/kmem.h>
+#include <sys/sysmacros.h>
#include <sys/cmn_err.h>
#include <sys/vtrace.h>
#include <sys/debug.h>
@@ -3726,14 +3727,14 @@ ah_auth_in_done(mblk_t *ipsec_in)
ipha_t *ipha;
uint_t ah_offset = 0;
mblk_t *mp;
- int align_len;
+ int align_len, newpos;
ah_t *ah;
- ipha_t *nipha;
uint32_t length;
+ uint32_t *dest32;
+ uint8_t *dest;
ipsec_in_t *ii;
boolean_t isv4;
ip6_t *ip6h;
- ip6_t *nip6h;
uint_t icv_len;
ipsa_t *assoc;
kstat_named_t *counter;
@@ -3774,6 +3775,7 @@ ah_auth_in_done(mblk_t *ipsec_in)
}
ah = (ah_t *)(mp->b_rptr + ah_offset);
+ newpos = sizeof (ah_t) + align_len;
/*
* We get here only when authentication passed.
@@ -3812,22 +3814,18 @@ ah_auth_in_done(mblk_t *ipsec_in)
/*
* We need to remove the AH header from the original
- * datagram. Easy way to do this is to use phdr_mp
- * to hold the IP header and the orginal mp to hold
- * the rest of it. So, we copy the IP header on to
- * phdr_mp, and set the b_rptr in mp past AH header.
+ * datagram. Best way to do this is to move the pre-AH headers
+ * forward in the (relatively simple) IPv4 case. In IPv6, it's
+ * a bit more complicated because of IPv6's next-header chaining,
+ * but it's doable.
*/
if (isv4) {
- bcopy(mp->b_rptr, phdr_mp->b_rptr, ah_offset);
- phdr_mp->b_wptr = phdr_mp->b_rptr + ah_offset;
- nipha = (ipha_t *)phdr_mp->b_rptr;
/*
* Assign the right protocol, adjust the length as we
* are removing the AH header and adjust the checksum to
* account for the protocol and length.
*/
- nipha->ipha_protocol = ah->ah_nexthdr;
- length = ntohs(nipha->ipha_length);
+ length = ntohs(ipha->ipha_length);
if (!ah_age_bytes(assoc, length, B_TRUE)) {
/* The ipsa has hit hard expiration, LOG and AUDIT. */
ipsec_assocfailure(info.mi_idnum, 0, 0,
@@ -3839,16 +3837,12 @@ ah_auth_in_done(mblk_t *ipsec_in)
counter = &ipdrops_ah_bytes_expire;
goto ah_in_discard;
}
- length -= (sizeof (ah_t) + align_len);
+ ipha->ipha_protocol = ah->ah_nexthdr;
+ length -= newpos;
- nipha->ipha_length = htons((uint16_t)length);
- nipha->ipha_hdr_checksum = 0;
- nipha->ipha_hdr_checksum = (uint16_t)ip_csum_hdr(nipha);
- /*
- * Skip IP,AH and the authentication data in the
- * original datagram.
- */
- mp->b_rptr += (ah_offset + sizeof (ah_t) + align_len);
+ ipha->ipha_length = htons((uint16_t)length);
+ ipha->ipha_hdr_checksum = 0;
+ ipha->ipha_hdr_checksum = (uint16_t)ip_csum_hdr(ipha);
} else {
uchar_t *whereptr;
int hdrlen;
@@ -3857,13 +3851,11 @@ ah_auth_in_done(mblk_t *ipsec_in)
ip6_dest_t *dsthdr;
ip6_rthdr0_t *rthdr;
- nip6h = (ip6_t *)phdr_mp->b_rptr;
-
/*
* Make phdr_mp hold until the AH header and make
* mp hold everything past AH header.
*/
- length = ntohs(nip6h->ip6_plen);
+ length = ntohs(ip6h->ip6_plen);
if (!ah_age_bytes(assoc, length + sizeof (ip6_t), B_TRUE)) {
/* The ipsa has hit hard expiration, LOG and AUDIT. */
ipsec_assocfailure(info.mi_idnum, 0, 0,
@@ -3875,9 +3867,6 @@ ah_auth_in_done(mblk_t *ipsec_in)
counter = &ipdrops_ah_bytes_expire;
goto ah_in_discard;
}
- bcopy(ip6h, nip6h, ah_offset);
- phdr_mp->b_wptr = phdr_mp->b_rptr + ah_offset;
- mp->b_rptr += (ah_offset + sizeof (ah_t) + align_len);
/*
* Update the next header field of the header preceding
@@ -3885,8 +3874,8 @@ ah_auth_in_done(mblk_t *ipsec_in)
* IPv6 header and proceed with the extension headers
* until we find what we're looking for.
*/
- nexthdr = &nip6h->ip6_nxt;
- whereptr = (uchar_t *)nip6h;
+ nexthdr = &ip6h->ip6_nxt;
+ whereptr = (uchar_t *)ip6h;
hdrlen = sizeof (ip6_t);
while (*nexthdr != IPPROTO_AH) {
@@ -3913,16 +3902,29 @@ ah_auth_in_done(mblk_t *ipsec_in)
}
}
*nexthdr = ah->ah_nexthdr;
+ length -= newpos;
+ ip6h->ip6_plen = htons((uint16_t)length);
+ }
- length -= (sizeof (ah_t) + align_len);
- nip6h->ip6_plen = htons((uint16_t)length);
+ /* Now that we've fixed the IP header, move it forward. */
+ mp->b_rptr += newpos;
+ if (IS_P2ALIGNED(mp->b_rptr, sizeof (uint32_t))) {
+ dest32 = (uint32_t *)(mp->b_rptr + ah_offset);
+ while (--dest32 >= (uint32_t *)mp->b_rptr)
+ *dest32 = *(dest32 - (newpos >> 2));
+ } else {
+ dest = mp->b_rptr + ah_offset;
+ while (--dest >= mp->b_rptr)
+ *dest = *(dest - newpos);
}
+ freeb(phdr_mp);
+ ipsec_in->b_cont = mp;
if (is_system_labeled()) {
/*
* inherit the label by setting it in the new ip header
*/
- mblk_setcred(phdr_mp, DB_CRED(mp));
+ mblk_setcred(mp, DB_CRED(mp));
}
return (IPSEC_STATUS_SUCCESS);
diff --git a/usr/src/uts/common/inet/ip/ipsecesp.c b/usr/src/uts/common/inet/ip/ipsecesp.c
index de25c6a0b8..f6f23503b1 100644
--- a/usr/src/uts/common/inet/ip/ipsecesp.c
+++ b/usr/src/uts/common/inet/ip/ipsecesp.c
@@ -763,7 +763,7 @@ esp_fix_natt_checksums(mblk_t *data_mp, ipsa_t *assoc)
/*
- * Strip ESP header and fix IP header
+ * Strip ESP header, check padding, and fix IP header.
* Returns B_TRUE on success, B_FALSE if an error occured.
*/
static boolean_t
@@ -776,6 +776,7 @@ esp_strip_header(mblk_t *data_mp, boolean_t isv4, uint32_t ivlen,
mblk_t *scratch;
uint8_t nexthdr, padlen;
uint8_t lastpad;
+ uint8_t *lastbyte;
/*
* Strip ESP data and fix IP header.
@@ -807,9 +808,9 @@ esp_strip_header(mblk_t *data_mp, boolean_t isv4, uint32_t ivlen,
* lastpad is the last byte of the padding, which can be used for
* a quick check to see if the padding is correct.
*/
- nexthdr = *(scratch->b_wptr - 1);
- padlen = *(scratch->b_wptr - 2);
- lastpad = *(scratch->b_wptr - 3);
+ lastbyte = scratch->b_wptr - 1;
+ nexthdr = *lastbyte--;
+ padlen = *lastbyte--;
if (isv4) {
/* Fix part of the IP header. */
@@ -822,7 +823,7 @@ esp_strip_header(mblk_t *data_mp, boolean_t isv4, uint32_t ivlen,
sizeof (esph_t) - ivlen) {
ESP_BUMP_STAT(bad_decrypt);
ipsec_rl_strlog(info.mi_idnum, 0, 0, SL_ERROR | SL_WARN,
- "Possibly corrupt ESP packet.");
+ "Corrupt ESP packet (padlen too big).\n");
esp1dbg(("padlen (%d) is greater than:\n", padlen));
esp1dbg(("pkt len(%d) - ip hdr - esp hdr - ivlen(%d) "
"= %d.\n", ntohs(ipha->ipha_length), ivlen,
@@ -867,7 +868,7 @@ esp_strip_header(mblk_t *data_mp, boolean_t isv4, uint32_t ivlen,
ivlen) {
ESP_BUMP_STAT(bad_decrypt);
ipsec_rl_strlog(info.mi_idnum, 0, 0, SL_ERROR | SL_WARN,
- "Possibly corrupt ESP packet.");
+ "Corrupt ESP packet (v6 padlen too big).\n");
esp1dbg(("padlen (%d) is greater than:\n", padlen));
esp1dbg(("pkt len(%u) - ip hdr - esp hdr - ivlen(%d)"
" = %u.\n", (unsigned)(ntohs(ip6h->ip6_plen)
@@ -888,41 +889,57 @@ esp_strip_header(mblk_t *data_mp, boolean_t isv4, uint32_t ivlen,
2 - sizeof (esph_t) - ivlen);
}
- if (ipsecesp_padding_check > 0 &&
- padlen != lastpad && padlen != 0) {
- ipsec_rl_strlog(info.mi_idnum, 0, 0, SL_ERROR | SL_WARN,
- "Possibly corrupt ESP packet.");
- esp1dbg(("lastpad (%d) not equal to padlen (%d):\n",
- lastpad, padlen));
- ESP_BUMP_STAT(bad_padding);
- *counter = &ipdrops_esp_bad_padding;
- return (B_FALSE);
- }
+ if (ipsecesp_padding_check > 0 && padlen > 0) {
+ /*
+ * Weak padding check: compare last-byte to length, they
+ * should be equal.
+ */
+ lastpad = *lastbyte--;
- if (ipsecesp_padding_check > 1) {
- uint8_t *last = (uint8_t *)(scratch->b_wptr - 3);
- uint8_t lastval = *last;
+ if (padlen != lastpad) {
+ ipsec_rl_strlog(info.mi_idnum, 0, 0, SL_ERROR | SL_WARN,
+ "Corrupt ESP packet (lastpad != padlen).\n");
+ esp1dbg(("lastpad (%d) not equal to padlen (%d):\n",
+ lastpad, padlen));
+ ESP_BUMP_STAT(bad_padding);
+ *counter = &ipdrops_esp_bad_padding;
+ return (B_FALSE);
+ }
/*
- * this assert may have to become an if
- * and a pullup if we start accepting
- * multi-dblk mblks. Any packet here will
- * have been pulled up in esp_inbound.
+ * Strong padding check: Check all pad bytes to see that
+ * they're ascending. Go backwards using a descending counter
+ * to verify. padlen == 1 is checked by previous block, so
+ * only bother if we've more than 1 byte of padding.
+ * Consequently, start the check one byte before the location
+ * of "lastpad".
*/
- ASSERT(MBLKL(scratch) >= lastval + 3);
-
- while (lastval != 0) {
- if (lastval != *last) {
- ipsec_rl_strlog(info.mi_idnum, 0, 0,
- SL_ERROR | SL_WARN,
- "Possibly corrupt ESP packet.");
- esp1dbg(("padding not in correct"
- " format:\n"));
- ESP_BUMP_STAT(bad_padding);
- *counter = &ipdrops_esp_bad_padding;
- return (B_FALSE);
+ if (ipsecesp_padding_check > 1) {
+ /*
+ * This assert may have to become an if and a pullup
+ * if we start accepting multi-dblk mblks. For now,
+ * though, any packet here will have been pulled up in
+ * esp_inbound.
+ */
+ ASSERT(MBLKL(scratch) >= lastpad + 3);
+
+ /*
+ * Use "--lastpad" because we already checked the very
+ * last pad byte previously.
+ */
+ while (--lastpad != 0) {
+ if (lastpad != *lastbyte) {
+ ipsec_rl_strlog(info.mi_idnum, 0, 0,
+ SL_ERROR | SL_WARN, "Corrupt ESP "
+ "packet (bad padding).\n");
+ esp1dbg(("padding not in correct"
+ " format:\n"));
+ ESP_BUMP_STAT(bad_padding);
+ *counter = &ipdrops_esp_bad_padding;
+ return (B_FALSE);
+ }
+ lastbyte--;
}
- lastval--; last--;
}
}
@@ -2051,7 +2068,7 @@ esp_outbound(mblk_t *mp)
uintptr_t esplen = sizeof (esph_t);
uint8_t protocol;
ipsa_t *assoc;
- uint_t iv_len = 0, mac_len = 0;
+ uint_t iv_len, mac_len = 0;
uchar_t *icv_buf;
udpha_t *udpha;
boolean_t is_natt = B_FALSE;
@@ -2148,26 +2165,25 @@ esp_outbound(mblk_t *mp)
esplen += UDPH_SIZE;
}
- if (assoc->ipsa_encr_alg != SADB_EALG_NULL)
- iv_len = assoc->ipsa_iv_len;
-
/*
* Set up ESP header and encryption padding for ENCR PI request.
*/
- /*
- * Determine the padding length. Pad to 4-bytes.
- *
- * Include the two additional bytes (hence the - 2) for the padding
- * length and the next header. Take this into account when
- * calculating the actual length of the padding.
- */
-
+ /* Determine the padding length. Pad to 4-bytes for no-encryption. */
if (assoc->ipsa_encr_alg != SADB_EALG_NULL) {
- padlen = ((unsigned)(iv_len - datalen - 2)) % iv_len;
+ iv_len = assoc->ipsa_iv_len;
+
+ /*
+ * Include the two additional bytes (hence the - 2) for the
+ * padding length and the next header. Take this into account
+ * when calculating the actual length of the padding.
+ */
+ ASSERT(ISP2(iv_len));
+ padlen = ((unsigned)(iv_len - datalen - 2)) & (iv_len - 1);
} else {
- padlen = ((unsigned)(sizeof (uint32_t) - datalen - 2)) %
- sizeof (uint32_t);
+ iv_len = 0;
+ padlen = ((unsigned)(sizeof (uint32_t) - datalen - 2)) &
+ (sizeof (uint32_t) - 1);
}
/* Allocate ESP header and IV. */
diff --git a/usr/src/uts/common/inet/ip/spd.c b/usr/src/uts/common/inet/ip/spd.c
index 308ba2bee7..f6918dfd21 100644
--- a/usr/src/uts/common/inet/ip/spd.c
+++ b/usr/src/uts/common/inet/ip/spd.c
@@ -63,6 +63,9 @@
#include <inet/ipsec_info.h>
#include <inet/sadb.h>
#include <inet/ipsec_impl.h>
+
+#include <inet/ip_impl.h> /* For IP_MOD_ID */
+
#include <inet/ipsecah.h>
#include <inet/ipsecesp.h>
#include <inet/ipdrop.h>
@@ -77,8 +80,8 @@ static mblk_t *ipsec_attach_global_policy(mblk_t *, conn_t *,
ipsec_selector_t *);
static mblk_t *ipsec_apply_global_policy(mblk_t *, conn_t *,
ipsec_selector_t *);
-static mblk_t *ipsec_check_ipsecin_policy(queue_t *, mblk_t *,
- ipsec_policy_t *, ipha_t *, ip6_t *, uint64_t);
+static mblk_t *ipsec_check_ipsecin_policy(mblk_t *, ipsec_policy_t *,
+ ipha_t *, ip6_t *, uint64_t);
static void ipsec_in_release_refs(ipsec_in_t *);
static void ipsec_out_release_refs(ipsec_out_t *);
static void ipsec_action_reclaim(void *);
@@ -952,14 +955,13 @@ iph_ipvN(ipsec_policy_head_t *iph, boolean_t v6)
*
*/
void
-ipsec_log_policy_failure(queue_t *q, int type, char *func_name, ipha_t *ipha,
- ip6_t *ip6h, boolean_t secure)
+ipsec_log_policy_failure(int type, char *func_name, ipha_t *ipha, ip6_t *ip6h,
+ boolean_t secure)
{
char sbuf[INET6_ADDRSTRLEN];
char dbuf[INET6_ADDRSTRLEN];
char *s;
char *d;
- short mid = 0;
ASSERT((ipha == NULL && ip6h != NULL) ||
(ip6h == NULL && ipha != NULL));
@@ -976,13 +978,9 @@ ipsec_log_policy_failure(queue_t *q, int type, char *func_name, ipha_t *ipha,
/* Always bump the policy failure counter. */
ipsec_policy_failure_count[type]++;
- if (q != NULL) {
- mid = q->q_qinfo->qi_minfo->mi_idnum;
- }
- ipsec_rl_strlog(mid, 0, 0, SL_ERROR|SL_WARN|SL_CONSOLE,
- ipsec_policy_failure_msgs[type],
- func_name,
- (secure ? "secure" : "not secure"), s, d);
+ ipsec_rl_strlog(IP_MOD_ID, 0, 0, SL_ERROR|SL_WARN|SL_CONSOLE,
+ ipsec_policy_failure_msgs[type], func_name,
+ (secure ? "secure" : "not secure"), s, d);
}
/*
@@ -1446,13 +1444,12 @@ ipsec_apply_global_policy(mblk_t *ipsec_mp, conn_t *connp,
}
-/* ARGSUSED */
/*
* Consumes a reference to ipsp.
*/
static mblk_t *
-ipsec_check_loopback_policy(queue_t *q, mblk_t *first_mp,
- boolean_t mctl_present, ipsec_policy_t *ipsp)
+ipsec_check_loopback_policy(mblk_t *first_mp, boolean_t mctl_present,
+ ipsec_policy_t *ipsp)
{
mblk_t *ipsec_mp;
ipsec_in_t *ii;
@@ -1468,7 +1465,8 @@ ipsec_check_loopback_policy(queue_t *q, mblk_t *first_mp,
/*
* We should do an actual policy check here. Revisit this
- * when we revisit the IPsec API.
+ * when we revisit the IPsec API. (And pass a conn_t in when we
+ * get there.)
*/
return (first_mp);
@@ -1798,14 +1796,13 @@ ipsec_check_ipsecin_latch(ipsec_in_t *ii, mblk_t *mp, ipsec_latch_t *ipl,
* Consumes a reference to ipsp.
*/
static mblk_t *
-ipsec_check_ipsecin_policy(queue_t *q, mblk_t *first_mp, ipsec_policy_t *ipsp,
+ipsec_check_ipsecin_policy(mblk_t *first_mp, ipsec_policy_t *ipsp,
ipha_t *ipha, ip6_t *ip6h, uint64_t pkt_unique)
{
ipsec_in_t *ii;
ipsec_action_t *ap;
const char *reason = "no policy actions found";
mblk_t *data_mp, *ipsec_mp;
- short mid = 0;
kstat_named_t *counter = &ipdrops_spd_got_secure;
data_mp = first_mp->b_cont;
@@ -1819,7 +1816,7 @@ ipsec_check_ipsecin_policy(queue_t *q, mblk_t *first_mp, ipsec_policy_t *ipsp,
ii = (ipsec_in_t *)ipsec_mp->b_rptr;
if (ii->ipsec_in_loopback)
- return (ipsec_check_loopback_policy(q, first_mp, B_TRUE, ipsp));
+ return (ipsec_check_loopback_policy(first_mp, B_TRUE, ipsp));
ASSERT(ii->ipsec_in_type == IPSEC_IN);
ASSERT(ii->ipsec_in_secure);
@@ -1855,10 +1852,7 @@ ipsec_check_ipsecin_policy(queue_t *q, mblk_t *first_mp, ipsec_policy_t *ipsp,
}
}
drop:
- if (q != NULL) {
- mid = q->q_qinfo->qi_minfo->mi_idnum;
- }
- ipsec_rl_strlog(mid, 0, 0, SL_ERROR|SL_WARN|SL_CONSOLE,
+ ipsec_rl_strlog(IP_MOD_ID, 0, 0, SL_ERROR|SL_WARN|SL_CONSOLE,
"ipsec inbound policy mismatch: %s, packet dropped\n",
reason);
IPPOL_REFRELE(ipsp);
@@ -2068,7 +2062,6 @@ ipsec_check_global_policy(mblk_t *first_mp, conn_t *connp,
{
ipsec_policy_t *p;
ipsec_selector_t sel;
- queue_t *q = NULL;
mblk_t *data_mp, *ipsec_mp;
boolean_t policy_present;
kstat_named_t *counter;
@@ -2096,9 +2089,6 @@ ipsec_check_global_policy(mblk_t *first_mp, conn_t *connp,
return (first_mp);
}
- if (connp != NULL)
- q = CONNP_TO_WQ(connp);
-
if (ipsec_mp != NULL) {
ASSERT(ipsec_mp->b_datap->db_type == M_CTL);
ii = (ipsec_in_t *)(ipsec_mp->b_rptr);
@@ -2126,7 +2116,7 @@ ipsec_check_global_policy(mblk_t *first_mp, conn_t *connp,
* Technically not a policy mismatch, but it is
* an internal failure.
*/
- ipsec_log_policy_failure(q, IPSEC_POLICY_MISMATCH,
+ ipsec_log_policy_failure(IPSEC_POLICY_MISMATCH,
"ipsec_init_inbound_sel", ipha, ip6h, B_FALSE);
counter = &ipdrops_spd_nomem;
goto fail;
@@ -2158,14 +2148,15 @@ ipsec_check_global_policy(mblk_t *first_mp, conn_t *connp,
return (first_mp);
} else {
counter = &ipdrops_spd_got_secure;
- ipsec_log_policy_failure(q, IPSEC_POLICY_NOT_NEEDED,
+ ipsec_log_policy_failure(IPSEC_POLICY_NOT_NEEDED,
"ipsec_check_global_policy", ipha, ip6h, B_TRUE);
goto fail;
}
}
- if ((ii != NULL) && (ii->ipsec_in_secure))
- return (ipsec_check_ipsecin_policy(q, ipsec_mp, p, ipha, ip6h,
- pkt_unique));
+ if ((ii != NULL) && (ii->ipsec_in_secure)) {
+ return (ipsec_check_ipsecin_policy(ipsec_mp, p, ipha, ip6h,
+ pkt_unique));
+ }
if (p->ipsp_act->ipa_allow_clear) {
BUMP_MIB(&ip_mib, ipsecInSucceeded);
IPPOL_REFRELE(p);
@@ -2177,7 +2168,7 @@ ipsec_check_global_policy(mblk_t *first_mp, conn_t *connp,
* global policy check because the packet was cleartext, and it
* should not have been.
*/
- ipsec_log_policy_failure(q, IPSEC_POLICY_MISMATCH,
+ ipsec_log_policy_failure(IPSEC_POLICY_MISMATCH,
"ipsec_check_global_policy", ipha, ip6h, B_FALSE);
counter = &ipdrops_spd_got_clear;
@@ -2400,8 +2391,6 @@ ipsec_check_inbound_policy(mblk_t *first_mp, conn_t *connp,
{
ipsec_in_t *ii;
boolean_t ret;
- queue_t *q;
- short mid = 0;
mblk_t *mp = mctl_present ? first_mp->b_cont : first_mp;
mblk_t *ipsec_mp = mctl_present ? first_mp : NULL;
ipsec_latch_t *ipl;
@@ -2433,7 +2422,6 @@ clear:
return (first_mp);
} else {
ipsec_log_policy_failure(
- CONNP_TO_WQ(connp),
IPSEC_POLICY_MISMATCH,
"ipsec_check_inbound_policy", ipha,
ip6h, B_FALSE);
@@ -2507,11 +2495,7 @@ clear:
BUMP_MIB(&ip_mib, ipsecInSucceeded);
return (first_mp);
}
- q = CONNP_TO_WQ(connp);
- if (q != NULL) {
- mid = q->q_qinfo->qi_minfo->mi_idnum;
- }
- ipsec_rl_strlog(mid, 0, 0, SL_ERROR|SL_WARN|SL_CONSOLE,
+ ipsec_rl_strlog(IP_MOD_ID, 0, 0, SL_ERROR|SL_WARN|SL_CONSOLE,
"ipsec inbound policy mismatch: %s, packet dropped\n",
reason);
ip_drop_packet(first_mp, B_TRUE, NULL, NULL, counter,
@@ -2525,8 +2509,8 @@ clear:
unique_id = conn_to_unique(connp, mp, ipha, ip6h);
IPPOL_REFHOLD(ipl->ipl_in_policy);
- first_mp = ipsec_check_ipsecin_policy(CONNP_TO_WQ(connp), first_mp,
- ipl->ipl_in_policy, ipha, ip6h, unique_id);
+ first_mp = ipsec_check_ipsecin_policy(first_mp, ipl->ipl_in_policy,
+ ipha, ip6h, unique_id);
/*
* NOTE: ipsecIn{Failed,Succeeeded} bumped by
* ipsec_check_ipsecin_policy().
@@ -4010,18 +3994,12 @@ ipsec_attach_ipsec_out(mblk_t *mp, conn_t *connp, ipsec_policy_t *pol,
uint8_t proto)
{
mblk_t *ipsec_mp;
- queue_t *q;
- short mid = 0;
ASSERT((pol != NULL) || (connp != NULL));
ipsec_mp = ipsec_alloc_ipsec_out();
if (ipsec_mp == NULL) {
- q = CONNP_TO_WQ(connp);
- if (q != NULL) {
- mid = q->q_qinfo->qi_minfo->mi_idnum;
- }
- ipsec_rl_strlog(mid, 0, 0, SL_ERROR|SL_NOTE,
+ ipsec_rl_strlog(IP_MOD_ID, 0, 0, SL_ERROR|SL_NOTE,
"ipsec_attach_ipsec_out: Allocation failure\n");
BUMP_MIB(&ip_mib, ipOutDiscards);
ip_drop_packet(mp, B_FALSE, NULL, NULL, &ipdrops_spd_nomem,
@@ -5444,8 +5422,8 @@ ipsec_check_ipsecin_policy_reasm(mblk_t *ipsec_mp, ipsec_policy_t *pol,
*/
IPPOL_REFHOLD(pol);
- if (ipsec_check_ipsecin_policy(NULL, ipsec_mp, pol,
- inner_ipv4, inner_ipv6, pkt_unique) != NULL) {
+ if (ipsec_check_ipsecin_policy(ipsec_mp, pol, inner_ipv4,
+ inner_ipv6, pkt_unique) != NULL) {
if (data_tail == NULL) {
/* First one */
data_chain = data_tail = ipsec_mp->b_cont;
@@ -5504,14 +5482,22 @@ ipsec_tun_inbound(mblk_t *ipsec_mp, mblk_t **data_mp, ipsec_tun_pol_t *itp,
ipsec_policy_t *pol;
uint16_t tmpport;
selret_t rc;
- boolean_t retval, port_policy_present, is_icmp;
+ boolean_t retval, port_policy_present, is_icmp, global_present;
in6_addr_t tmpaddr;
- uint8_t flags;
+ uint8_t flags, *holder, *outer_hdr;
sel.ips_is_icmp_inv_acq = 0;
- ASSERT(outer_ipv4 != NULL && outer_ipv6 == NULL ||
- outer_ipv4 == NULL && outer_ipv6 != NULL);
+ if (outer_ipv4 != NULL) {
+ ASSERT(outer_ipv6 == NULL);
+ outer_hdr = (uint8_t *)outer_ipv4;
+ global_present = ipsec_inbound_v4_policy_present;
+ } else {
+ outer_hdr = (uint8_t *)outer_ipv6;
+ global_present = ipsec_inbound_v6_policy_present;
+ }
+ ASSERT(outer_hdr != NULL);
+
ASSERT(inner_ipv4 != NULL && inner_ipv6 == NULL ||
inner_ipv4 == NULL && inner_ipv6 != NULL);
ASSERT(message == *data_mp || message->b_cont == *data_mp);
@@ -5709,9 +5695,7 @@ ipsec_tun_inbound(mblk_t *ipsec_mp, mblk_t **data_mp, ipsec_tun_pol_t *itp,
*/
/* If no per-tunnel security, check global policy now. */
- if (ipsec_mp != NULL &&
- (((outer_ipv4 != NULL) && !ipsec_inbound_v4_policy_present) ||
- ((outer_ipv6 != NULL) && !ipsec_inbound_v6_policy_present))) {
+ if (ipsec_mp != NULL && !global_present) {
if (((ipsec_in_t *)(ipsec_mp->b_rptr))->
ipsec_in_icmp_loopback) {
/*
@@ -5728,12 +5712,24 @@ ipsec_tun_inbound(mblk_t *ipsec_mp, mblk_t **data_mp, ipsec_tun_pol_t *itp,
return (B_FALSE);
}
+ /*
+ * The following assertion is valid because only the tun module alters
+ * the mblk chain - stripping the outer header by advancing mp->b_rptr.
+ */
+ ASSERT(is_icmp ||
+ ((*data_mp)->b_datap->db_base <= outer_hdr &&
+ outer_hdr < (*data_mp)->b_rptr));
+ holder = (*data_mp)->b_rptr;
+ (*data_mp)->b_rptr = outer_hdr;
+
/* NOTE: Frees message if it returns NULL. */
if (ipsec_check_global_policy(message, NULL, outer_ipv4, outer_ipv6,
(ipsec_mp != NULL)) == NULL) {
return (B_FALSE);
}
+ (*data_mp)->b_rptr = holder;
+
if (ipsec_mp != NULL)
freeb(ipsec_mp);
diff --git a/usr/src/uts/common/inet/ipsec_impl.h b/usr/src/uts/common/inet/ipsec_impl.h
index 623154dae9..6e4764a89c 100644
--- a/usr/src/uts/common/inet/ipsec_impl.h
+++ b/usr/src/uts/common/inet/ipsec_impl.h
@@ -651,8 +651,7 @@ extern mblk_t *ipsec_check_inbound_policy(mblk_t *, conn_t *, ipha_t *, ip6_t *,
boolean_t);
extern boolean_t ipsec_in_to_out(mblk_t *, ipha_t *, ip6_t *);
-extern void ipsec_log_policy_failure(queue_t *, int, char *, ipha_t *,
- ip6_t *, boolean_t);
+extern void ipsec_log_policy_failure(int, char *, ipha_t *, ip6_t *, boolean_t);
extern boolean_t ipsec_inbound_accept_clear(mblk_t *, ipha_t *, ip6_t *);
extern int ipsec_conn_cache_policy(conn_t *, boolean_t);
extern mblk_t *ipsec_alloc_ipsec_out(void);
diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c
index cbe35bd58c..d42c01d93e 100644
--- a/usr/src/uts/common/inet/tcp/tcp.c
+++ b/usr/src/uts/common/inet/tcp/tcp.c
@@ -12082,7 +12082,7 @@ tcp_check_policy(tcp_t *tcp, mblk_t *first_mp, ipha_t *ipha, ip6_t *ip6h,
if (act == NULL || act->ipa_act.ipa_type == IPSEC_ACT_BYPASS ||
act->ipa_act.ipa_type == IPSEC_ACT_CLEAR)
return (B_TRUE);
- ipsec_log_policy_failure(tcp->tcp_wq, IPSEC_POLICY_MISMATCH,
+ ipsec_log_policy_failure(IPSEC_POLICY_MISMATCH,
"tcp_check_policy", ipha, ip6h, secure);
ip_drop_packet(first_mp, B_TRUE, NULL, NULL,
&ipdrops_tcp_clear, &tcp_dropper);
@@ -12093,9 +12093,8 @@ tcp_check_policy(tcp_t *tcp, mblk_t *first_mp, ipha_t *ipha, ip6_t *ip6h,
* We have a secure packet.
*/
if (act == NULL) {
- ipsec_log_policy_failure(tcp->tcp_wq,
- IPSEC_POLICY_NOT_NEEDED, "tcp_check_policy", ipha, ip6h,
- secure);
+ ipsec_log_policy_failure(IPSEC_POLICY_NOT_NEEDED,
+ "tcp_check_policy", ipha, ip6h, secure);
ip_drop_packet(first_mp, B_TRUE, NULL, NULL,
&ipdrops_tcp_secure, &tcp_dropper);
return (B_FALSE);