From nobody@FreeBSD.org  Fri Jan 18 17:30:16 2008
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 3D8CE16A418
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 18 Jan 2008 17:30:16 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 181AC13C500
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 18 Jan 2008 17:30:16 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.2/8.14.2) with ESMTP id m0IHSqcK000905
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 18 Jan 2008 17:28:52 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.2/8.14.1/Submit) id m0IHSqHt000904;
	Fri, 18 Jan 2008 17:28:52 GMT
	(envelope-from nobody)
Message-Id: <200801181728.m0IHSqHt000904@www.freebsd.org>
Date: Fri, 18 Jan 2008 17:28:52 GMT
From: James Juran <james.juran@baesystems.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: unp_connect() locking problems with early returns
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         119778
>Category:       kern
>Synopsis:       unp_connect() locking problems with early returns
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    rwatson
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jan 18 17:40:00 UTC 2008
>Closed-Date:    Wed Jan 23 12:23:25 UTC 2008
>Last-Modified:  Wed Jan 30 22:00:05 UTC 2008
>Originator:     James Juran
>Release:        7.0-RC1
>Organization:
BAE Systems
>Environment:
N/A
>Description:
There are two early returns in unp_connect() that need to re-acquire the
UNP global lock before returning.  I tested on the December snapshot of
CURRENT-8.0, but the same problem occurs in RELENG_7.

