Subject: patch for memory leak
To: , , <tech-kern@netbsd.org>
From: Ted U <grendel@heorot.stanford.edu>
List: tech-kern
Date: 05/03/2001 00:32:28
following is a patch that fixes 3 occurences of realloc in BSD kernels
that could result in a memory leak.  if realloc returns null, then the
previously held memory is not freed.  the affected areas are ipfilter and
usb audio.

ted

--
Ted Unangst -- grendel@heorot.stanford.edu -- http://heorot.stanford.edu/
Keep your vogue code that all have.   /   Tomorrow's world we've all seen.
Keep your modern ways and keep your bugs. / The metal man is here to stay.
                           - Theatre of Tragedy, "Machine"


PATCH:
Fixes memory leaks in BSD.  This patch applies clean against OpenBSD
-current.  NetBSD and FreeBSD should also be patchable like this,
though the offsets and file locations may differ.

--- sys/netient/ip_fil.c.orig	Sun Apr 29 20:07:08 2001
+++ sys/netinet/ip_fil.c	Sun Apr 29 20:30:34 2001
@@ -1638,8 +1638,9 @@
 char *name;
 int v;
 {
 	struct ifnet *ifp, **ifa;
+	struct ifnet **old_ifneta;
 # if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
 	(defined(OpenBSD) && (OpenBSD >= 199603))
 	for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
 		if (!strcmp(name, ifp->if_xname))
@@ -1667,11 +1668,13 @@
 		}
 		nifs = 1;
 	} else {
 		nifs++;
+		old_ifneta = ifneta;
 		ifneta = (struct ifnet **)realloc(ifneta,
 						  (nifs + 1) * sizeof(*ifa));
 		if (!ifneta) {
+			free(old_ifneta);
 			nifs = 0;
 			return NULL;
 		}
 		ifneta[nifs] = NULL;
--- sys/dev/usb/uaudio.c.orig	Sun Apr 29 20:07:18 2001
+++ sys/dev/usb/uaudio.c	Sun Apr 29 20:22:25 2001
@@ -534,16 +534,21 @@
 void
 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
 {
 	int res;
+	struct mixerctl *old_ctls = NULL;

 	if (sc->sc_nctls == 0)
 		sc->sc_ctls = malloc(sizeof *mc, M_USBDEV, M_NOWAIT);
-	else
+	else {
+		old_ctls = sc->sc_ctls;
 		sc->sc_ctls = realloc(sc->sc_ctls,
 				      (sc->sc_nctls+1) * sizeof *mc,
 				      M_USBDEV, M_NOWAIT);
+	}
 	if (sc->sc_ctls == NULL) {
+		if (old_ctls)
+			free(old_ctls, M_USBDEV);
 		printf("uaudio_mixer_add_ctl: no memory\n");
 		return;
 	}

@@ -1015,15 +1020,21 @@

 void
 uaudio_add_alt(struct uaudio_softc *sc, struct as_info *ai)
 {
+	struct as_info *old_alts = NULL;
+
 	if (sc->sc_nalts == 0)
 		sc->sc_alts = malloc(sizeof *ai, M_USBDEV, M_NOWAIT);
-	else
+	else {
+		old_alts = sc->sc_alts;
 		sc->sc_alts = realloc(sc->sc_alts,
 				      (sc->sc_nalts+1) * sizeof *ai,
 				      M_USBDEV, M_NOWAIT);
+	}
 	if (sc->sc_alts == NULL) {
+		if(old_alts)
+			free(old_alts, M_USBDEV);
 		printf("uaudio_add_alt: no memory\n");
 		return;
 	}
 	DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",