@@ -167,6 +167,25 @@ struct fpm_child_s *fpm_child_find(pid_t pid) /* {{{ */
167
167
}
168
168
/* }}} */
169
169
170
+ static int fpm_child_cloexec (void )
171
+ {
172
+ /* If PHP code invokes pcntl_fork()/exec(), we don't want the external programm to inherit the descriptor.
173
+ If the external process accidentally uses the socket it will likely break the communication */
174
+ int attrs = fcntl (fpm_globals .listening_socket , F_GETFD );
175
+ if (0 > attrs ) {
176
+ zlog (ZLOG_WARNING , "failed to get attributes of listening socket, errno: %d" , errno );
177
+ return -1 ;
178
+ }
179
+
180
+ /* set CLOEXEC to prevent the descriptor leaking to child processes */
181
+ if (0 > fcntl (fpm_globals .listening_socket , F_SETFD , attrs | FD_CLOEXEC )) {
182
+ zlog (ZLOG_WARNING , "failed to change attribute of listening socket" );
183
+ return -1 ;
184
+ }
185
+
186
+ return 0 ;
187
+ }
188
+
170
189
static void fpm_child_init (struct fpm_worker_pool_s * wp ) /* {{{ */
171
190
{
172
191
fpm_globals .max_requests = wp -> config -> pm_max_requests ;
@@ -178,7 +197,8 @@ static void fpm_child_init(struct fpm_worker_pool_s *wp) /* {{{ */
178
197
0 > fpm_unix_init_child (wp ) ||
179
198
0 > fpm_signals_init_child () ||
180
199
0 > fpm_env_init_child (wp ) ||
181
- 0 > fpm_php_init_child (wp )) {
200
+ 0 > fpm_php_init_child (wp ) ||
201
+ 0 > fpm_child_cloexec ()) {
182
202
183
203
zlog (ZLOG_ERROR , "[pool %s] child failed to initialize" , wp -> config -> name );
184
204
exit (FPM_EXIT_SOFTWARE );
0 commit comments