From ilepore@damnhippie.dyndns.org  Sun Oct 30 19:40:24 2011
Return-Path: <ilepore@damnhippie.dyndns.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id AB608106564A
	for <freebsd-gnats-submit@freebsd.org>; Sun, 30 Oct 2011 19:40:24 +0000 (UTC)
	(envelope-from ilepore@damnhippie.dyndns.org)
Received: from qmta08.emeryville.ca.mail.comcast.net (qmta08.emeryville.ca.mail.comcast.net [76.96.30.80])
	by mx1.freebsd.org (Postfix) with ESMTP id 9116B8FC0A
	for <freebsd-gnats-submit@freebsd.org>; Sun, 30 Oct 2011 19:40:24 +0000 (UTC)
Received: from omta20.emeryville.ca.mail.comcast.net ([76.96.30.87])
	by qmta08.emeryville.ca.mail.comcast.net with comcast
	id r7GK1h0011smiN4A87gG6z; Sun, 30 Oct 2011 19:40:16 +0000
Received: from damnhippie.dyndns.org ([24.8.232.202])
	by omta20.emeryville.ca.mail.comcast.net with comcast
	id r7a21h0064NgCEG8g7a658; Sun, 30 Oct 2011 19:34:06 +0000
Received: from revolution.hippie.lan (revolution.hippie.lan [172.22.42.240])
	by damnhippie.dyndns.org (8.14.3/8.14.3) with ESMTP id p9UJeIDt044357
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 30 Oct 2011 13:40:18 -0600 (MDT)
	(envelope-from ilepore@damnhippie.dyndns.org)
Received: (from ilepore@localhost)
	by revolution.hippie.lan (8.14.5/8.14.4/Submit) id p9UJeITQ049268;
	Sun, 30 Oct 2011 13:40:18 -0600 (MDT)
	(envelope-from ilepore)
Message-Id: <201110301940.p9UJeITQ049268@revolution.hippie.lan>
Date: Sun, 30 Oct 2011 13:40:18 -0600 (MDT)
From: Ian Lepore <freebsd@damnhippie.dyndns.org>
Reply-To: Ian Lepore <freebsd@damnhippie.dyndns.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] rman_manage_region() error return path leaves mutex locked
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         162174
>Category:       kern
>Synopsis:       [kernel] [patch] rman_manage_region() error return path leaves mutex locked
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Oct 30 19:50:11 UTC 2011
>Closed-Date:    Fri Nov 02 22:16:57 UTC 2012
>Last-Modified:  Fri Nov 02 22:16:57 UTC 2012
>Originator:     Ian Lepore <freebsd@damnhippie.dyndns.org>
>Release:        FreeBSD 8.2-STABLE
>Organization:
Symmetricom, Inc.
>Environment:
FreeBSD tflex 8.2-STABLE FreeBSD 8.2-STABLE #29: Tue Oct 11 13:32:35 UTC 2011     root@revolution.hippie.lan:/usr/obj/arm/usr/src/sys/TFLEX  arm

>Description:
If rman_manage_region() detects an overlapping region and returns EBUSY it
leaves the rman mutex locked, causing a panic on some future rman call.

>How-To-Repeat:

>Fix:
This patch was generated against 8.2-STABLE but applies cleanly to -current.
The error handling idiom in this module seems to be the "goto out" style so
I did this same way.

