131 lines
3.1 KiB
Diff
131 lines
3.1 KiB
Diff
--- sys/netipsec/xform_ah.c.orig
|
|
+++ sys/netipsec/xform_ah.c
|
|
@@ -264,7 +264,7 @@
|
|
#ifdef INET6
|
|
struct ip6_ext *ip6e;
|
|
struct ip6_hdr ip6;
|
|
- int alloc, len, ad;
|
|
+ int ad, alloc, nxt, noff;
|
|
#endif /* INET6 */
|
|
|
|
switch (proto) {
|
|
@@ -293,7 +293,7 @@
|
|
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;) {
|
|
@@ -374,7 +374,7 @@
|
|
|
|
/* Zeroize all other options. */
|
|
count = ptr[off + 1];
|
|
- bcopy(ipseczeroes, ptr, count);
|
|
+ bcopy(ipseczeroes, ptr + off, count);
|
|
off += count;
|
|
break;
|
|
}
|
|
@@ -447,61 +447,44 @@
|
|
} 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);
|
|
+ if (count != noff)
|
|
+ goto error6;
|
|
|
|
- /* Free, if we allocated. */
|
|
- if (alloc)
|
|
- free(ptr, M_XDATA);
|
|
- return EINVAL;
|
|
- }
|
|
- }
|
|
-
|
|
/* 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:
|
|
@@ -509,14 +492,15 @@
|
|
* 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);
|