Module Name:    src
Committed By:   jdolecek
Date:           Tue Apr  7 15:40:14 UTC 2020

Modified Files:
        src/sys/arch/xen/include: xenbus.h
        src/sys/arch/xen/xenbus: xenbus_probe.c

Log Message:
partially convert to kmem_alloc()

plug memory leak in one xenbus_probe_device_type() error path
when read_backend_details() fails


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/xen/include/xenbus.h
cvs rdiff -u -r1.44 -r1.45 src/sys/arch/xen/xenbus/xenbus_probe.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/arch/xen/include/xenbus.h
diff -u src/sys/arch/xen/include/xenbus.h:1.19 src/sys/arch/xen/include/xenbus.h:1.20
--- src/sys/arch/xen/include/xenbus.h:1.19	Tue Apr  7 14:07:01 2020
+++ src/sys/arch/xen/include/xenbus.h	Tue Apr  7 15:40:14 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xenbus.h,v 1.19 2020/04/07 14:07:01 jdolecek Exp $ */
+/* $NetBSD: xenbus.h,v 1.20 2020/04/07 15:40:14 jdolecek Exp $ */
 /******************************************************************************
  * xenbus.h
  *
@@ -96,6 +96,7 @@ struct xenbus_device {
 	int xbusd_has_error;
 	/* for xenbus internal use */
 	struct xenbus_watch xbusd_otherend_watch;
+	size_t xbusd_sz;		/* size of allocated structure */
 	const char xbusd_path[1]; /* our path */
 };
 

Index: src/sys/arch/xen/xenbus/xenbus_probe.c
diff -u src/sys/arch/xen/xenbus/xenbus_probe.c:1.44 src/sys/arch/xen/xenbus/xenbus_probe.c:1.45
--- src/sys/arch/xen/xenbus/xenbus_probe.c:1.44	Tue Apr  7 14:07:01 2020
+++ src/sys/arch/xen/xenbus/xenbus_probe.c	Tue Apr  7 15:40:14 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xenbus_probe.c,v 1.44 2020/04/07 14:07:01 jdolecek Exp $ */
+/* $NetBSD: xenbus_probe.c,v 1.45 2020/04/07 15:40:14 jdolecek Exp $ */
 /******************************************************************************
  * Talks to Xen Store to figure out what devices we have.
  *
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xenbus_probe.c,v 1.44 2020/04/07 14:07:01 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xenbus_probe.c,v 1.45 2020/04/07 15:40:14 jdolecek Exp $");
 
 #if 0
 #define DPRINTK(fmt, args...) \
@@ -313,6 +313,7 @@ xenbus_probe_device_type(const char *pat
 {
 	int err, i, pos, msize;
 	int *lookup = NULL;
+	size_t lookup_sz = 0;
 	unsigned long state;
 	char **dir;
 	unsigned int dir_n = 0;
@@ -331,16 +332,13 @@ xenbus_probe_device_type(const char *pat
 		int minp;
 		unsigned long minv;
 		unsigned long *id;
+		size_t id_sz;
 
-		lookup = malloc(sizeof(int) * dir_n, M_DEVBUF,
-		    M_WAITOK | M_ZERO);
-		if (lookup == NULL)
-			panic("can't malloc lookup");
-
-		id = malloc(sizeof(unsigned long) * dir_n, M_DEVBUF,
-		    M_WAITOK | M_ZERO);
-		if (id == NULL)
-			panic("can't malloc id");
+		lookup_sz = sizeof(int) * dir_n;
+		lookup = kmem_zalloc(lookup_sz, KM_SLEEP);
+
+		id_sz = sizeof(unsigned long) * dir_n;
+		id = kmem_zalloc(id_sz, KM_SLEEP);
 
 		/* Convert string values to numeric; skip invalid */
 		for (i = 0; i < dir_n; i++) {
@@ -370,8 +368,9 @@ xenbus_probe_device_type(const char *pat
 			else
 				break;
 		}
-		
-		free(id, M_DEVBUF);
+
+		kmem_free(id, id_sz);
+
 		/* Adjust in case we had to skip non-numeric entries */
 		dir_n = pos;
 	}
