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;