Module Name:    src
Committed By:   martin
Date:           Sun Apr  1 08:48:39 UTC 2018

Modified Files:
        src/sys/netipsec [netbsd-8]: xform_ah.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #680):

        sys/netipsec/xform_ah.c: revision 1.87
        sys/netipsec/xform_ah.c: revision 1.77

Reinforce and clarify.

Reinforce this area, make sure the length field fits the option. Normally
it always does because the options were already sanitized earlier.


To generate a diff of this commit:
cvs rdiff -u -r1.54.2.5 -r1.54.2.6 src/sys/netipsec/xform_ah.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netipsec/xform_ah.c
diff -u src/sys/netipsec/xform_ah.c:1.54.2.5 src/sys/netipsec/xform_ah.c:1.54.2.6
--- src/sys/netipsec/xform_ah.c:1.54.2.5	Mon Feb 26 18:42:49 2018
+++ src/sys/netipsec/xform_ah.c	Sun Apr  1 08:48:39 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ah.c,v 1.54.2.5 2018/02/26 18:42:49 martin Exp $	*/
+/*	$NetBSD: xform_ah.c,v 1.54.2.6 2018/04/01 08:48:39 martin Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
 /*
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.54.2.5 2018/02/26 18:42:49 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.54.2.6 2018/04/01 08:48:39 martin Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -491,54 +491,48 @@ ah_massage_headers(struct mbuf **m0, int
 
 		nxt = ip6.ip6_nxt & 0xff; /* Next header type. */
 
-		for (off = 0; off < skip - sizeof(struct ip6_hdr);)
+		for (off = 0; off < skip - sizeof(struct ip6_hdr);) {
+			int noff;
+
 			switch (nxt) {
 			case IPPROTO_HOPOPTS:
 			case IPPROTO_DSTOPTS:
-				ip6e = (struct ip6_ext *) (ptr + off);
+				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 = off + sizeof(struct ip6_ext);
-				     count < off + ((ip6e->ip6e_len + 1) << 3);) {
+				     count < noff;) {
 					if (ptr[count] == IP6OPT_PAD1) {
 						count++;
-						continue; /* Skip padding. */
+						continue;
 					}
 
-					/* Sanity check. */
-					if (count > off +
-					    ((ip6e->ip6e_len + 1) << 3)) {
-						m_freem(m);
-
-						/* Free, if we allocated. */
-						if (alloc)
-							free(ptr, M_XDATA);
-						return EINVAL;
+					if (count + 1 >= noff) {
+						goto error6;
 					}
-
 					ad = ptr[count + 1] + 2;
 
-					/* If mutable option, zeroize. */
-					if (ptr[count] & IP6OPT_MUTABLE)
-						memcpy(ptr + count, ipseczeroes,
-						    ad);
+					if (count + ad > noff) {
+						goto error6;
+					}
+
+					if (ptr[count] & IP6OPT_MUTABLE) {
+						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. */
@@ -551,7 +545,7 @@ ah_massage_headers(struct mbuf **m0, int
 				 * Always include routing headers in
 				 * computation.
 				 */
-				ip6e = (struct ip6_ext *) (ptr + off);
+				ip6e = (struct ip6_ext *)(ptr + off);
 				rh = (struct ip6_rthdr *)(ptr + off);
 				/*
 				 * must adjust content to make it look like
@@ -592,11 +586,13 @@ ah_massage_headers(struct mbuf **m0, int
 			default:
 				DPRINTF(("%s: unexpected IPv6 header type %d\n",
 				    __func__, off));
+error6:
 				if (alloc)
 					free(ptr, M_XDATA);
 				m_freem(m);
 				return EINVAL;
 			}
+		}
 
 		/* Copyback and free, if we allocated. */
 		if (alloc) {

Reply via email to