Page MenuHomeFreeBSD

D8468.diff
No OneTemporary

D8468.diff

Index: head/lib/libipsec/pfkey.c
===================================================================
--- head/lib/libipsec/pfkey.c
+++ head/lib/libipsec/pfkey.c
@@ -1776,6 +1776,7 @@
case SADB_EXT_SPIRANGE:
case SADB_X_EXT_POLICY:
case SADB_X_EXT_SA2:
+ case SADB_X_EXT_SA_REPLAY:
mhp[ext->sadb_ext_type] = (caddr_t)ext;
break;
case SADB_X_EXT_NAT_T_TYPE:
Index: head/lib/libipsec/pfkey_dump.c
===================================================================
--- head/lib/libipsec/pfkey_dump.c
+++ head/lib/libipsec/pfkey_dump.c
@@ -219,6 +219,7 @@
struct sadb_key *m_auth, *m_enc;
struct sadb_ident *m_sid, *m_did;
struct sadb_sens *m_sens;
+ struct sadb_x_sa_replay *m_sa_replay;
/* check pfkey message. */
if (pfkey_align(m, mhp)) {
@@ -243,6 +244,7 @@
m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC];
m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST];
m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY];
+ m_sa_replay = (struct sadb_x_sa_replay *)mhp[SADB_X_EXT_SA_REPLAY];
/* source address */
if (m_saddr == NULL) {
@@ -306,7 +308,8 @@
/* replay windoe size & flags */
printf("\tseq=0x%08x replay=%u flags=0x%08x ",
m_sa2->sadb_x_sa2_sequence,
- m_sa->sadb_sa_replay,
+ m_sa_replay ? (m_sa_replay->sadb_x_sa_replay_replay >> 3) :
+ m_sa->sadb_sa_replay,
m_sa->sadb_sa_flags);
/* state */
Index: head/sys/net/pfkeyv2.h
===================================================================
--- head/sys/net/pfkeyv2.h
+++ head/sys/net/pfkeyv2.h
@@ -283,6 +283,14 @@
};
_Static_assert(sizeof(struct sadb_x_nat_t_frag) == 8, "struct size mismatch");
+/* Additional large replay window support
+ */
+struct sadb_x_sa_replay {
+ u_int16_t sadb_x_sa_replay_len;
+ u_int16_t sadb_x_sa_replay_exttype;
+ u_int32_t sadb_x_sa_replay_replay; /* in packets */
+};
+_Static_assert(sizeof(struct sadb_x_sa_replay) == 8, "struct size mismatch");
#define SADB_EXT_RESERVED 0
#define SADB_EXT_SA 1
@@ -311,7 +319,8 @@
#define SADB_X_EXT_NAT_T_OAI 23 /* Peer's NAT_OA for src of SA. */
#define SADB_X_EXT_NAT_T_OAR 24 /* Peer's NAT_OA for dst of SA. */
#define SADB_X_EXT_NAT_T_FRAG 25 /* Manual MTU override. */
-#define SADB_EXT_MAX 25
+#define SADB_X_EXT_SA_REPLAY 26 /* Replay window override. */
+#define SADB_EXT_MAX 26
#define SADB_SATYPE_UNSPEC 0
#define SADB_SATYPE_AH 2
Index: head/sys/netipsec/ipsec.c
===================================================================
--- head/sys/netipsec/ipsec.c
+++ head/sys/netipsec/ipsec.c
@@ -251,7 +251,6 @@
#endif
static void ipsec_delpcbpolicy(struct inpcbpolicy *);
static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *src);
-static void vshiftl(unsigned char *, int, int);
MALLOC_DEFINE(M_IPSEC_INPCB, "inpcbpolicy", "inpcb-resident ipsec policy");
@@ -1476,57 +1475,70 @@
* beforehand).
* 0 (zero) is returned if packet disallowed, 1 if packet permitted.
*
- * Based on RFC 2401.
+ * Based on RFC 6479. Blocks are 32 bits unsigned integers
*/
+
+#define IPSEC_BITMAP_INDEX_MASK(w) (w - 1)
+#define IPSEC_REDUNDANT_BIT_SHIFTS 5
+#define IPSEC_REDUNDANT_BITS (1 << IPSEC_REDUNDANT_BIT_SHIFTS)
+#define IPSEC_BITMAP_LOC_MASK (IPSEC_REDUNDANT_BITS - 1)
+
int
ipsec_chkreplay(u_int32_t seq, struct secasvar *sav)
{
const struct secreplay *replay;
- u_int32_t diff;
- int fr;
- u_int32_t wsizeb; /* Constant: bits of window size. */
- int frlast; /* Constant: last frame. */
+ u_int32_t wsizeb; /* Constant: window size. */
+ int ret, index, bit_location;
IPSEC_ASSERT(sav != NULL, ("Null SA"));
IPSEC_ASSERT(sav->replay != NULL, ("Null replay state"));
+ SECASVAR_LOCK(sav);
+
+ ret = 0;
replay = sav->replay;
+ /* No need to check replay if disabled. */
if (replay->wsize == 0)
- return (1); /* No need to check replay. */
+ goto allowed;
/* Constant. */
- frlast = replay->wsize - 1;
wsizeb = replay->wsize << 3;
/* Sequence number of 0 is invalid. */
if (seq == 0)
- return (0);
+ goto end;
/* First time is always okay. */
if (replay->count == 0)
- return (1);
-
- if (seq > replay->lastseq) {
- /* Larger sequences are okay. */
- return (1);
- } else {
- /* seq is equal or less than lastseq. */
- diff = replay->lastseq - seq;
+ goto allowed;
- /* Over range to check, i.e. too old or wrapped. */
- if (diff >= wsizeb)
- return (0);
-
- fr = frlast - diff / 8;
-
- /* This packet already seen? */
- if ((replay->bitmap)[fr] & (1 << (diff % 8)))
- return (0);
+ /* Larger sequences are okay. */
+ if (seq > replay->lastseq)
+ goto allowed;
+
+ /* Over range to check, i.e. too old or wrapped. */
+ if (replay->lastseq - seq >= wsizeb)
+ goto end;
+
+ /* The sequence is inside the sliding window
+ * now check the bit in the bitmap
+ * bit location only depends on the sequence number
+ */
+ bit_location = seq & IPSEC_BITMAP_LOC_MASK;
+ index = (seq >> IPSEC_REDUNDANT_BIT_SHIFTS)
+ & IPSEC_BITMAP_INDEX_MASK(replay->bitmap_size);
+
+ /* This packet already seen? */
+ if ((replay->bitmap)[index] & (1 << bit_location))
+ goto end;
+
+allowed:
+ ret = 1;
+end:
+ SECASVAR_UNLOCK(sav);
- /* Out of order but good. */
- return (1);
- }
+ return (ret);
}
/*
@@ -1539,72 +1551,61 @@
{
char buf[128];
struct secreplay *replay;
- u_int32_t diff;
- int fr;
- u_int32_t wsizeb; /* Constant: bits of window size. */
- int frlast; /* Constant: last frame. */
+ u_int32_t wsizeb; /* Constant: window size. */
+ int ret, diff, index, bit_location;
IPSEC_ASSERT(sav != NULL, ("Null SA"));
IPSEC_ASSERT(sav->replay != NULL, ("Null replay state"));
+ SECASVAR_LOCK(sav);
+
+ ret = 1;
replay = sav->replay;
if (replay->wsize == 0)
goto ok; /* No need to check replay. */
/* Constant. */
- frlast = replay->wsize - 1;
wsizeb = replay->wsize << 3;
/* Sequence number of 0 is invalid. */
if (seq == 0)
- return (1);
+ goto end;
- /* First time. */
- if (replay->count == 0) {
- replay->lastseq = seq;
- bzero(replay->bitmap, replay->wsize);
- (replay->bitmap)[frlast] = 1;
+ /* The packet is too old, no need to update */
+ if (wsizeb + seq < replay->lastseq)
goto ok;
- }
+ /* Now update the bit */
+ index = (seq >> IPSEC_REDUNDANT_BIT_SHIFTS);
+
+ /* First check if the sequence number is in the range */
if (seq > replay->lastseq) {
- /* seq is larger than lastseq. */
- diff = seq - replay->lastseq;
+ int id;
+ int index_cur = replay->lastseq >> IPSEC_REDUNDANT_BIT_SHIFTS;
- /* New larger sequence number. */
- if (diff < wsizeb) {
- /* In window. */
- /* Set bit for this packet. */
- vshiftl(replay->bitmap, diff, replay->wsize);
- (replay->bitmap)[frlast] |= 1;
- } else {
- /* This packet has a "way larger". */
- bzero(replay->bitmap, replay->wsize);
- (replay->bitmap)[frlast] = 1;
+ diff = index - index_cur;
+ if (diff > replay->bitmap_size) {
+ /* something unusual in this case */
+ diff = replay->bitmap_size;
}
- replay->lastseq = seq;
- /* Larger is good. */
- } else {
- /* seq is equal or less than lastseq. */
- diff = replay->lastseq - seq;
-
- /* Over range to check, i.e. too old or wrapped. */
- if (diff >= wsizeb)
- return (1);
+ for (id = 0; id < diff; ++id) {
+ replay->bitmap[(id + index_cur + 1)
+ & IPSEC_BITMAP_INDEX_MASK(replay->bitmap_size)] = 0;
+ }
- fr = frlast - diff / 8;
+ replay->lastseq = seq;
+ }
- /* This packet already seen? */
- if ((replay->bitmap)[fr] & (1 << (diff % 8)))
- return (1);
+ index &= IPSEC_BITMAP_INDEX_MASK(replay->bitmap_size);
+ bit_location = seq & IPSEC_BITMAP_LOC_MASK;
- /* Mark as seen. */
- (replay->bitmap)[fr] |= (1 << (diff % 8));
+ /* this packet has already been received */
+ if (replay->bitmap[index] & (1 << bit_location))
+ goto end;
- /* Out of order but good. */
- }
+ replay->bitmap[index] |= (1 << bit_location);
ok:
if (replay->count == ~0) {
@@ -1614,39 +1615,18 @@
/* Don't increment, no more packets accepted. */
if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
- return (1);
+ goto end;
ipseclog((LOG_WARNING, "%s: replay counter made %d cycle. %s\n",
__func__, replay->overflow,
ipsec_logsastr(sav, buf, sizeof(buf))));
}
- replay->count++;
-
- return (0);
-}
+ ret = 0;
-/*
- * Shift variable length buffer to left.
- * IN: bitmap: pointer to the buffer
- * nbit: the number of to shift.
- * wsize: buffer size (bytes).
- */
-static void
-vshiftl(unsigned char *bitmap, int nbit, int wsize)
-{
- int s, j, i;
- unsigned char over;
-
- for (j = 0; j < nbit; j += 8) {
- s = (nbit - j < 8) ? (nbit - j): 8;
- bitmap[0] <<= s;
- for (i = 1; i < wsize; i++) {
- over = (bitmap[i] >> (8 - s));
- bitmap[i] <<= s;
- bitmap[i-1] |= over;
- }
- }
+end:
+ SECASVAR_UNLOCK(sav);
+ return (ret);
}
/* Return a printable string for the address. */
Index: head/sys/netipsec/key.c
===================================================================
--- head/sys/netipsec/key.c
+++ head/sys/netipsec/key.c
@@ -243,7 +243,10 @@
sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OAI */
sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OAR */
sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */
+ sizeof(struct sadb_x_sa_replay), /* SADB_X_EXT_SA_REPLAY */
};
+_Static_assert(sizeof(minsize)/sizeof(int) == SADB_EXT_MAX + 1, "minsize size mismatch");
+
static const int maxsize[] = {
sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */
sizeof(struct sadb_sa), /* SADB_EXT_SA */
@@ -271,7 +274,9 @@
0, /* SADB_X_EXT_NAT_T_OAI */
0, /* SADB_X_EXT_NAT_T_OAR */
sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */
+ sizeof(struct sadb_x_sa_replay), /* SADB_X_EXT_SA_REPLAY */
};
+_Static_assert(sizeof(maxsize)/sizeof(int) == SADB_EXT_MAX + 1, "minsize size mismatch");
static VNET_DEFINE(int, ipsec_esp_keymin) = 256;
static VNET_DEFINE(int, ipsec_esp_auth) = 0;
@@ -472,6 +477,7 @@
#define KEY_PORTTOSADDR(saddr, port) \
key_porttosaddr((struct sockaddr *)(saddr), (port))
static struct mbuf *key_setsadbxsa2(u_int8_t, u_int32_t, u_int32_t);
+static struct mbuf *key_setsadbxsareplay(u_int32_t);
static struct mbuf *key_setsadbxpolicy(u_int16_t, u_int8_t,
u_int32_t, u_int32_t);
static struct seckey *key_dup_keymsg(const struct sadb_key *, u_int,
@@ -2940,6 +2946,8 @@
sav->sched = NULL;
}
if (sav->replay != NULL) {
+ if (sav->replay->bitmap != NULL)
+ free(sav->replay->bitmap, M_IPSEC_MISC);
free(sav->replay, M_IPSEC_MISC);
sav->replay = NULL;
}
@@ -3108,6 +3116,7 @@
/* SA */
if (mhp->ext[SADB_EXT_SA] != NULL) {
const struct sadb_sa *sa0;
+ u_int32_t replay;
sa0 = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA];
if (mhp->extlen[SADB_EXT_SA] < sizeof(*sa0)) {
@@ -3119,19 +3128,57 @@
sav->alg_enc = sa0->sadb_sa_encrypt;
sav->flags = sa0->sadb_sa_flags;
- /* replay window */
- if ((sa0->sadb_sa_flags & SADB_X_EXT_OLD) == 0) {
- sav->replay = (struct secreplay *)
- malloc(sizeof(struct secreplay)+sa0->sadb_sa_replay, M_IPSEC_MISC, M_NOWAIT|M_ZERO);
- if (sav->replay == NULL) {
+ /* Optional replay window */
+ replay = 0;
+ if ((sa0->sadb_sa_flags & SADB_X_EXT_OLD) == 0)
+ replay = sa0->sadb_sa_replay;
+ if ((mhp->ext[SADB_X_EXT_SA_REPLAY]) != NULL) {
+ replay = ((const struct sadb_x_sa_replay *)
+ mhp->ext[SADB_X_EXT_SA_REPLAY])->sadb_x_sa_replay_replay;
+
+ if (replay > UINT32_MAX - 32) {
+ ipseclog((LOG_DEBUG, "%s: replay window too big.\n",
+ __func__));
+ error = EINVAL;
+ goto fail;
+ }
+
+ replay = (replay + 7) >> 3;
+ }
+
+ sav->replay = (struct secreplay *)
+ malloc(sizeof(struct secreplay),
+ M_IPSEC_MISC, M_NOWAIT|M_ZERO);
+ if (sav->replay == NULL) {
+ ipseclog((LOG_DEBUG, "%s: No more memory.\n",
+ __func__));
+ error = ENOBUFS;
+ goto fail;
+ }
+
+ if (replay != 0) {
+ /* number of 32b blocks to be allocated */
+ u_int32_t bitmap_size;
+
+ /* RFC 6479:
+ * - the allocated replay window size must be a power of two
+ * - use an extra 32b block as a redundant window
+ */
+ bitmap_size = 1;
+ while (replay + 4 > bitmap_size)
+ bitmap_size <<= 1;
+ bitmap_size = bitmap_size / 4;
+
+ sav->replay->bitmap = malloc(bitmap_size*sizeof(u_int32_t),
+ M_IPSEC_MISC, M_NOWAIT|M_ZERO);
+ if (sav->replay->bitmap == NULL) {
ipseclog((LOG_DEBUG, "%s: No more memory.\n",
__func__));
error = ENOBUFS;
goto fail;
}
- if (sa0->sadb_sa_replay != 0)
- sav->replay->bitmap = (caddr_t)(sav->replay+1);
- sav->replay->wsize = sa0->sadb_sa_replay;
+ sav->replay->bitmap_size = bitmap_size;
+ sav->replay->wsize = replay;
}
}
@@ -3406,7 +3453,7 @@
struct mbuf *result = NULL, *tres = NULL, *m;
int i;
int dumporder[] = {
- SADB_EXT_SA, SADB_X_EXT_SA2,
+ SADB_EXT_SA, SADB_X_EXT_SA2, SADB_X_EXT_SA_REPLAY,
SADB_EXT_LIFETIME_HARD, SADB_EXT_LIFETIME_SOFT,
SADB_EXT_LIFETIME_CURRENT, SADB_EXT_ADDRESS_SRC,
SADB_EXT_ADDRESS_DST, SADB_EXT_ADDRESS_PROXY, SADB_EXT_KEY_AUTH,
@@ -3419,6 +3466,7 @@
SADB_X_EXT_NAT_T_FRAG,
#endif
};
+ u_int32_t replay_count;
m = key_setsadbmsg(type, 0, satype, seq, pid, sav->refcnt);
if (m == NULL)
@@ -3435,13 +3483,25 @@
break;
case SADB_X_EXT_SA2:
- m = key_setsadbxsa2(sav->sah->saidx.mode,
- sav->replay ? sav->replay->count : 0,
+ SECASVAR_LOCK(sav);
+ replay_count = sav->replay ? sav->replay->count : 0;
+ SECASVAR_UNLOCK(sav);
+ m = key_setsadbxsa2(sav->sah->saidx.mode, replay_count,
sav->sah->saidx.reqid);
if (!m)
goto fail;
break;
+ case SADB_X_EXT_SA_REPLAY:
+ if (sav->replay == NULL ||
+ sav->replay->wsize <= UINT8_MAX)
+ continue;
+
+ m = key_setsadbxsareplay(sav->replay->wsize);
+ if (!m)
+ goto fail;
+ break;
+
case SADB_EXT_ADDRESS_SRC:
m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
&sav->sah->saidx.src.sa,
@@ -3634,7 +3694,9 @@
p->sadb_sa_len = PFKEY_UNIT64(len);
p->sadb_sa_exttype = SADB_EXT_SA;
p->sadb_sa_spi = sav->spi;
- p->sadb_sa_replay = (sav->replay != NULL ? sav->replay->wsize : 0);
+ p->sadb_sa_replay = sav->replay ?
+ (sav->replay->wsize > UINT8_MAX ?
+ UINT8_MAX : sav->replay->wsize) : 0;
p->sadb_sa_state = sav->state;
p->sadb_sa_auth = sav->alg_auth;
p->sadb_sa_encrypt = sav->alg_enc;
@@ -3719,6 +3781,32 @@
return m;
}
+/*
+ * Set data into sadb_x_sa_replay.
+ */
+static struct mbuf *
+key_setsadbxsareplay(u_int32_t replay)
+{
+ struct mbuf *m;
+ struct sadb_x_sa_replay *p;
+ size_t len;
+
+ len = PFKEY_ALIGN8(sizeof(struct sadb_x_sa_replay));
+ m = m_get2(len, M_NOWAIT, MT_DATA, 0);
+ if (m == NULL)
+ return (NULL);
+ m_align(m, len);
+ m->m_len = len;
+ p = mtod(m, struct sadb_x_sa_replay *);
+
+ bzero(p, len);
+ p->sadb_x_sa_replay_len = PFKEY_UNIT64(len);
+ p->sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY;
+ p->sadb_x_sa_replay_replay = (replay << 3);
+
+ return m;
+}
+
#ifdef IPSEC_NAT_T
/*
* Set a type in sadb_x_nat_t_type.
@@ -6853,6 +6941,7 @@
int len;
int error = -1;
struct sadb_lifetime *lt;
+ u_int32_t replay_count;
IPSEC_ASSERT (sav != NULL, ("null sav"));
IPSEC_ASSERT (sav->sah != NULL, ("null sa header"));
@@ -6876,8 +6965,11 @@
m_cat(result, m);
/* create SA extension */
- m = key_setsadbxsa2(sav->sah->saidx.mode,
- sav->replay ? sav->replay->count : 0,
+ SECASVAR_LOCK(sav);
+ replay_count = sav->replay ? sav->replay->count : 0;
+ SECASVAR_UNLOCK(sav);
+
+ m = key_setsadbxsa2(sav->sah->saidx.mode, replay_count,
sav->sah->saidx.reqid);
if (!m) {
error = ENOBUFS;
@@ -6885,6 +6977,15 @@
}
m_cat(result, m);
+ if (sav->replay && sav->replay->wsize > UINT8_MAX) {
+ m = key_setsadbxsareplay(sav->replay->wsize);
+ if (!m) {
+ error = ENOBUFS;
+ goto fail;
+ }
+ m_cat(result, m);
+ }
+
/* create lifetime extension (current and soft) */
len = PFKEY_ALIGN8(sizeof(*lt)) * 2;
m = m_get2(len, M_NOWAIT, MT_DATA, 0);
@@ -7560,6 +7661,7 @@
case SADB_X_EXT_NAT_T_OAR:
case SADB_X_EXT_NAT_T_FRAG:
#endif
+ case SADB_X_EXT_SA_REPLAY:
/* duplicate check */
/*
* XXX Are there duplication payloads of either
Index: head/sys/netipsec/key_debug.c
===================================================================
--- head/sys/netipsec/key_debug.c
+++ head/sys/netipsec/key_debug.c
@@ -570,8 +570,11 @@
if (sav->key_enc != NULL)
kdebug_sadb_key((struct sadb_ext *)sav->key_enc);
- if (sav->replay != NULL)
+ if (sav->replay != NULL) {
+ SECASVAR_LOCK(sav);
kdebug_secreplay(sav->replay);
+ SECASVAR_UNLOCK(sav);
+ }
if (sav->lft_c != NULL)
kdebug_sec_lifetime(sav->lft_c);
if (sav->lft_h != NULL)
@@ -595,8 +598,8 @@
if (rpl == NULL)
panic("%s: NULL pointer was passed.\n", __func__);
- printf(" secreplay{ count=%u wsize=%u seq=%u lastseq=%u",
- rpl->count, rpl->wsize, rpl->seq, rpl->lastseq);
+ printf(" secreplay{ count=%u bitmap_size=%u wsize=%u seq=%u lastseq=%u",
+ rpl->count, rpl->bitmap_size, rpl->wsize, rpl->seq, rpl->lastseq);
if (rpl->bitmap == NULL) {
printf(" }\n");
@@ -605,7 +608,7 @@
printf("\n bitmap { ");
- for (len = 0; len < rpl->wsize; len++) {
+ for (len = 0; len < rpl->bitmap_size*4; len++) {
for (l = 7; l >= 0; l--)
printf("%u", (((rpl->bitmap)[len] >> l) & 1) ? 1 : 0);
}
Index: head/sys/netipsec/keydb.h
===================================================================
--- head/sys/netipsec/keydb.h
+++ head/sys/netipsec/keydb.h
@@ -35,6 +35,8 @@
#ifdef _KERNEL
+#include <sys/mutex.h>
+
#include <netipsec/key_var.h>
#ifndef _SOCKADDR_UNION_DEFINED
@@ -170,14 +172,18 @@
#define SAV_ISCTR(_sav) ((_sav)->alg_enc == SADB_X_EALG_AESCTR)
#define SAV_ISCTRORGCM(_sav) (SAV_ISCTR((_sav)) || SAV_ISGCM((_sav)))
-/* replay prevention */
+/* Replay prevention, protected by SECASVAR_LOCK:
+ * (m) locked by mtx
+ * (c) read only except during creation / free
+ */
struct secreplay {
- u_int32_t count;
- u_int wsize; /* window size, i.g. 4 bytes */
- u_int32_t seq; /* used by sender */
- u_int32_t lastseq; /* used by receiver */
- caddr_t bitmap; /* used by receiver */
- int overflow; /* overflow flag */
+ u_int32_t count; /* (m) */
+ u_int wsize; /* (c) window size, i.g. 4 bytes */
+ u_int32_t seq; /* (m) used by sender */
+ u_int32_t lastseq; /* (m) used by receiver */
+ u_int32_t *bitmap; /* (m) used by receiver */
+ u_int bitmap_size; /* (c) size of the bitmap array */
+ int overflow; /* (m) overflow flag */
};
/* socket table due to send PF_KEY messages. */
Index: head/sys/netipsec/xform_ah.c
===================================================================
--- head/sys/netipsec/xform_ah.c
+++ head/sys/netipsec/xform_ah.c
@@ -961,8 +961,11 @@
/* Insert packet replay counter, as requested. */
if (sav->replay) {
+ SECASVAR_LOCK(sav);
+
if (sav->replay->count == ~0 &&
(sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
+ SECASVAR_UNLOCK(sav);
DPRINTF(("%s: replay counter wrapped for SA %s/%08lx\n",
__func__, ipsec_address(&sav->sah->saidx.dst, buf,
sizeof(buf)), (u_long) ntohl(sav->spi)));
@@ -976,6 +979,8 @@
#endif
sav->replay->count++;
ah->ah_seq = htonl(sav->replay->count);
+
+ SECASVAR_UNLOCK(sav);
}
/* Get crypto descriptors. */
Index: head/sys/netipsec/xform_esp.c
===================================================================
--- head/sys/netipsec/xform_esp.c
+++ head/sys/netipsec/xform_esp.c
@@ -762,12 +762,14 @@
if (sav->replay) {
u_int32_t replay;
+ SECASVAR_LOCK(sav);
#ifdef REGRESSION
/* Emulate replay attack when ipsec_replay is TRUE. */
if (!V_ipsec_replay)
#endif
sav->replay->count++;
replay = htonl(sav->replay->count);
+ SECASVAR_UNLOCK(sav);
bcopy((caddr_t) &replay,
mtod(mo, caddr_t) + roff + sizeof(u_int32_t),
sizeof(u_int32_t));

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 12, 4:25 PM (8 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17122608
Default Alt Text
D8468.diff (19 KB)

Event Timeline