NetBSD Problem Report #47538

From campbell@mumble.net  Wed Feb  6 21:04:44 2013
Return-Path: <campbell@mumble.net>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	by www.NetBSD.org (Postfix) with ESMTP id E2A2863E705
	for <gnats-bugs@gnats.NetBSD.org>; Wed,  6 Feb 2013 21:04:43 +0000 (UTC)
Message-Id: <20130206210409.E9480604E3@jupiter.mumble.net>
Date: Wed,  6 Feb 2013 21:04:09 +0000 (UTC)
From: Taylor R Campbell <campbell+netbsd@mumble.net>
Reply-To: Taylor R Campbell <campbell+netbsd@mumble.net>
To: gnats-bugs@gnats.NetBSD.org
Subject: races in uatp(4)
X-Send-Pr-Version: 3.95

>Number:         47538
>Category:       kern
>Synopsis:       races in uatp(4)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    riastradh
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Feb 06 21:05:00 +0000 2013
>Last-Modified:  Fri Feb 08 13:28:12 +0000 2013
>Originator:     Taylor R Campbell <campbell+netbsd@mumble.net>
>Release:        NetBSD-current
>Organization:
>Environment:
>Description:

	uatp_detach does nothing to ensure the callout is stopped
	before destroying it or to ensure that uatp_intr will not run
	before clobbering the softc structure.  sc_status, sc_input,
	sc_input_index, and sc_input_size are not protected by any
	mutex.  Also, geyser34_enable_raw_mode has a window between the
	UR_GET_REPORT and UR_SET_REPORT requests with nothing to
	prevent intervening updates to the report.  It's not clear that
	this is a problem, but it makes me nervous.

	The hardware should perhaps be reset when enabling the uhidev,
	not just when attaching the device -- that might help to fix
	the interrupt storms I have seen when starting X which the
	heuristic in uatp_intr doesn't detect.

>How-To-Repeat:

	Code inspection.

>Fix:

	Coming!

	I think that it should suffice to

	(a) extend sc_tap_mutex to cover all the mutable fields (and
	rename it to sc_lock), and

	(b) add some logic to uatp_detach to wait for the callout to
	stop running.

	In particular, I believe calling uhidev_close is enough to
	block further uatp_intr, so it is not necessary to add any
	logic to uatp_intr to check for sc_status & ENABLED.

	Eliminating the window in geyser34_enable_raw_mode might be
	best done with an additional flag in sc_status, say RESETTING,
	and an associated condvar:

static int
uatp_enter(struct uatp_softc *sc)
{
	int error;

	mutex_enter(&sc->sc_lock);
	while (ISSET(sc->sc_status, UATP_RESETTING)) {
		error = cv_timedwait_sig(&sc->sc_cv, &sc->sc_lock,
		    mstohz(1000));
		if (error)
			return error;
	}

	return 0;
}

static void
uatp_exit(struct uatp_softc *sc)
{

	mutex_exit(&sc->sc_lock);
}

static void
geyser34_enable_raw_mode(struct uatp_softc *sc)
{

	if (uatp_enter(sc) != 0)
		return;
	sc->sc_status |= UATP_RESETTING;
	uatp_exit(sc);

	...do the USB requests...

out:	mutex_enter(&sc->sc_lock);
	sc->sc_status &=~ UATP_RESETTING;
	cv_broadcast(&sc->sc_cv);
	mutex_exit(&sc->sc_lock);
}

>Release-Note:

>Audit-Trail:

Responsible-Changed-From-To: kern-bug-people->riastradh
Responsible-Changed-By: riastradh@NetBSD.org
Responsible-Changed-When: Fri, 08 Feb 2013 13:28:12 +0000
Responsible-Changed-Why:
mine


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.