I posted this problem to freebsd-net (http://lists.freebsd.org/pipermail/freebsd-net/2008-January/016392.html) but did not receive a response.

>How-To-Repeat:
This program will trigger a panic on a WITNESS-enabled system:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>

int main(void)
{
    int s;
    struct sockaddr_un un;

    s = socket(PF_LOCAL, SOCK_STREAM, 0);
    if (s == -1)
    {
	perror("socket");
	exit(1);
    }

    memset(&un, 0, sizeof(un));
    un.sun_family = AF_UNIX;
    if ((connect(s, (struct sockaddr *)&un, 2)) == -1)
    {
	perror("connect");
	exit(1);
    }
    return 0;
}

>Fix:
I believe this patch will fix the problem, but unfortunately I do not
have time to test it.  Could someone please try this out?  Instead of
this approach, it may be possible to move the unlocking to after the
early returns are done, but I have not analyzed what impact this would
have.

Index: uipc_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.210
diff -u -p -r1.210 uipc_usrreq.c
--- uipc_usrreq.c	1 Jan 2008 01:46:42 -0000	1.210
+++ uipc_usrreq.c	3 Jan 2008 02:53:51 -0000
@@ -1129,13 +1129,16 @@ unp_connect(struct socket *so, struct so
 	KASSERT(unp != NULL, ("unp_connect: unp == NULL"));
 
 	len = nam->sa_len - offsetof(struct sockaddr_un, sun_path);
-	if (len <= 0)
+	if (len <= 0) {
+		UNP_GLOBAL_WLOCK();
 		return (EINVAL);
+	}
 	strlcpy(buf, soun->sun_path, len + 1);
 
 	UNP_PCB_LOCK(unp);
 	if (unp->unp_flags & UNP_CONNECTING) {
 		UNP_PCB_UNLOCK(unp);
+		UNP_GLOBAL_WLOCK();
 		return (EALREADY);
 	}
 	unp->unp_flags |= UNP_CONNECTING;


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->rwatson 
Responsible-Changed-By: kris 
Responsible-Changed-When: Fri Jan 18 18:44:15 UTC 2008 
Responsible-Changed-Why:  
Assign to maintainer 

http://www.freebsd.org/cgi/query-pr.cgi?pr=119778 
State-Changed-From-To: open->patched 
State-Changed-By: rwatson 
State-Changed-When: Fri Jan 18 19:16:32 UTC 2008 
State-Changed-Why:  
Transition to patched state as I committed a fix in uipc_usrreq.c:1.214 
along the lines suggested (moving the WUNLOCK) rather than the specific 
patch included.  I'll leave the PR until this is MFC'd -- I'll request 
permission from re@ to MFC this before 7.0 is shipped.  Thanks for the 
report! 


http://www.freebsd.org/cgi/query-pr.cgi?pr=119778 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/119778: commit references a PR
Date: Fri, 18 Jan 2008 19:16:13 +0000 (UTC)

 rwatson     2008-01-18 19:16:03 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/kern             uipc_usrreq.c 
   Log:
   Move unlock of global UNIX domain socket lock slightly lower in
   unp_connect(): it is expected to return with the lock held, and two
   possible error paths otherwise returned with it unlocked.
   
   The fix committed here is slightly different from the patch in the
   PR, but along an alternative line suggested in the PR.
   
   PR:             119778
   MFC after:      3 days
   Submitted by:   James Juran <james dot juran at baesystems dot com>
   
   Revision  Changes    Path
   1.214     +1 -1      src/sys/kern/uipc_usrreq.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/119778: commit references a PR
Date: Wed, 23 Jan 2008 12:07:23 +0000 (UTC)

 rwatson     2008-01-23 12:07:17 UTC
 
   FreeBSD src repository
 
   Modified files:        (Branch: RELENG_7)
     sys/kern             uipc_usrreq.c 
   Log:
   Merge uipc_usrreq.c:1.214 from HEAD to RELENG_7:
   
     Move unlock of global UNIX domain socket lock slightly lower in
     unp_connect(): it is expected to return with the lock held, and two
     possible error paths otherwise returned with it unlocked.
   
     The fix committed here is slightly different from the patch in the
     PR, but along an alternative line suggested in the PR.
   
     PR:             119778
     Submitted by:   James Juran <james dot juran at baesystems dot com>
   
   Approved by:    re (gnn)
   
   Revision   Changes    Path
   1.206.2.1  +1 -1      src/sys/kern/uipc_usrreq.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/119778: commit references a PR
Date: Wed, 23 Jan 2008 12:08:18 +0000 (UTC)

 rwatson     2008-01-23 12:08:12 UTC
 
   FreeBSD src repository
 
   Modified files:        (Branch: RELENG_7_0)
     sys/kern             uipc_usrreq.c 
   Log:
   Merge uipc_usrreq.c:1.214 from HEAD to RELENG_7_0:
   
     Move unlock of global UNIX domain socket lock slightly lower in
     unp_connect(): it is expected to return with the lock held, and two
     possible error paths otherwise returned with it unlocked.
   
     The fix committed here is slightly different from the patch in the
     PR, but along an alternative line suggested in the PR.
   
     PR:             119778
     Submitted by:   James Juran <james dot juran at baesystems dot com>
   
   Approved by:    re (gnn)
   
   Revision   Changes    Path
   1.206.4.1  +1 -1      src/sys/kern/uipc_usrreq.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: rwatson 
State-Changed-When: Wed Jan 23 12:22:47 UTC 2008 
State-Changed-Why:  
Close PR as fixes have been merged to RELENG_7 and RELENG_7_0, and should 
appear in 7.0-RELEASE.  Thanks for the bug report and fix!  Please let me 
know if you run into any further issues with UNIX domain sockets. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=119778 

From: James Juran <james.juran@baesystems.com>
To: bug-followup@FreeBSD.org, rwatson <rwatson@FreeBSD.org>
Cc:  
Subject: Re: kern/119778: unp_connect() locking problems with early returns
Date: Fri, 25 Jan 2008 09:38:28 -0500

 Thanks very much for applying this so quickly.
 
 James
 

From: Robert Watson <rwatson@FreeBSD.org>
To: James Juran <james.juran@baesystems.com>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/119778: unp_connect() locking problems with early returns
Date: Wed, 30 Jan 2008 21:58:00 +0000 (GMT)

 On Fri, 25 Jan 2008, James Juran wrote:
 
 > Thanks very much for applying this so quickly.
 
 No problem.  Feel free to give me a ping if you run into any further problems 
 with UNIX domain sockets.
 
 Robert N M Watson
 Computer Laboratory
 University of Cambridge
>Unformatted:
