diff --git a/auto/unix b/auto/unix index 10835f6c..b5b33bb3 100644 --- a/auto/unix +++ b/auto/unix @@ -990,3 +990,27 @@ ngx_feature_test='struct addrinfo *res; if (getaddrinfo("localhost", NULL, NULL, &res) != 0) return 1; freeaddrinfo(res)' . auto/feature + +ngx_feature="SOCK_CLOEXEC support" +ngx_feature_name="NGX_HAVE_SOCKET_CLOEXEC" +ngx_feature_run=no +ngx_feature_incs="#include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="int fd; + fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);" +. auto/feature + +ngx_feature="FD_CLOEXEC support" +ngx_feature_name="NGX_HAVE_FD_CLOEXEC" +ngx_feature_run=no +ngx_feature_incs="#include + #include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="int fd; + fd = socket(AF_INET, SOCK_STREAM, 0); + fcntl(fd, F_SETFD, FD_CLOEXEC);" +. auto/feature diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c index cd55520c..438e0806 100644 --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -4466,8 +4466,14 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec) ngx_event_t *rev, *wev; ngx_connection_t *c; +#if (NGX_HAVE_SOCKET_CLOEXEC) + s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0); + +#else s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM, 0); +#endif + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &rec->log, 0, "TCP socket %d", s); if (s == (ngx_socket_t) -1) { @@ -4494,6 +4500,15 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec) goto failed; } +#if (NGX_HAVE_FD_CLOEXEC) + if (ngx_cloexec(s) == -1) { + ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno, + ngx_cloexec_n " failed"); + + goto failed; + } +#endif + rev = c->read; wev = c->write; diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index 19fec68..8c2f01a 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -73,6 +73,9 @@ struct ngx_event_s { /* to test on worker exit */ unsigned channel:1; unsigned resolver:1; +#if (HAVE_SOCKET_CLOEXEC_PATCH) + unsigned skip_socket_leak_check:1; +#endif unsigned cancelable:1; diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index 77563709..5827b9d0 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -62,7 +62,9 @@ ngx_event_accept(ngx_event_t *ev) #if (NGX_HAVE_ACCEPT4) if (use_accept4) { - s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK); + s = accept4(lc->fd, &sa.sockaddr, &socklen, + SOCK_NONBLOCK | SOCK_CLOEXEC); + } else { s = accept(lc->fd, &sa.sockaddr, &socklen); } @@ -202,6 +204,16 @@ ngx_event_accept(ngx_event_t *ev) ngx_close_accepted_connection(c); return; } + +#if (NGX_HAVE_FD_CLOEXEC) + if (ngx_cloexec(s) == -1) { + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, + ngx_cloexec_n " failed"); + ngx_close_accepted_connection(c); + return; + } +#endif + } } diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c index c5bb8068..cf33b1d2 100644 --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -38,8 +38,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) type = (pc->type ? pc->type : SOCK_STREAM); +#if (NGX_HAVE_SOCKET_CLOEXEC) + s = ngx_socket(pc->sockaddr->sa_family, type | SOCK_CLOEXEC, 0); + +#else s = ngx_socket(pc->sockaddr->sa_family, type, 0); +#endif + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, "%s socket %d", (type == SOCK_STREAM) ? "stream" : "dgram", s); @@ -80,6 +87,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) goto failed; } +#if (NGX_HAVE_FD_CLOEXEC) + if (ngx_cloexec(s) == -1) { + ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, + ngx_cloexec_n " failed"); + + goto failed; + } +#endif + if (pc->local) { #if (NGX_HAVE_TRANSPARENT_PROXY) diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index c4376a5..48e8fa8 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -1032,6 +1032,9 @@ ngx_worker_process_exit(ngx_cycle_t *cycle) for (i = 0; i < cycle->connection_n; i++) { if (c[i].fd != -1 && c[i].read +#if (HAVE_SOCKET_CLOEXEC_PATCH) + && !c[i].read->skip_socket_leak_check +#endif && !c[i].read->accept && !c[i].read->channel && !c[i].read->resolver) diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h index fcc51533..d1eebf47 100644 --- a/src/os/unix/ngx_socket.h +++ b/src/os/unix/ngx_socket.h @@ -38,6 +38,17 @@ int ngx_blocking(ngx_socket_t s); #endif +#if (NGX_HAVE_FD_CLOEXEC) + +#define ngx_cloexec(s) fcntl(s, F_SETFD, FD_CLOEXEC) +#define ngx_cloexec_n "fcntl(FD_CLOEXEC)" + +/* at least FD_CLOEXEC is required to ensure connection fd is closed + * after execve */ +#define HAVE_SOCKET_CLOEXEC_PATCH 1 + +#endif + int ngx_tcp_nopush(ngx_socket_t s); int ngx_tcp_push(ngx_socket_t s); an>Ludovic Courtès 2020-05-03locale: Add glibc 2.29 to '%default-locale-libcs'....This eases transition for anyone reconfiguring and still having profiles with packages using the former libc. * gnu/system/locale.scm (%default-locale-libcs): Add GLIBC-2.29. Ludovic Courtès 2020-02-12system: locale: Remove canonical-package call....This is a follow-up of dfc8ccbf5da96a67eb1cade499f0def21e7fdb02. Building locales using the same glibc as the one programs are linked against is enough. * gnu/system/locale.scm (%default-locale-libcs): Use the plain glibc package. Mathieu Othacehe 2020-02-11system: Stop using canonical-package....Usage of canonical-package outside of thunked fields breaks cross-compilation, see: https://lists.gnu.org/archive/html/guix-devel/2019-12/msg00410.html. * gnu/installer.scm (installer-program): Remove canonical-package. * gnu/services/base.scm (<nscd-cache>): Ditto, (%base-services): ditto. * gnu/services/xorg.scm: Remove useless canonical-package import. * gnu/system.scm (%base-packages): Remove canonical-package. * gnu/system/install.scm (%installation-services): Ditto, (installation-os): ditto. * gnu/system/locale.scm (single-locale-directory): Ditto. Mathieu Othacehe