Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Assume that SOCK_CLOEXEC is available and works
This fixes (harmless) data races when accessing the various
__have_sock_cloexec variables.
  • Loading branch information
Florian Weimer committed Oct 17, 2015
1 parent f546f87 commit 52fb79d
Show file tree
Hide file tree
Showing 11 changed files with 33 additions and 232 deletions.
22 changes: 22 additions & 0 deletions ChangeLog
@@ -1,3 +1,25 @@
2015-10-17 Florian Weimer <fweimer@redhat.com>

* sysdeps/unix/sysv/linux/kernel-features.h
(__ASSUME_SOCK_CLOEXEC): Remove.
* include/sys/socket.h (__have_sock_cloexec): Remove declaration.
(__have_paccept): Remove unused macro.
* include/unistd.h (__have_sock_cloexec): Remove declaration.
* misc/syslog.c (openlog_internal): Remove fallback code for
!__ASSUME_SOCK_CLOEXEC.
* nis/ypclnt.c (yp_bind_client_create): Remove fallback code for
missing SOCK_CLOEXEC.
* nscd/connections.c (have_sock_cloexec): Remove definition.
(nscd_init): Remove fallback code for !__ASSUME_SOCK_CLOEXEC.
* nscd/nscd_helper.c (open_socket): Remove fallback code for
!__ASSUME_SOCK_CLOEXEC.
* resolv/res_send.c (__have_o_nonblock): Remove definition.
(reopen): Remove fallback code for !__ASSUME_SOCK_CLOEXEC.
* socket/have_sock_cloexec.c (__have_sock_cloexec): Remove
definition.
* sunrpc/clnt_udp.c (__libc_clntudp_bufcreate): Remove fallback
code for !__ASSUME_SOCK_CLOEXEC.

2015-10-17 Florian Weimer <fweimer@redhat.com>

[BZ #18982]
Expand Down
8 changes: 0 additions & 8 deletions include/sys/socket.h
Expand Up @@ -154,13 +154,5 @@ libc_hidden_proto (__libc_sa_len)
# define SA_LEN(_x) __libc_sa_len((_x)->sa_family)
#endif

#ifdef SOCK_CLOEXEC
extern int __have_sock_cloexec attribute_hidden;
/* At lot of other functionality became available at the same time as
SOCK_CLOEXEC. Avoid defining separate variables for all of them
unless it is really necessary. */
# define __have_paccept __have_sock_cloexec
#endif

#endif
#endif
1 change: 0 additions & 1 deletion include/unistd.h
Expand Up @@ -170,7 +170,6 @@ extern int __libc_pause (void);
/* Not cancelable variant. */
extern int __pause_nocancel (void) attribute_hidden;

extern int __have_sock_cloexec attribute_hidden;
extern int __have_pipe2 attribute_hidden;
extern int __have_dup3 attribute_hidden;

Expand Down
33 changes: 3 additions & 30 deletions misc/syslog.c
Expand Up @@ -346,36 +346,9 @@ openlog_internal(const char *ident, int logstat, int logfac)
(void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
sizeof(SyslogAddr.sun_path));
if (LogStat & LOG_NDELAY) {
#ifdef SOCK_CLOEXEC
# ifndef __ASSUME_SOCK_CLOEXEC
if (__have_sock_cloexec >= 0) {
# endif
LogFile = __socket(AF_UNIX,
LogType
| SOCK_CLOEXEC, 0);
# ifndef __ASSUME_SOCK_CLOEXEC
if (__have_sock_cloexec == 0)
__have_sock_cloexec
= ((LogFile != -1
|| errno != EINVAL)
? 1 : -1);
}
# endif
#endif
#ifndef __ASSUME_SOCK_CLOEXEC
# ifdef SOCK_CLOEXEC
if (__have_sock_cloexec < 0)
# endif
LogFile = __socket(AF_UNIX, LogType, 0);
#endif
if (LogFile == -1)
return;
#ifndef __ASSUME_SOCK_CLOEXEC
# ifdef SOCK_CLOEXEC
if (__have_sock_cloexec < 0)
# endif
__fcntl(LogFile, F_SETFD, FD_CLOEXEC);
#endif
LogFile = __socket(AF_UNIX, LogType | SOCK_CLOEXEC, 0);
if (LogFile == -1)
return;
}
}
if (LogFile != -1 && !connected)
Expand Down
16 changes: 1 addition & 15 deletions nis/ypclnt.c
Expand Up @@ -68,25 +68,11 @@ yp_bind_client_create (const char *domain, dom_binding *ysd,
ysd->dom_domain[YPMAXDOMAIN] = '\0';

ysd->dom_socket = RPC_ANYSOCK;
#ifdef SOCK_CLOEXEC
# define xflags SOCK_CLOEXEC
#else
# define xflags 0
#endif
ysd->dom_client = __libc_clntudp_bufcreate (&ysd->dom_server_addr, YPPROG,
YPVERS, UDPTIMEOUT,
&ysd->dom_socket,
UDPMSGSIZE, UDPMSGSIZE,
xflags);

if (ysd->dom_client != NULL)
{
#ifndef SOCK_CLOEXEC
/* If the program exits, close the socket */
if (fcntl (ysd->dom_socket, F_SETFD, FD_CLOEXEC) == -1)
perror ("fcntl: F_SETFD");
#endif
}
SOCK_CLOEXEC);
}

#if USE_BINDINGDIR
Expand Down
68 changes: 1 addition & 67 deletions nscd/connections.c
Expand Up @@ -257,11 +257,6 @@ int inotify_fd = -1;
static int nl_status_fd = -1;
#endif

#ifndef __ASSUME_SOCK_CLOEXEC
/* Negative if SOCK_CLOEXEC is not supported, positive if it is, zero
before be know the result. */
static int have_sock_cloexec;
#endif
#ifndef __ASSUME_ACCEPT4
static int have_accept4;
#endif
Expand Down Expand Up @@ -830,21 +825,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
}

/* Create the socket. */
#ifndef __ASSUME_SOCK_CLOEXEC
sock = -1;
if (have_sock_cloexec >= 0)
#endif
{
sock = socket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
#ifndef __ASSUME_SOCK_CLOEXEC
if (have_sock_cloexec == 0)
have_sock_cloexec = sock != -1 || errno != EINVAL ? 1 : -1;
#endif
}
#ifndef __ASSUME_SOCK_CLOEXEC
if (have_sock_cloexec < 0)
sock = socket (AF_UNIX, SOCK_STREAM, 0);
#endif
sock = socket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
if (sock < 0)
{
dbg_log (_("cannot open socket: %s"), strerror (errno));
Expand All @@ -860,28 +841,6 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
do_exit (errno == EACCES ? 4 : 1, 0, NULL);
}

#ifndef __ASSUME_SOCK_CLOEXEC
if (have_sock_cloexec < 0)
{
/* We don't want to get stuck on accept. */
int fl = fcntl (sock, F_GETFL);
if (fl == -1 || fcntl (sock, F_SETFL, fl | O_NONBLOCK) == -1)
{
dbg_log (_("cannot change socket to nonblocking mode: %s"),
strerror (errno));
do_exit (1, 0, NULL);
}

/* The descriptor needs to be closed on exec. */
if (paranoia && fcntl (sock, F_SETFD, FD_CLOEXEC) == -1)
{
dbg_log (_("cannot set socket to close on exec: %s"),
strerror (errno));
do_exit (1, 0, NULL);
}
}
#endif

/* Set permissions for the socket. */
chmod (_PATH_NSCDSOCKET, DEFFILEMODE);

Expand Down Expand Up @@ -922,31 +881,6 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
/* Start the timestamp process. */
dbs[hstdb].head->extra_data[NSCD_HST_IDX_CONF_TIMESTAMP]
= __bump_nl_timestamp ();

