diff options
author | archie <archie@FreeBSD.org> | 2002-12-14 00:56:07 +0000 |
---|---|---|
committer | archie <archie@FreeBSD.org> | 2002-12-14 00:56:07 +0000 |
commit | 1c7767c0c6727d617485636ac527df8828b48412 (patch) | |
tree | 0e65d6d530003e2448285e1f0bdda7f2b0f4e7dc /sys/netgraph | |
parent | 42f2975f177d686ff001a40d230fa111e5a29d56 (diff) | |
download | FreeBSD-src-1c7767c0c6727d617485636ac527df8828b48412.zip FreeBSD-src-1c7767c0c6727d617485636ac527df8828b48412.tar.gz |
Fix two bugs:
(a) Save control message return address only if NGM_MPPC_CONFIG_DECOMP
(b) Properly count the number of required re-key operations
when we loose synchronization and have to resync
MFC after: 3 days
Diffstat (limited to 'sys/netgraph')
-rw-r--r-- | sys/netgraph/ng_mppc.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c index 8da6ebd..9637df8 100644 --- a/sys/netgraph/ng_mppc.c +++ b/sys/netgraph/ng_mppc.c @@ -90,8 +90,14 @@ MALLOC_DEFINE(M_NETGRAPH_MPPC, "netgraph_mppc", "netgraph mppc node "); /* Key length */ #define KEYLEN(b) (((b) & MPPE_128) ? 16 : 8) -/* What sequence number jump is too far */ -#define MPPC_INSANE_JUMP 256 +/* + * When packets are lost with MPPE, we may have to re-key arbitrarily + * many times to 'catch up' to the new jumped-ahead sequence number. + * Since this can be expensive, we pose a limit on how many re-keyings + * we will do at one time to avoid a possible D.O.S. vulnerability. + * This should instead be a configurable parameter. + */ +#define MPPE_MAX_REKEY 1000 /* MPPC packet header bits */ #define MPPC_FLAG_FLUSHED 0x8000 /* xmitter reset state */ @@ -261,7 +267,8 @@ ng_mppc_rcvmsg(node_p node, item_p item, hook_p lasthook) cfg->bits = 0; /* Save return address so we can send reset-req's */ - priv->ctrlnode = NGI_RETADDR(item); + if (!isComp) + priv->ctrlnode = NGI_RETADDR(item); /* Configuration is OK, reset to it */ d->cfg = *cfg; @@ -566,7 +573,8 @@ ng_mppc_decompress(node_p node, struct mbuf *m, struct mbuf **resultp) { const priv_p priv = NG_NODE_PRIVATE(node); struct ng_mppc_dir *const d = &priv->recv; - u_int16_t header, cc, numLost; + u_int16_t header, cc; + u_int numLost; u_char *buf; int len; @@ -584,13 +592,8 @@ ng_mppc_decompress(node_p node, struct mbuf *m, struct mbuf **resultp) return (ENOMEM); m_copydata(m, MPPC_HDRLEN, len, (caddr_t)buf); - /* Check for insane jumps in sequence numbering (D.O.S. attack) */ + /* Check for an unexpected jump in the sequence number */ numLost = ((cc - d->cc) & MPPC_CCOUNT_MASK); - if (numLost >= MPPC_INSANE_JUMP) { - log(LOG_ERR, "%s: insane jump %d", __func__, numLost); - priv->recv.cfg.enable = 0; - goto failed; - } /* If flushed bit set, we can always handle packet */ if ((header & MPPC_FLAG_FLUSHED) != 0) { @@ -600,10 +603,22 @@ ng_mppc_decompress(node_p node, struct mbuf *m, struct mbuf **resultp) #endif #ifdef NETGRAPH_MPPC_ENCRYPTION if ((d->cfg.bits & MPPE_BITS) != 0) { + u_int rekey; + + /* How many times are we going to have to re-key? */ + rekey = ((d->cfg.bits & MPPE_STATELESS) != 0) ? + numLost : (numLost / (MPPE_UPDATE_MASK + 1)); + if (rekey > MPPE_MAX_REKEY) { + log(LOG_ERR, "%s: too many (%d) packets" + " dropped, disabling node %p!", + __func__, numLost, node); + priv->recv.cfg.enable = 0; + goto failed; + } - /* Resync as necessary, skipping lost packets */ + /* Re-key as necessary to catch up to peer */ while (d->cc != cc) { - if ((d->cfg.bits & MPPE_STATELESS) + if ((d->cfg.bits & MPPE_STATELESS) != 0 || (d->cc & MPPE_UPDATE_MASK) == MPPE_UPDATE_FLAG) { ng_mppc_updatekey(d->cfg.bits, |