Add a mutex to prevent races during initialization code from multiple threads.
Found in named.
This commit is contained in:
parent
aa22af27ce
commit
13a9d5601a
|
@ -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
|
||||
|
|
|
@ -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 01:01:37 christos Exp $");
|
|||
#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, void (*fun)(int, const char *, va_list))
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue