mirror of https://github.com/F-Stack/f-stack.git
Fix denial of service of ipsec.
Corresponding upstream changeset from https://www.freebsd.org/security/advisories/FreeBSD-SA-18:05.ipsec.asc.
This commit is contained in:
parent
04b1440d33
commit
d0b1b30af0
|
@ -301,7 +301,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||
#ifdef INET6
|
||||
struct ip6_ext *ip6e;
|
||||
struct ip6_hdr ip6;
|
||||
int alloc, len, ad;
|
||||
int ad, alloc, nxt, noff;
|
||||
#endif /* INET6 */
|
||||
|
||||
switch (proto) {
|
||||
|
@ -330,7 +330,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||
else
|
||||
ip->ip_off = htons(0);
|
||||
|
||||
ptr = mtod(m, unsigned char *) + sizeof(struct ip);
|
||||
ptr = mtod(m, unsigned char *);
|
||||
|
||||
/* IPv4 option processing */
|
||||
for (off = sizeof(struct ip); off < skip;) {
|
||||
|
@ -411,7 +411,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||
|
||||
/* Zeroize all other options. */
|
||||
count = ptr[off + 1];
|
||||
bcopy(ipseczeroes, ptr, count);
|
||||
bcopy(ipseczeroes, ptr + off, count);
|
||||
off += count;
|
||||
break;
|
||||
}
|
||||
|
@ -484,61 +484,45 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||
} else
|
||||
break;
|
||||
|
||||
off = ip6.ip6_nxt & 0xff; /* Next header type. */
|
||||
nxt = ip6.ip6_nxt & 0xff; /* Next header type. */
|
||||
|
||||
for (len = 0; len < skip - sizeof(struct ip6_hdr);)
|
||||
switch (off) {
|
||||
for (off = 0; off < skip - sizeof(struct ip6_hdr);)
|
||||
switch (nxt) {
|
||||
case IPPROTO_HOPOPTS:
|
||||
case IPPROTO_DSTOPTS:
|
||||
ip6e = (struct ip6_ext *) (ptr + len);
|
||||
ip6e = (struct ip6_ext *)(ptr + off);
|
||||
noff = off + ((ip6e->ip6e_len + 1) << 3);
|
||||
|
||||
/* Sanity check. */
|
||||
if (noff > skip - sizeof(struct ip6_hdr))
|
||||
goto error6;
|
||||
|
||||
/*
|
||||
* Process the mutable/immutable
|
||||
* options -- borrows heavily from the
|
||||
* KAME code.
|
||||
* Zero out mutable options.
|
||||
*/
|
||||
for (count = len + sizeof(struct ip6_ext);
|
||||
count < len + ((ip6e->ip6e_len + 1) << 3);) {
|
||||
for (count = off + sizeof(struct ip6_ext);
|
||||
count < noff;) {
|
||||
if (ptr[count] == IP6OPT_PAD1) {
|
||||
count++;
|
||||
continue; /* Skip padding. */
|
||||
}
|
||||
|
||||
/* Sanity check. */
|
||||
if (count > len +
|
||||
((ip6e->ip6e_len + 1) << 3)) {
|
||||
m_freem(m);
|
||||
ad = ptr[count + 1] + 2;
|
||||
if (count + ad > noff)
|
||||
goto error6;
|
||||
|
||||
/* Free, if we allocated. */
|
||||
if (alloc)
|
||||
free(ptr, M_XDATA);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
ad = ptr[count + 1];
|
||||
|
||||
/* If mutable option, zeroize. */
|
||||
if (ptr[count] & IP6OPT_MUTABLE)
|
||||
bcopy(ipseczeroes, ptr + count,
|
||||
ptr[count + 1]);
|
||||
memset(ptr + count, 0, ad);
|
||||
|
||||
count += ad;
|
||||
|
||||
/* Sanity check. */
|
||||
if (count >
|
||||
skip - sizeof(struct ip6_hdr)) {
|
||||
m_freem(m);
|
||||
|
||||
/* Free, if we allocated. */
|
||||
if (alloc)
|
||||
free(ptr, M_XDATA);
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (count != noff)
|
||||
goto error6;
|
||||
|
||||
/* Advance. */
|
||||
len += ((ip6e->ip6e_len + 1) << 3);
|
||||
off = ip6e->ip6e_nxt;
|
||||
off += ((ip6e->ip6e_len + 1) << 3);
|
||||
nxt = ip6e->ip6e_nxt;
|
||||
break;
|
||||
|
||||
case IPPROTO_ROUTING:
|
||||
|
@ -546,14 +530,15 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||
* Always include routing headers in
|
||||
* computation.
|
||||
*/
|
||||
ip6e = (struct ip6_ext *) (ptr + len);
|
||||
len += ((ip6e->ip6e_len + 1) << 3);
|
||||
off = ip6e->ip6e_nxt;
|
||||
ip6e = (struct ip6_ext *) (ptr + off);
|
||||
off += ((ip6e->ip6e_len + 1) << 3);
|
||||
nxt = ip6e->ip6e_nxt;
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINTF(("%s: unexpected IPv6 header type %d",
|
||||
__func__, off));
|
||||
error6:
|
||||
if (alloc)
|
||||
free(ptr, M_XDATA);
|
||||
m_freem(m);
|
||||
|
|
Loading…
Reference in New Issue