From louie@whizzo.transsys.com  Mon Jan 17 21:00:26 2000
Return-Path: <louie@whizzo.transsys.com>
Received: from whizzo.transsys.com (whizzo.TransSys.COM [144.202.42.10])
	by hub.freebsd.org (Postfix) with ESMTP id D1397151BB
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 17 Jan 2000 21:00:25 -0800 (PST)
	(envelope-from louie@whizzo.transsys.com)
Received: (from louie@localhost)
	by whizzo.transsys.com (8.9.3/8.9.1) id AAA23756;
	Tue, 18 Jan 2000 00:00:23 -0500 (EST)
	(envelope-from louie)
Message-Id: <200001180500.AAA23756@whizzo.transsys.com>
Date: Tue, 18 Jan 2000 00:00:23 -0500 (EST)
From: Louis Mamakos <louie@TransSys.COM>
Sender: louie@whizzo.transsys.com
Reply-To: louie@TransSys.COM
To: FreeBSD-gnats-submit@freebsd.org,
	Nick Hibma <n_hibma@webweaving.org>
Subject: null pointer dereference in USB stack
X-Send-Pr-Version: 3.2

>Number:         16168
>Category:       kern
>Synopsis:       null pointer dereference when manipulating multiple USB endpoints
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    n_hibma
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 17 21:10:01 PST 2000
>Closed-Date:    Sun Jan 23 07:48:22 PST 2000
>Last-Modified:  Sun Jan 23 07:48:48 PST 2000
>Originator:     Louis Mamakos
>Release:        FreeBSD 4.0-CURRENT i386
>Organization:
>Environment:

Any recent 4.0-current (as of early Jan, 2000), USB device with
multiple endpoints (e.g., Handspring Visor), and using /dev/ugen0
device to diddle with.

>Description:

There's a problem with simultanous use of multiple USB endpoints on a
device.  Consider the following sequence of actions:

1.  plug in USB device with multiple endpoints, such as a Handspring
Visor.

2.  open /dev/ugen0 to get a handle on the control endpoint.

3.  open /dev/ugen0.2 to get a handle on a bulk endpoint on which
bidirectional transfers will occur.

3.  perform an ioctl(ugen0_fd, USB_SET_CONFIG, &one) operation.

3a.  then kernel will invoke ugen_set_config() in sys/dev/usb/ugen.c.  This
will perform a memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints).  Note
this zap the state associated with step (3) above, in particular,
the pipeh member of the struct ugen_endpoint structure.

4.  perform a select, read or write system call on the fd associated
with /dev/ugen0.2.  If DIAGNOSTIC is not defined, you'll eventually
dereference the pipeh structure member mentioned above.

>How-To-Repeat:

As described.

>Fix:

"It hurts when I do that.  Well, don't do that!"

Clearly, whacking the application program to perform all diddling
with the device configuration on the control endpoint before opening
the bulk endpoint is easy to do.  However, doing these operations in
the "wrong" order shouldn't cause the kernel to panic.

One simple approach is to removed the conditional #ifdef DIAGNOSTIC
around the tests in ugenpoll, ugen_do_read, ugen_do_write, etc, so that
a panic() is avoided.  This somehow seems unsatisfactory.  I suspect
that I don't completely grok the structure of the USB driver stack to
suggest a more tasteful alternative.

Perhaps some of the ioctl()'s that reset the state of the driver for
a device should be prohibited if any other endpoints are currently
open?

louie



>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->n_hibma 
Responsible-Changed-By: n_hibma 
Responsible-Changed-When: Tue Jan 18 01:24:09 PST 2000 
Responsible-Changed-Why:  
USB is mine. 
State-Changed-From-To: open->closed 
State-Changed-By: n_hibma 
State-Changed-When: Sun Jan 23 07:48:22 PST 2000 
State-Changed-Why:  
Fixed in rev. 1.35 of ugen.c 
>Unformatted:
