Merge branch 'master' into staging
[jackhill/guix/guix.git] / gnu / packages / patches / nginx-socket-cloexec.patch
CommitLineData
4b0e08be
OP
1diff --git a/auto/unix b/auto/unix
2index 10835f6c..b5b33bb3 100644
3--- a/auto/unix
4+++ b/auto/unix
5@@ -990,3 +990,27 @@ ngx_feature_test='struct addrinfo *res;
6 if (getaddrinfo("localhost", NULL, NULL, &res) != 0) return 1;
7 freeaddrinfo(res)'
8 . auto/feature
9+
10+ngx_feature="SOCK_CLOEXEC support"
11+ngx_feature_name="NGX_HAVE_SOCKET_CLOEXEC"
12+ngx_feature_run=no
13+ngx_feature_incs="#include <sys/types.h>
14+ #include <sys/socket.h>"
15+ngx_feature_path=
16+ngx_feature_libs=
17+ngx_feature_test="int fd;
18+ fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);"
19+. auto/feature
20+
21+ngx_feature="FD_CLOEXEC support"
22+ngx_feature_name="NGX_HAVE_FD_CLOEXEC"
23+ngx_feature_run=no
24+ngx_feature_incs="#include <sys/types.h>
25+ #include <sys/socket.h>
26+ #include <fcntl.h>"
27+ngx_feature_path=
28+ngx_feature_libs=
29+ngx_feature_test="int fd;
30+ fd = socket(AF_INET, SOCK_STREAM, 0);
31+ fcntl(fd, F_SETFD, FD_CLOEXEC);"
32+. auto/feature
33diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
34index cd55520c..438e0806 100644
35--- a/src/core/ngx_resolver.c
36+++ b/src/core/ngx_resolver.c
37@@ -4466,8 +4466,14 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec)
38 ngx_event_t *rev, *wev;
39 ngx_connection_t *c;
40
41+#if (NGX_HAVE_SOCKET_CLOEXEC)
42+ s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0);
43+
44+#else
45 s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM, 0);
46
47+#endif
48+
49 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &rec->log, 0, "TCP socket %d", s);
50
51 if (s == (ngx_socket_t) -1) {
52@@ -4494,6 +4500,15 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec)
53 goto failed;
54 }
55
56+#if (NGX_HAVE_FD_CLOEXEC)
57+ if (ngx_cloexec(s) == -1) {
58+ ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno,
59+ ngx_cloexec_n " failed");
60+
61+ goto failed;
62+ }
63+#endif
64+
65 rev = c->read;
66 wev = c->write;
67
68diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
69index 19fec68..8c2f01a 100644
70--- a/src/event/ngx_event.h
71+++ b/src/event/ngx_event.h
72@@ -73,6 +73,9 @@ struct ngx_event_s {
73 /* to test on worker exit */
74 unsigned channel:1;
75 unsigned resolver:1;
76+#if (HAVE_SOCKET_CLOEXEC_PATCH)
77+ unsigned skip_socket_leak_check:1;
78+#endif
79
80 unsigned cancelable:1;
81
82diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
83index 77563709..5827b9d0 100644
84--- a/src/event/ngx_event_accept.c
85+++ b/src/event/ngx_event_accept.c
86@@ -62,7 +62,9 @@ ngx_event_accept(ngx_event_t *ev)
87
88 #if (NGX_HAVE_ACCEPT4)
89 if (use_accept4) {
90- s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK);
91+ s = accept4(lc->fd, &sa.sockaddr, &socklen,
92+ SOCK_NONBLOCK | SOCK_CLOEXEC);
93+
94 } else {
95 s = accept(lc->fd, &sa.sockaddr, &socklen);
96 }
97@@ -202,6 +204,16 @@ ngx_event_accept(ngx_event_t *ev)
98 ngx_close_accepted_connection(c);
99 return;
100 }
101+
102+#if (NGX_HAVE_FD_CLOEXEC)
103+ if (ngx_cloexec(s) == -1) {
104+ ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
105+ ngx_cloexec_n " failed");
106+ ngx_close_accepted_connection(c);
107+ return;
108+ }
109+#endif
110+
111 }
112 }
113
114diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c
115index c5bb8068..cf33b1d2 100644
116--- a/src/event/ngx_event_connect.c
117+++ b/src/event/ngx_event_connect.c
118@@ -38,8 +38,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
119
120 type = (pc->type ? pc->type : SOCK_STREAM);
121
122+#if (NGX_HAVE_SOCKET_CLOEXEC)
123+ s = ngx_socket(pc->sockaddr->sa_family, type | SOCK_CLOEXEC, 0);
124+
125+#else
126 s = ngx_socket(pc->sockaddr->sa_family, type, 0);
127
128+#endif
129+
130+
131 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, "%s socket %d",
132 (type == SOCK_STREAM) ? "stream" : "dgram", s);
133
134@@ -80,6 +87,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
135 goto failed;
136 }
137
138+#if (NGX_HAVE_FD_CLOEXEC)
139+ if (ngx_cloexec(s) == -1) {
140+ ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
141+ ngx_cloexec_n " failed");
142+
143+ goto failed;
144+ }
145+#endif
146+
147 if (pc->local) {
148
149 #if (NGX_HAVE_TRANSPARENT_PROXY)
150diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
151index c4376a5..48e8fa8 100644
152--- a/src/os/unix/ngx_process_cycle.c
153+++ b/src/os/unix/ngx_process_cycle.c
154@@ -1032,6 +1032,9 @@ ngx_worker_process_exit(ngx_cycle_t *cycle)
155 for (i = 0; i < cycle->connection_n; i++) {
156 if (c[i].fd != -1
157 && c[i].read
158+#if (HAVE_SOCKET_CLOEXEC_PATCH)
159+ && !c[i].read->skip_socket_leak_check
160+#endif
161 && !c[i].read->accept
162 && !c[i].read->channel
163 && !c[i].read->resolver)
164diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h
165index fcc51533..d1eebf47 100644
166--- a/src/os/unix/ngx_socket.h
167+++ b/src/os/unix/ngx_socket.h
168@@ -38,6 +38,17 @@ int ngx_blocking(ngx_socket_t s);
169
170 #endif
171
172+#if (NGX_HAVE_FD_CLOEXEC)
173+
174+#define ngx_cloexec(s) fcntl(s, F_SETFD, FD_CLOEXEC)
175+#define ngx_cloexec_n "fcntl(FD_CLOEXEC)"
176+
177+/* at least FD_CLOEXEC is required to ensure connection fd is closed
178+ * after execve */
179+#define HAVE_SOCKET_CLOEXEC_PATCH 1
180+
181+#endif
182+
183 int ngx_tcp_nopush(ngx_socket_t s);
184 int ngx_tcp_push(ngx_socket_t s);
185