Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 7 Jan 2009 12:38:31 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r186859 - in stable/7/sys: . contrib/pf dev/cxgb netgraph
Message-ID:  <200901071238.n07CcVke085919@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Wed Jan  7 12:38:31 2009
New Revision: 186859
URL: http://svn.freebsd.org/changeset/base/186859

Log:
  MFC rev. 185723, 186189:
  
  Carefully handle memory errors to keep peers compression/encryption state
  consistent. There are some cases reported where peers fatally getting out
  of sync without any visible reason. I hope this solve the problem.
  
  Unroll two loops of SHA1Update(). 60 bytes of static memory is not a price.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/netgraph/ng_mppc.c

Modified: stable/7/sys/netgraph/ng_mppc.c
==============================================================================
--- stable/7/sys/netgraph/ng_mppc.c	Wed Jan  7 11:54:00 2009	(r186858)
+++ stable/7/sys/netgraph/ng_mppc.c	Wed Jan  7 12:38:31 2009	(r186859)
@@ -492,17 +492,18 @@ ng_mppc_compress(node_p node, struct mbu
 		/* Work with contiguous regions of memory. */
 		inlen = m->m_pkthdr.len;
 		inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT);
-		if (inbuf == NULL) {
-			m_freem(m);
-			return (ENOMEM);
-		}
+		if (inbuf == NULL)
+			goto err1;
 		m_copydata(m, 0, inlen, (caddr_t)inbuf);
 
 		outlen = MPPC_MAX_BLOWUP(inlen);
 		outbuf = malloc(outlen, M_NETGRAPH_MPPC, M_NOWAIT);
 		if (outbuf == NULL) {
-			m_freem(m);
 			free(inbuf, M_NETGRAPH_MPPC);
+err1:
+			m_freem(m);
+			MPPC_InitCompressionHistory(d->history);
+			d->flushed = 1;
 			return (ENOMEM);
 		}
 
@@ -538,8 +539,13 @@ ng_mppc_compress(node_p node, struct mbu
 		free(outbuf, M_NETGRAPH_MPPC);
 
 		/* Check m_devget() result. */
-		if (m == NULL)
+		if (m == NULL) {
+			if (!d->flushed) {
+				MPPC_InitCompressionHistory(d->history);
+				d->flushed = 1;
+			}
 			return (ENOMEM);
+		}
 	}
 #endif
 
@@ -551,6 +557,18 @@ ng_mppc_compress(node_p node, struct mbu
 		/* Set header bits */
 		header |= MPPC_FLAG_ENCRYPTED;
 
+		/* We must own the mbuf chain exclusively to modify it. */
+		m = m_unshare(m, M_DONTWAIT);
+		if (m == NULL) {
+			if (!d->flushed) {
+#ifdef NETGRAPH_MPPC_COMPRESSION
+				MPPC_InitCompressionHistory(d->history);
+#endif
+				d->flushed = 1;
+			}
+			return (ENOMEM);
+		}
+
 		/* Update key if it's time */
 		if ((d->cfg.bits & MPPE_STATELESS) != 0
 		    || (d->cc & MPPE_UPDATE_MASK) == MPPE_UPDATE_FLAG) {
@@ -562,11 +580,6 @@ ng_mppc_compress(node_p node, struct mbu
 			rc4_init(&d->rc4, d->key, KEYLEN(d->cfg.bits));
 		}
 
-		/* We must own the mbuf chain exclusively to modify it. */
-		m = m_unshare(m, M_DONTWAIT);
-		if (m == NULL)
-			return (ENOMEM);
-
 		/* Encrypt packet */
 		m1 = m;
 		while (m1) {
@@ -811,21 +824,24 @@ ng_mppc_reset_req(node_p node)
 static void
 ng_mppc_getkey(const u_char *h, u_char *h2, int len)
 {
-	static const u_char pad1[10] =
-	    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
-	static const u_char pad2[10] =
-	    { 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, };
+	static const u_char pad1[40] =
+	    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+	static const u_char pad2[40] =
+	    { 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+	      0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+	      0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+	      0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2 };
 	u_char hash[20];
 	SHA1_CTX c;
-	int k;
 
 	SHA1Init(&c);
 	SHA1Update(&c, h, len);
-	for (k = 0; k < 4; k++)
-		SHA1Update(&c, pad1, sizeof(pad1));
+	SHA1Update(&c, pad1, sizeof(pad1));
 	SHA1Update(&c, h2, len);
-	for (k = 0; k < 4; k++)
-		SHA1Update(&c, pad2, sizeof(pad2));
+	SHA1Update(&c, pad2, sizeof(pad2));
 	SHA1Final(hash, &c);
 	bcopy(hash, h2, len);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901071238.n07CcVke085919>