Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Apr 2004 13:09:29 +0300
From:      Ruslan Ermilov <ru@FreeBSD.org>
To:        Julian Elischer <julian@elischer.org>, Archie Cobbs <archie@FreeBSD.org>
Cc:        Julian Elischer <julian@FreeBSD.org>
Subject:   Re: ng_bridge(4) has an easily exploitable memory leak
Message-ID:  <20040408100929.GD16290@ip.net.ua>
In-Reply-To: <Pine.BSF.4.21.0404071227420.34985-100000@InterJet.elischer.org>
References:  <20040407191003.GA1136@ip.net.ua> <Pine.BSF.4.21.0404071227420.34985-100000@InterJet.elischer.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--jkO+KyKz7TfD21mV
Content-Type: multipart/mixed; boundary="gMR3gsNFwZpnI/Ts"
Content-Disposition: inline


--gMR3gsNFwZpnI/Ts
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Wed, Apr 07, 2004 at 12:28:38PM -0700, Julian Elischer wrote:
> On Wed, 7 Apr 2004, Ruslan Ermilov wrote:
>=20
> > On RELENG_4, ng_bridge(4) has an easily exploitable memory leak,
> > and may quickly run system out of mbufs.  It's enough to just
> > have only one link connected to the bridge, e.g., the "upper"
> > hook of the ng_ether(4) with IP address assigned, and pinging
> > the broadcast IP address on the interface.  The bug is more
> > real when constructing a bridge, or, like we experienced it,
> > by shutting down all except one bridge's link.  The following
> > patch fixes it:
> >=20
[snipped]

> > An alternate solution is to MFC most of ng_bridge.c,v 1.8.  Julian?
>=20
> what does an MFC diff look like?
> (bridge is one of archies's nodes)
>=20
But it was _you_ who masked this bugfix (which would equally apply
to RELENG_4 as well) under the "SMP preparation" emblem.  ;)

Anyway, the patch for RELENG_4 is attached.  I've only compile tested
it.


Cheers,
--=20
Ruslan Ermilov
ru@FreeBSD.org
FreeBSD committer

--gMR3gsNFwZpnI/Ts
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=p
Content-Transfer-Encoding: quoted-printable

Index: ng_bridge.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/netgraph/ng_bridge.c,v
retrieving revision 1.1.2.6
diff -u -p -r1.1.2.6 ng_bridge.c
--- ng_bridge.c	9 Jan 2004 08:58:06 -0000	1.1.2.6
+++ ng_bridge.c	8 Apr 2004 09:53:43 -0000
@@ -518,7 +518,8 @@ ng_bridge_rcvdata(hook_p hook, struct mb
 	struct ng_bridge_link *link;
 	struct ether_header *eh;
 	int error =3D 0, linkNum;
-	int i, manycast;
+	int manycast;
+	struct ng_bridge_link *firstLink;
=20
 	/* Get link number */
 	linkNum =3D LINK_NUM(hook);
@@ -657,20 +658,43 @@ ng_bridge_rcvdata(hook_p hook, struct mb
 	}
=20
 	/* Distribute unknown, multicast, broadcast pkts to all other links */
-	for (linkNum =3D i =3D 0; i < priv->numLinks - 1; linkNum++) {
-		struct ng_bridge_link *const destLink =3D priv->links[linkNum];
+	firstLink =3D NULL;
+	for (linkNum =3D 0; linkNum <=3D priv->numLinks; linkNum++) {
+		struct ng_bridge_link *destLink;
 		meta_p meta2 =3D NULL;
-		struct mbuf *m2;
+		struct mbuf *m2 =3D NULL;
=20
-		/* Skip incoming link and disconnected links */
-		if (destLink =3D=3D NULL || destLink =3D=3D link)
-			continue;
-
-		/* Copy mbuf and meta info */
-		if (++i =3D=3D priv->numLinks - 1) {		/* last link */
-			m2 =3D m;
-			meta2 =3D meta;
-		}  else {
+		/*
+		 * If we have checked all the links then now
+		 * send the original on its reserved link
+		 */
+		if (linkNum =3D=3D priv->numLinks) {
+			/* If we never saw a good link, leave. */
+			if (firstLink =3D=3D NULL) {
+				NG_FREE_DATA(m, meta);
+				return (0);
+			}=09
+			destLink =3D firstLink;
+		} else {
+			destLink =3D priv->links[linkNum];
+			/* Skip incoming link and disconnected links */
+			if (destLink =3D=3D NULL || destLink =3D=3D link) {
+				continue;
+			}
+			if (firstLink =3D=3D NULL) {
+				/*
+				 * This is the first usable link we have found.
+				 * Reserve it for the originals.
+				 * If we never find another we save a copy.
+				 */
+				firstLink =3D destLink;
+				continue;
+			}
+
+			/*
+			 * It's usable link but not the reserved (first) one.
+			 * Copy mbuf and meta info for sending.
+			 */
 			m2 =3D m_dup(m, M_NOWAIT);	/* XXX m_copypacket() */
 			if (m2 =3D=3D NULL) {
 				link->stats.memoryFailures++;
@@ -701,7 +725,16 @@ ng_bridge_rcvdata(hook_p hook, struct mb
 		}
=20
 		/* Send packet */
-		NG_SEND_DATA(error, destLink->hook, m2, meta2);
+		if (destLink =3D=3D firstLink) {=20
+			/*
+			 * If we've sent all the others, send the original
+			 * on the first link we found.
+			 */
+			NG_SEND_DATA(error, destLink->hook, m, meta);
+			break; /* always done last - not really needed. */
+		} else {
+			NG_SEND_DATA(error, destLink->hook, m2, meta2);
+		}
 	}
 	return (error);
 }

--gMR3gsNFwZpnI/Ts--

--jkO+KyKz7TfD21mV
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (FreeBSD)

iD8DBQFAdSTZUkv4P6juNwoRAp/cAJ4pDK1arhdvuPRodwJgPhMhv07oRQCdH9fX
xet0k5yoCDF04g6dHqTzWsQ=
=Mo22
-----END PGP SIGNATURE-----

--jkO+KyKz7TfD21mV--



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