--- kern_subr.diff begins here ---
diff -r 96e180d3dc91 sys/kern/subr_rman.c
--- sys/kern/subr_rman.c.orig	Sat Oct 29 17:47:07 2011 -0600
+++ sys/kern/subr_rman.c	Sun Oct 30 13:23:14 2011 -0600
@@ -158,6 +158,7 @@ rman_init(struct rman *rm)
 int
 rman_manage_region(struct rman *rm, u_long start, u_long end)
 {
+	int rv;
 	struct resource_i *r, *s, *t;
 
 	DPRINTF(("rman_manage_region: <%s> request: start %#lx, end %#lx\n",
@@ -184,14 +185,16 @@ rman_manage_region(struct rman *rm, u_lo
 		TAILQ_INSERT_TAIL(&rm->rm_list, r, r_link);
 	} else {
 		/* Check for any overlap with the current region. */
-		if (r->r_start <= s->r_end && r->r_end >= s->r_start)
-			return EBUSY;
-
+		if (r->r_start <= s->r_end && r->r_end >= s->r_start) {
+			rv = EBUSY;
+			goto out;
+		}
 		/* Check for any overlap with the next region. */
 		t = TAILQ_NEXT(s, r_link);
-		if (t && r->r_start <= t->r_end && r->r_end >= t->r_start)
-			return EBUSY;
-
+		if (t && r->r_start <= t->r_end && r->r_end >= t->r_start) {
+			rv = EBUSY;
+			goto out;
+		}
 		/*
 		 * See if this region can be merged with the next region.  If
 		 * not, clear the pointer.
@@ -222,8 +225,10 @@ rman_manage_region(struct rman *rm, u_lo
 		}
 	}
 
+	rv = 0;
+out:
 	mtx_unlock(rm->rm_mtx);
-	return 0;
+	return (rv);
 }
 
 int
--- kern_subr.diff ends here ---

>Release-Note:
>Audit-Trail:

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/162174: commit references a PR
Date: Thu, 31 May 2012 17:27:19 +0000 (UTC)

 Author: imp
 Date: Thu May 31 17:27:05 2012
 New Revision: 236359
 URL: http://svn.freebsd.org/changeset/base/236359
 
 Log:
   Unlock in the error path to prevent a lock leak.
   
   PR:		162174
   Submitted by:	Ian Lepore
   MFC after:	2 weeks
 
 Modified:
   head/sys/kern/subr_rman.c
 
 Modified: head/sys/kern/subr_rman.c
 ==============================================================================
 --- head/sys/kern/subr_rman.c	Thu May 31 14:47:02 2012	(r236358)
 +++ head/sys/kern/subr_rman.c	Thu May 31 17:27:05 2012	(r236359)
 @@ -161,6 +161,7 @@ int
  rman_manage_region(struct rman *rm, u_long start, u_long end)
  {
  	struct resource_i *r, *s, *t;
 +	int rv = 0;
  
  	DPRINTF(("rman_manage_region: <%s> request: start %#lx, end %#lx\n",
  	    rm->rm_descr, start, end));
 @@ -188,13 +189,17 @@ rman_manage_region(struct rman *rm, u_lo
  		TAILQ_INSERT_TAIL(&rm->rm_list, r, r_link);
  	} else {
  		/* Check for any overlap with the current region. */
 -		if (r->r_start <= s->r_end && r->r_end >= s->r_start)
 -			return EBUSY;
 +		if (r->r_start <= s->r_end && r->r_end >= s->r_start) {
 +			rv = EBUSY;
 +			goto out;
 +		}
  
  		/* Check for any overlap with the next region. */
  		t = TAILQ_NEXT(s, r_link);
 -		if (t && r->r_start <= t->r_end && r->r_end >= t->r_start)
 -			return EBUSY;
 +		if (t && r->r_start <= t->r_end && r->r_end >= t->r_start) {
 +			rv = EBUSY;
 +			goto out;
 +		}
  
  		/*
  		 * See if this region can be merged with the next region.  If
 @@ -225,9 +230,9 @@ rman_manage_region(struct rman *rm, u_lo
  			TAILQ_INSERT_BEFORE(s, r, r_link);
  		}
  	}
 -
 +out:
  	mtx_unlock(rm->rm_mtx);
 -	return 0;
 +	return rv;
  }
  
  int
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: imp 
State-Changed-When: Thu May 31 11:36:42 MDT 2012 
State-Changed-Why:  
Committed. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=162174 
State-Changed-From-To: patched->closed 
State-Changed-By: eadler 
State-Changed-When: Fri Nov 2 22:16:56 UTC 2012 
State-Changed-Why:  
fixed/mfced by now 

http://www.freebsd.org/cgi/query-pr.cgi?pr=162174 
>Unformatted:
