Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 02 Jan 2008 22:06:53 -0500
From:      James Juran <james.juran@baesystems.com>
To:        freebsd-net@freebsd.org
Subject:   unp_connect() locking problems with early returns
Message-ID:  <1199329613.2807.8.camel@big.juranfamily.org>

next in thread | raw e-mail | index | archive | help
There are two early returns in unp_connect() that need to re-acquire the
UNP global lock before returning.  This program will trigger a panic on
a WITNESS-enabled system.  I tested on the December snapshot of
CURRENT-8.0, but the same problem occurs in RELENG_7.

#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;
}

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;


-- 
James Juran
Lead Secure Systems Engineer
BAE Systems Information Technology
Information Assurance Group
XTS Operating Systems
james.juran@baesystems.com




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1199329613.2807.8.camel>