Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/usb Reset ud_ifaces and ud_cdesc to NULL, to prevent...



details:   https://anonhg.NetBSD.org/src/rev/35c7c9551f5b
branches:  trunk
changeset: 933948:35c7c9551f5b
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sun May 31 18:33:08 2020 +0000

description:
Reset ud_ifaces and ud_cdesc to NULL, to prevent use-after-free in
usb_free_device().

Reported-by: syzbot+c7e74d0ae89e9f08f863%syzkaller.appspotmail.com@localhost

diffstat:

 sys/dev/usb/usb_subr.c |  13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diffs (41 lines):

diff -r 79a65813574f -r 35c7c9551f5b sys/dev/usb/usb_subr.c
--- a/sys/dev/usb/usb_subr.c    Sun May 31 18:20:23 2020 +0000
+++ b/sys/dev/usb/usb_subr.c    Sun May 31 18:33:08 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usb_subr.c,v 1.246 2020/05/31 18:20:23 jdolecek Exp $  */
+/*     $NetBSD: usb_subr.c,v 1.247 2020/05/31 18:33:08 maxv Exp $      */
 /*     $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $   */
 
 /*
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.246 2020/05/31 18:20:23 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.247 2020/05/31 18:33:08 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -734,14 +734,21 @@
                if (err) {
                        while (--ifcidx >= 0)
                                usbd_free_iface_data(dev, ifcidx);
+                       kmem_free(dev->ud_ifaces,
+                           nifc * sizeof(struct usbd_interface));
+                       dev->ud_ifaces = NULL;
                        goto bad;
                }
        }
 
        return USBD_NORMAL_COMPLETION;
 
- bad:
+bad:
+       /* XXX Use usbd_set_config() to reset the config? */
+       /* XXX Should we forbid USB_UNCONFIG_NO from bConfigurationValue? */
+       dev->ud_config = USB_UNCONFIG_NO;
        kmem_free(cdp, len);
+       dev->ud_cdesc = NULL;
        if (bdp != NULL) {
                kmem_free(bdp, UGETW(bdp->wTotalLength));
                dev->ud_bdesc = NULL;



Home | Main Index | Thread Index | Old Index