# ifndef __ASSUME_SOCK_CLOEXEC
if (have_sock_cloexec < 0)
{
/* We don't want to get stuck on accept. */
int fl = fcntl (nl_status_fd, F_GETFL);
if (fl == -1
|| fcntl (nl_status_fd, F_SETFL, fl | O_NONBLOCK) == -1)
{
dbg_log (_("\
cannot change socket to nonblocking mode: %s"),
strerror (errno));
do_exit (1, 0, NULL);
}

/* The descriptor needs to be closed on exec. */
if (paranoia
&& fcntl (nl_status_fd, F_SETFD, FD_CLOEXEC) == -1)
{
dbg_log (_("cannot set socket to close on exec: %s"),
strerror (errno));
do_exit (1, 0, NULL);
}
}
# endif
}
}
}
Expand Down
27 changes: 1 addition & 26 deletions nscd/nscd_helper.c
Expand Up @@ -166,24 +166,7 @@ open_socket (request_type type, const char *key, size_t keylen)
{
int sock;

#ifdef SOCK_CLOEXEC
# ifndef __ASSUME_SOCK_CLOEXEC
if (__have_sock_cloexec >= 0)
# endif
{
sock = __socket (PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
# ifndef __ASSUME_SOCK_CLOEXEC
if (__have_sock_cloexec == 0)
__have_sock_cloexec = sock != -1 || errno != EINVAL ? 1 : -1;
# endif
}
#endif
#ifndef __ASSUME_SOCK_CLOEXEC
# ifdef SOCK_CLOEXEC
if (__have_sock_cloexec < 0)
# endif
sock = __socket (PF_UNIX, SOCK_STREAM, 0);
#endif
sock = __socket (PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
if (sock < 0)
return -1;

Expand All @@ -194,14 +177,6 @@ open_socket (request_type type, const char *key, size_t keylen)
char key[];
} *reqdata = alloca (real_sizeof_reqdata);

#ifndef __ASSUME_SOCK_CLOEXEC
# ifdef SOCK_NONBLOCK
if (__have_sock_cloexec < 0)
# endif
/* Make socket non-blocking. */
__fcntl (sock, F_SETFL, O_RDWR | O_NONBLOCK);
#endif

struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
strcpy (sun.sun_path, _PATH_NSCDSOCKET);
Expand Down
49 changes: 4 additions & 45 deletions resolv/res_send.c
Expand Up @@ -104,14 +104,6 @@ static const char rcsid[] = "$BINDId: res_send.c,v 8.38 2000/03/30 20:16:51 vixi
#define MAXPACKET 65536
#endif


#ifndef __ASSUME_SOCK_CLOEXEC
static int __have_o_nonblock;
#else
# define __have_o_nonblock 0
#endif


/* From ev_streams.c. */

static inline void
Expand Down Expand Up @@ -927,38 +919,14 @@ reopen (res_state statp, int *terrno, int ns)

/* only try IPv6 if IPv6 NS and if not failed before */
if (nsap->sa_family == AF_INET6 && !statp->ipv6_unavail) {
if (__glibc_likely (__have_o_nonblock >= 0)) {
EXT(statp).nssocks[ns] =
socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK,
0);
#ifndef __ASSUME_SOCK_CLOEXEC
if (__have_o_nonblock == 0)
__have_o_nonblock
= (EXT(statp).nssocks[ns] == -1
&& errno == EINVAL ? -1 : 1);
#endif
}
if (__glibc_unlikely (__have_o_nonblock < 0))
EXT(statp).nssocks[ns] =
socket(PF_INET6, SOCK_DGRAM, 0);
EXT(statp).nssocks[ns]
= socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK, 0);
if (EXT(statp).nssocks[ns] < 0)
statp->ipv6_unavail = errno == EAFNOSUPPORT;
slen = sizeof (struct sockaddr_in6);
} else if (nsap->sa_family == AF_INET) {
if (__glibc_likely (__have_o_nonblock >= 0)) {
EXT(statp).nssocks[ns]
= socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK,
0);
#ifndef __ASSUME_SOCK_CLOEXEC
if (__have_o_nonblock == 0)
__have_o_nonblock
= (EXT(statp).nssocks[ns] == -1
&& errno == EINVAL ? -1 : 1);
#endif
}
if (__glibc_unlikely (__have_o_nonblock < 0))
EXT(statp).nssocks[ns]
= socket(PF_INET, SOCK_DGRAM, 0);
EXT(statp).nssocks[ns]
= socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, 0);
slen = sizeof (struct sockaddr_in);
}
if (EXT(statp).nssocks[ns] < 0) {
Expand All @@ -983,15 +951,6 @@ reopen (res_state statp, int *terrno, int ns)
__res_iclose(statp, false);
return (0);
}
if (__glibc_unlikely (__have_o_nonblock < 0)) {
/* Make socket non-blocking. */
int fl = __fcntl (EXT(statp).nssocks[ns], F_GETFL);
if (fl != -1)
__fcntl (EXT(statp).nssocks[ns], F_SETFL,
fl | O_NONBLOCK);
Dprint(statp->options & RES_DEBUG,
(stdout, ";; new DG socket\n"))
}
}

return 1;
Expand Down
4 changes: 0 additions & 4 deletions socket/have_sock_cloexec.c
Expand Up @@ -19,10 +19,6 @@
#include <sys/socket.h>
#include <kernel-features.h>

#if defined SOCK_CLOEXEC && !defined __ASSUME_SOCK_CLOEXEC
int __have_sock_cloexec;
#endif

#if defined O_CLOEXEC && !defined __ASSUME_PIPE2
int __have_pipe2;
#endif
Expand Down
36 changes: 1 addition & 35 deletions sunrpc/clnt_udp.c
Expand Up @@ -171,31 +171,7 @@ __libc_clntudp_bufcreate (struct sockaddr_in *raddr, u_long program,
cu->cu_xdrpos = XDR_GETPOS (&(cu->cu_outxdrs));
if (*sockp < 0)
{
#ifdef SOCK_NONBLOCK
# ifndef __ASSUME_SOCK_CLOEXEC
if (__have_sock_cloexec >= 0)
# endif
{
*sockp = __socket (AF_INET, SOCK_DGRAM|SOCK_NONBLOCK|flags,
IPPROTO_UDP);
# ifndef __ASSUME_SOCK_CLOEXEC
if (__have_sock_cloexec == 0)
__have_sock_cloexec = *sockp >= 0 || errno != EINVAL ? 1 : -1;
# endif
}
#endif
#ifndef __ASSUME_SOCK_CLOEXEC
# ifdef SOCK_CLOEXEC
if (__have_sock_cloexec < 0)
# endif
{
*sockp = __socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
# ifdef SOCK_CLOEXEC
if (flags & SOCK_CLOEXEC)
__fcntl (*sockp, F_SETFD, FD_CLOEXEC);
# endif
}
#endif
*sockp = __socket (AF_INET, SOCK_DGRAM|SOCK_NONBLOCK|flags, IPPROTO_UDP);
if (__glibc_unlikely (*sockp < 0))
{
struct rpc_createerr *ce = &get_rpc_createerr ();
Expand All @@ -205,16 +181,6 @@ __libc_clntudp_bufcreate (struct sockaddr_in *raddr, u_long program,
}
/* attempt to bind to prov port */
(void) bindresvport (*sockp, (struct sockaddr_in *) 0);
#ifndef __ASSUME_SOCK_CLOEXEC
# ifdef SOCK_CLOEXEC
if (__have_sock_cloexec < 0)
# endif
{
/* the sockets rpc controls are non-blocking */
int dontblock = 1;
(void) __ioctl (*sockp, FIONBIO, (char *) &dontblock);
}
#endif
#ifdef IP_RECVERR
{
int on = 1;
Expand Down
1 change: 0 additions & 1 deletion sysdeps/unix/sysv/linux/kernel-features.h
Expand Up @@ -86,7 +86,6 @@

/* Support for various CLOEXEC and NONBLOCK flags was added in
2.6.27. */
#define __ASSUME_SOCK_CLOEXEC 1
#define __ASSUME_IN_NONBLOCK 1
#define __ASSUME_PIPE2 1
#define __ASSUME_EVENTFD2 1
Expand Down

0 comments on commit 52fb79d

Please sign in to comment.