Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb ugen(4): Keep fields null when not allocated; ka...
details: https://anonhg.NetBSD.org/src/rev/12e798f7d2f3
branches: trunk
changeset: 1023434:12e798f7d2f3
user: riastradh <riastradh%NetBSD.org@localhost>
date: Tue Sep 07 10:44:04 2021 +0000
description:
ugen(4): Keep fields null when not allocated; kassert on close.
This avoids silent leaks in DIAGNOSTIC kernels.
diffstat:
sys/dev/usb/ugen.c | 38 +++++++++++++++++++++++++++-----------
1 files changed, 27 insertions(+), 11 deletions(-)
diffs (128 lines):
diff -r 010214ff1359 -r 12e798f7d2f3 sys/dev/usb/ugen.c
--- a/sys/dev/usb/ugen.c Tue Sep 07 10:43:51 2021 +0000
+++ b/sys/dev/usb/ugen.c Tue Sep 07 10:44:04 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ugen.c,v 1.166 2021/09/07 10:43:51 riastradh Exp $ */
+/* $NetBSD: ugen.c,v 1.167 2021/09/07 10:44:04 riastradh Exp $ */
/*
* Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.166 2021/09/07 10:43:51 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.167 2021/09/07 10:44:04 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@@ -669,8 +669,10 @@
DPRINTFN(5, ("ugenopen: isoc open done\n"));
break;
bad:
- while (--i >= 0) /* implicit buffer free */
+ while (--i >= 0) { /* implicit buffer free */
usbd_destroy_xfer(sce->isoreqs[i].xfer);
+ sce->isoreqs[i].xfer = NULL;
+ }
usbd_close_pipe(sce->pipeh);
sce->pipeh = NULL;
kmem_free(sce->ibuf, isize * UGEN_NISOFRAMES);
@@ -699,13 +701,8 @@
KASSERT(KERNEL_LOCKED_P()); /* sc_is_open */
- if (!sc->sc_is_open[endpt]) {
- KASSERT(sc->sc_endpoints[endpt][IN].pipeh == NULL);
- KASSERT(sc->sc_endpoints[endpt][OUT].pipeh == NULL);
- KASSERT(sc->sc_endpoints[endpt][IN].ibuf == NULL);
- KASSERT(sc->sc_endpoints[endpt][OUT].ibuf == NULL);
- return;
- }
+ if (!sc->sc_is_open[endpt])
+ goto out;
if (endpt == USB_CONTROL_ENDPOINT) {
DPRINTFN(5, ("ugenclose: close control\n"));
@@ -733,13 +730,16 @@
msize = isize;
break;
case UE_ISOCHRONOUS:
- for (i = 0; i < UGEN_NISOREQS; ++i)
+ for (i = 0; i < UGEN_NISOREQS; ++i) {
usbd_destroy_xfer(sce->isoreqs[i].xfer);
+ sce->isoreqs[i].xfer = NULL;
+ }
msize = isize * UGEN_NISOFRAMES;
break;
case UE_BULK:
if (sce->state & (UGEN_BULK_RA | UGEN_BULK_WB)) {
usbd_destroy_xfer(sce->ra_wb_xfer);
+ sce->ra_wb_xfer = NULL;
msize = sce->ra_wb_bufsize;
}
break;
@@ -755,6 +755,14 @@
}
out: sc->sc_is_open[endpt] = 0;
+ for (dir = OUT; dir <= IN; dir++) {
+ sce = &sc->sc_endpoints[endpt][dir];
+ KASSERT(sce->pipeh == NULL);
+ KASSERT(sce->ibuf == NULL);
+ KASSERT(sce->ra_wb_xfer == NULL);
+ for (i = 0; i < UGEN_NISOREQS; i++)
+ KASSERT(sce->isoreqs[i].xfer == NULL);
+ }
}
static int
@@ -1649,6 +1657,8 @@
/* Only turn RA on if it's currently off. */
if (sce->state & UGEN_BULK_RA)
return 0;
+ KASSERT(sce->ra_wb_xfer == NULL);
+ KASSERT(sce->ibuf == NULL);
if (sce->ra_wb_bufsize == 0 || sce->ra_wb_reqsize == 0)
/* shouldn't happen */
@@ -1674,6 +1684,7 @@
kmem_free(sce->ibuf, sce->ra_wb_bufsize);
sce->ibuf = NULL;
usbd_destroy_xfer(sce->ra_wb_xfer);
+ sce->ra_wb_xfer = NULL;
return EIO;
}
} else {
@@ -1684,6 +1695,7 @@
sce->state &= ~UGEN_BULK_RA;
usbd_abort_pipe(sce->pipeh);
usbd_destroy_xfer(sce->ra_wb_xfer);
+ sce->ra_wb_xfer = NULL;
/*
* XXX Discard whatever's in the buffer, but we
* should keep it around and drain the buffer
@@ -1707,12 +1719,15 @@
/* Only turn WB on if it's currently off. */
if (sce->state & UGEN_BULK_WB)
return 0;
+ KASSERT(sce->ra_wb_xfer == NULL);
+ KASSERT(sce->ibuf == NULL);
if (sce->ra_wb_bufsize == 0 || sce->ra_wb_reqsize == 0)
/* shouldn't happen */
return EINVAL;
error = usbd_create_xfer(sce->pipeh, sce->ra_wb_reqsize,
0, 0, &sce->ra_wb_xfer);
+ /* XXX check error??? */
sce->ra_wb_xferlen = sce->ra_wb_reqsize;
sce->ibuf = kmem_alloc(sce->ra_wb_bufsize, KM_SLEEP);
sce->fill = sce->cur = sce->ibuf;
@@ -1732,6 +1747,7 @@
*/
usbd_abort_pipe(sce->pipeh);
usbd_destroy_xfer(sce->ra_wb_xfer);
+ sce->ra_wb_xfer = NULL;
kmem_free(sce->ibuf, sce->ra_wb_bufsize);
sce->ibuf = NULL;
}
Home |
Main Index |
Thread Index |
Old Index