@@ -77,7 +77,10 @@ typedef int gid_t;
77
77
78
78
#ifndef ZEND_WIN32
79
79
# include <sys/types.h>
80
+ # include <sys/wait.h>
80
81
# include <sys/ipc.h>
82
+ # include <pwd.h>
83
+ # include <grp.h>
81
84
#endif
82
85
83
86
#include <sys/stat.h>
@@ -4532,6 +4535,9 @@ static int accel_finish_startup(void)
4532
4535
}
4533
4536
4534
4537
if (ZCG (accel_directives ).preload && * ZCG (accel_directives ).preload ) {
4538
+ #ifndef ZEND_WIN32
4539
+ int in_child = 0 ;
4540
+ #endif
4535
4541
int ret = SUCCESS ;
4536
4542
int rc ;
4537
4543
int orig_error_reporting ;
@@ -4564,6 +4570,67 @@ static int accel_finish_startup(void)
4564
4570
return SUCCESS ;
4565
4571
}
4566
4572
4573
+ #ifndef ZEND_WIN32
4574
+ if (geteuid () == 0 ) {
4575
+ pid_t pid ;
4576
+ struct passwd * pw ;
4577
+
4578
+ if (!ZCG (accel_directives ).preload_user
4579
+ || !* ZCG (accel_directives ).preload_user ) {
4580
+ zend_shared_alloc_unlock ();
4581
+ zend_accel_error (ACCEL_LOG_FATAL , "\"opcache.preload_user\" has not been defined" );
4582
+ return FAILURE ;
4583
+ }
4584
+
4585
+ pw = getpwnam (ZCG (accel_directives ).preload_user );
4586
+ if (pw == NULL ) {
4587
+ zend_shared_alloc_unlock ();
4588
+ zend_accel_error (ACCEL_LOG_FATAL , "Preloading failed to getpwnam(\"%s\")" , ZCG (accel_directives ).preload_user );
4589
+ return FAILURE ;
4590
+ }
4591
+
4592
+ pid = fork ();
4593
+ if (pid == -1 ) {
4594
+ zend_shared_alloc_unlock ();
4595
+ zend_accel_error (ACCEL_LOG_FATAL , "Preloading failed to fork()" );
4596
+ return FAILURE ;
4597
+ } else if (pid == 0 ) { /* children */
4598
+ if (setgid (pw -> pw_gid ) < 0 ) {
4599
+ zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to setgid(%d)" , pw -> pw_gid );
4600
+ exit (1 );
4601
+ }
4602
+ if (initgroups (pw -> pw_name , pw -> pw_gid ) < 0 ) {
4603
+ zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to initgroups(\"%s\", %d)" , pw -> pw_name , pw -> pw_uid );
4604
+ exit (1 );
4605
+ }
4606
+ if (setuid (pw -> pw_uid ) < 0 ) {
4607
+ zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to setuid(%d)" , pw -> pw_uid );
4608
+ exit (1 );
4609
+ }
4610
+ in_child = 1 ;
4611
+ } else { /* parent */
4612
+ int status ;
4613
+
4614
+ if (waitpid (pid , & status , 0 ) < 0 ) {
4615
+ zend_shared_alloc_unlock ();
4616
+ zend_accel_error (ACCEL_LOG_FATAL , "Preloading failed to waitpid(%d)" , pid );
4617
+ return FAILURE ;
4618
+ }
4619
+ zend_shared_alloc_unlock ();
4620
+ if (WIFEXITED (status ) && WEXITSTATUS (status ) == 0 ) {
4621
+ return SUCCESS ;
4622
+ } else {
4623
+ return FAILURE ;
4624
+ }
4625
+ }
4626
+ } else {
4627
+ if (ZCG (accel_directives ).preload_user
4628
+ && * ZCG (accel_directives ).preload_user ) {
4629
+ zend_accel_error (ACCEL_LOG_WARNING , "\"opcache.preload_user\" is ignored" );
4630
+ }
4631
+ }
4632
+ #endif
4633
+
4567
4634
sapi_module .activate = NULL ;
4568
4635
sapi_module .deactivate = NULL ;
4569
4636
sapi_module .register_server_variables = NULL ;
@@ -4639,6 +4706,16 @@ static int accel_finish_startup(void)
4639
4706
4640
4707
sapi_activate ();
4641
4708
4709
+ #ifndef ZEND_WIN32
4710
+ if (in_child ) {
4711
+ if (ret == SUCCESS ) {
4712
+ exit (0 );
4713
+ } else {
4714
+ exit (2 );
4715
+ }
4716
+ }
4717
+ #endif
4718
+
4642
4719
return ret ;
4643
4720
}
4644
4721
0 commit comments