@@ -387,15 +386,14 @@ xenbus_probe_device_type(const char *pat
 		 * already has room for one char in xbusd_path.
 		 */
 		msize = sizeof(*xbusd) + strlen(path) + strlen(dir[i]) + 2;
-		xbusd = malloc(msize, M_DEVBUF, M_WAITOK | M_ZERO);
-		if (xbusd == NULL)
-			panic("can't malloc xbusd");
-			
+		xbusd = kmem_zalloc(msize, KM_SLEEP);
+		xbusd->xbusd_sz = msize;
+
 		snprintf(__UNCONST(xbusd->xbusd_path),
 		    msize - sizeof(*xbusd) + 1, "%s/%s", path, dir[i]);
 		if (xenbus_lookup_device_path(xbusd->xbusd_path) != NULL) {
 			/* device already registered */
-			free(xbusd, M_DEVBUF);
+			kmem_free(xbusd, xbusd->xbusd_sz);
 			continue;
 		}
 		err = xenbus_read_ul(NULL, xbusd->xbusd_path, "state",
@@ -403,13 +401,13 @@ xenbus_probe_device_type(const char *pat
 		if (err) {
 			printf("xenbus: can't get state "
 			    "for %s (%d)\n", xbusd->xbusd_path, err);
-			free(xbusd, M_DEVBUF);
+			kmem_free(xbusd, xbusd->xbusd_sz);
 			err = 0;
 			continue;
 		}
 		if (state != XenbusStateInitialising) {
 			/* device is not new */
-			free(xbusd, M_DEVBUF);
+			kmem_free(xbusd, xbusd->xbusd_sz);
 			continue;
 		}
 
@@ -425,7 +423,7 @@ xenbus_probe_device_type(const char *pat
 				break;
 			}
 			if (create(xbusd)) {
-				free(xbusd, M_DEVBUF);
+				kmem_free(xbusd, xbusd->xbusd_sz);
 				continue;
 			}
 		} else {
@@ -437,19 +435,20 @@ xenbus_probe_device_type(const char *pat
 				printf("xenbus device type %s: id %s is not a"
 				    " number\n", type, dir[i]);
 				err = EFTYPE;
-				free(xbusd, M_DEVBUF);
+				kmem_free(xbusd, xbusd->xbusd_sz);
 				break;
 			}
 			err = read_backend_details(xbusd);
 			if (err != 0) {
 				printf("xenbus: can't get backend details "
 				    "for %s (%d)\n", xbusd->xbusd_path, err);
+				kmem_free(xbusd, xbusd->xbusd_sz);
 				break;
 			}
 			xbusd->xbusd_u.f.f_dev = config_found_ia(xenbus_dev,
 			    "xenbus", &xa, xenbus_print);
 			if (xbusd->xbusd_u.f.f_dev == NULL) {
-				free(xbusd, M_DEVBUF);
+				kmem_free(xbusd, xbusd->xbusd_sz);
 				continue;
 			}
 		}
@@ -459,7 +458,7 @@ xenbus_probe_device_type(const char *pat
 	}
 	free(dir, M_DEVBUF);
 	if (lookup)
-		free(lookup, M_DEVBUF);
+		kmem_free(lookup, lookup_sz);
 	
 	return err;
 }
@@ -569,7 +568,7 @@ xenbus_free_device(struct xenbus_device 
 	free_otherend_watch(xbusd);
 	free_otherend_details(xbusd);
 	xenbus_switch_state(xbusd, NULL, XenbusStateClosed);
-	free(xbusd, M_DEVBUF);
+	kmem_free(xbusd, xbusd->xbusd_sz);
 	return 0;
 }
 

Reply via email to