co...@sdf.org
unread,Oct 12, 2016, 11:40:12 AM10/12/16You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to port-sparc6...@netbsd.org, gnats...@netbsd.org, netbs...@netbsd.org
>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);
}