Module Name:    src
Committed By:   christos
Date:           Wed Dec 30 16:42:48 UTC 2015

Modified Files:
        src/external/bsd/blacklist/lib: Makefile bl.c

Log Message:
Add a mutex to prevent races during initialization code from multiple threads.
Found in named.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/blacklist/lib/Makefile
cvs rdiff -u -r1.26 -r1.27 src/external/bsd/blacklist/lib/bl.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/blacklist/lib/Makefile
diff -u src/external/bsd/blacklist/lib/Makefile:1.3 src/external/bsd/blacklist/lib/Makefile:1.4
--- src/external/bsd/blacklist/lib/Makefile:1.3	Thu Jan 22 13:46:15 2015
+++ src/external/bsd/blacklist/lib/Makefile	Wed Dec 30 11:42:48 2015
@@ -1,7 +1,10 @@
-# $NetBSD: Makefile,v 1.3 2015/01/22 18:46:15 christos Exp $
+# $NetBSD: Makefile,v 1.4 2015/12/30 16:42:48 christos Exp $
 
 USE_SHLIBDIR=   yes
 
+CPPFLAGS+=-D_REENTRANT
+DPADD+=${LIBPTHREAD}
+LPADD+=-lpthread
 LIB=blacklist
 SRCS=bl.c blacklist.c
 MAN=libblacklist.3

Index: src/external/bsd/blacklist/lib/bl.c
diff -u src/external/bsd/blacklist/lib/bl.c:1.26 src/external/bsd/blacklist/lib/bl.c:1.27
--- src/external/bsd/blacklist/lib/bl.c:1.26	Wed May 27 21:01:37 2015
+++ src/external/bsd/blacklist/lib/bl.c	Wed Dec 30 11:42:48 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: bl.c,v 1.26 2015/05/28 01:01:37 christos Exp $	*/
+/*	$NetBSD: bl.c,v 1.27 2015/12/30 16:42:48 christos Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: bl.c,v 1.26 2015/05/28 01:01:37 christos Exp $");
+__RCSID("$NetBSD: bl.c,v 1.27 2015/12/30 16:42:48 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -53,6 +53,9 @@ __RCSID("$NetBSD: bl.c,v 1.26 2015/05/28
 #include <errno.h>
 #include <stdarg.h>
 #include <netinet/in.h>
+#ifdef _REENTRANT
+#include <pthread.h>
+#endif
 
 #include "bl.h"
 
@@ -66,6 +69,16 @@ typedef struct {
 } bl_message_t;
 
 struct blacklist {
+#ifdef _REENTRANT
+	pthread_mutex_t b_mutex;
+# define BL_INIT(b)	pthread_mutex_init(&b->b_mutex, NULL)
+# define BL_LOCK(b)	pthread_mutex_lock(&b->b_mutex)
+# define BL_UNLOCK(b)	pthread_mutex_unlock(&b->b_mutex)
+#else
+# define BL_INIT(b)	do {} while(/*CONSTCOND*/0)
+# define BL_LOCK(b)	BL_INIT(b)
+# define BL_UNLOCK(b)	BL_INIT(b)
+#endif
 	int b_fd;
 	int b_connected;
 	struct sockaddr_un b_sun;
@@ -88,13 +101,17 @@ bl_getfd(bl_t b)
 }
 
 static void
-bl_reset(bl_t b)
+bl_reset(bl_t b, bool locked)
 {
 	int serrno = errno;
+	if (!locked)
+		BL_LOCK(b);
 	close(b->b_fd);
 	errno = serrno;
 	b->b_fd = -1;
 	b->b_connected = -1;
+	if (!locked)
+		BL_UNLOCK(b);
 }
 
 static void
@@ -129,12 +146,15 @@ bl_init(bl_t b, bool srv)
 #define SOCK_NOSIGPIPE 0
 #endif
 
+	BL_LOCK(b);
+
 	if (b->b_fd == -1) {
 		b->b_fd = socket(PF_LOCAL,
 		    SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK|SOCK_NOSIGPIPE, 0);
 		if (b->b_fd == -1) {
 			bl_log(b->b_fun, LOG_ERR, "%s: socket failed (%m)",
 			    __func__);
+			BL_UNLOCK(b);
 			return -1;
 		}
 #if SOCK_CLOEXEC == 0
@@ -153,9 +173,16 @@ bl_init(bl_t b, bool srv)
 #endif
 	}
 
-	if (bl_isconnected(b))
+	if (bl_isconnected(b)) {
+		BL_UNLOCK(b);
 		return 0;
+	}
 
+	/*
+	 * We try to connect anyway even when we are a server to verify
+	 * that no other server is listening to the socket. If we succeed
+	 * to connect and we are a server, someone else owns it.
+	 */
 	rv = connect(b->b_fd, (const void *)sun, (socklen_t)sizeof(*sun));
 	if (rv == 0) {
 		if (srv) {
@@ -177,6 +204,7 @@ bl_init(bl_t b, bool srv)
 				    __func__, sun->sun_path);
 				b->b_connected = 1;
 			}
+			BL_UNLOCK(b);
 			return -1;
 		}
 		bl_log(b->b_fun, LOG_DEBUG, "Connected to blacklist server",
@@ -237,9 +265,11 @@ bl_init(bl_t b, bool srv)
 	}
 #endif
 
+	BL_UNLOCK(b);
 	return 0;
 out:
-	bl_reset(b);
+	bl_reset(b, true);
+	BL_UNLOCK(b);
 	return -1;
 }
 
@@ -252,6 +282,7 @@ bl_create(bool srv, const char *path, vo
 	b->b_fun = fun == NULL ? vsyslog : fun;
 	b->b_fd = -1;
 	b->b_connected = -1;
+	BL_INIT(b);
 
 	memset(&b->b_sun, 0, sizeof(b->b_sun));
 	b->b_sun.sun_family = AF_LOCAL;
@@ -272,7 +303,7 @@ out:
 void
 bl_destroy(bl_t b)
 {
-	bl_reset(b);
+	bl_reset(b, false);
 	free(b);
 }
 
@@ -377,7 +408,7 @@ again:
 		return -1;
 
 	if ((sendmsg(b->b_fd, &msg, 0) == -1) && tried++ < NTRIES) {
-		bl_reset(b);
+		bl_reset(b, false);
 		goto again;
 	}
 	return tried >= NTRIES ? -1 : 0;

Reply via email to