NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-sparc64/51554: Avoid unsafe allocation in ldc/vdsk



>Number:         51554
>Category:       port-sparc64
>Synopsis:       Avoid unsafe allocation in ldc/vdsk
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-sparc64-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Oct 12 15:40:00 +0000 2016
>Originator:     coypu
>Release:        NetBSD 7.99.39
>Organization:
>Environment:
no sparc hardware here!
>Description:
In vdsk.c and ldc.c are some memory allocation issues.
If memory is allocation kmem_zalloc is called with KM_NOSLEEP, but failure
is not checked. If it was checked and NULL returns, it will leak memory
upon failure, so create a label for freeing previously allocated memory.

I've mentioned the memory leak to OpenBSD, but unsure if loudly enough.

sidenote: unsure whether kmem_zalloc is needed as opposed to kmem_alloc,
because I don't think OpenBSD zeroes here, but perhaps their malloc is that weird.
>How-To-Repeat:

>Fix:
Something like this may do (not even compile tested, slow machine, sorry)

Index: ldc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/dev/ldc.c,v
retrieving revision 1.2
diff -u -r1.2 ldc.c
--- ldc.c	20 Aug 2016 18:21:18 -0000	1.2
+++ ldc.c	12 Oct 2016 15:28:31 -0000
@@ -553,7 +553,8 @@
 	    BUS_DMA_NOWAIT) != 0)
 		goto unmap;
 #else
-	 va = (vaddr_t)kmem_zalloc(size, KM_NOSLEEP);
+	if ((va = (vaddr_t)kmem_zalloc(size, KM_NOSLEEP)) == NULL)
+		goto free;
 #endif
 	lq->lq_va = (vaddr_t)va;
 	lq->lq_nentries = nentries;
@@ -566,6 +567,8 @@
 destroy:
 	bus_dmamap_destroy(t, lq->lq_map);
 #endif
+free:
+	kmem_free(lq, sizeof(struct ldc_queue));
 	return (NULL);
 }
 
@@ -636,7 +639,8 @@
 		goto unmap;
 	}
 #else
-	va = (vaddr_t)kmem_zalloc(size, KM_NOSLEEP);
+	if ((va = (vaddr_t)kmem_zalloc(size, KM_NOSLEEP)) == NULL)
+		goto free;
 #endif
 	lm->lm_slot = (struct ldc_map_slot *)va;
 	lm->lm_nentries = nentries;
@@ -651,6 +655,8 @@
 destroy:
 	bus_dmamap_destroy(t, lm->lm_map);
 #endif
+free:
+	kmem_free(lm, sizeof(struct ldc_map));
 	return (NULL);
 }
 
Index: vdsk.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/dev/vdsk.c,v
retrieving revision 1.2
diff -u -r1.2 vdsk.c
--- vdsk.c	20 Aug 2016 18:21:18 -0000	1.2
+++ vdsk.c	12 Oct 2016 15:28:32 -0000
@@ -968,7 +968,8 @@
 	    BUS_DMA_NOWAIT) != 0)
 		goto unmap;
 #else
-	va = (vaddr_t)kmem_zalloc(size, KM_NOSLEEP);
+	if ((va = (vaddr_t)kmem_zalloc(size, KM_NOSLEEP)) == NULL)
+		goto free;
 #endif
 	vd->vd_desc = (struct vd_desc *)va;
 	vd->vd_nentries = nentries;
@@ -985,6 +986,8 @@
 destroy:
 	bus_dmamap_destroy(t, vd->vd_map);
 #endif
+free:
+	kmem_free(vd, sizeof(struct vdsk_dring));
 	return (NULL);
 }
 



Home | Main Index | Thread Index | Old Index