From 5331a82c487dfbccd398488b0664eaa02e82d68a Mon Sep 17 00:00:00 2001 From: anton Date: Wed, 17 Nov 2021 06:20:30 +0000 Subject: [PATCH] Fix a double free in uhidev_close() caused by a race between uhidev_open() and uhidev_close(). In uhidev_close() the UHIDEV_OPEN flag is cleared early on but the same thread can end up sleeping while closing the input or output pipe. This allows another thread to enter uhidev_open() but only to fail opening either the input or output pipe since they are already open for exclusive use. The uhidev_open() error path frees the input buffer but leaves a dangling pointer around; causing uhidev_close() to free the same buffer. This can at least happen on xhci(4) which can end up sleeping in xhci_pipe_close(). Reported by and ok gnezdo@ --- sys/dev/usb/uhidev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c index b50d4385a02..3e61642ca9e 100644 --- a/sys/dev/usb/uhidev.c +++ b/sys/dev/usb/uhidev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uhidev.c,v 1.100 2021/11/15 15:36:24 anton Exp $ */ +/* $OpenBSD: uhidev.c,v 1.101 2021/11/17 06:20:30 anton Exp $ */ /* $NetBSD: uhidev.c,v 1.14 2003/03/11 16:44:00 augustss Exp $ */ /* @@ -592,6 +592,7 @@ out2: out1: DPRINTF(("uhidev_open: failed in someway")); free(sc->sc_ibuf, M_USBDEV, sc->sc_isize); + sc->sc_ibuf = NULL; scd->sc_state &= ~UHIDEV_OPEN; sc->sc_refcnt = 0; sc->sc_ipipe = NULL; -- 2.20.1