@@ -73,7 +73,10 @@ typedef int gid_t;
73
73
74
74
#ifndef ZEND_WIN32
75
75
# include <sys/types.h>
76
+ # include <sys/wait.h>
76
77
# include <sys/ipc.h>
78
+ # include <pwd.h>
79
+ # include <grp.h>
77
80
#endif
78
81
79
82
#include <sys/stat.h>
@@ -4478,6 +4481,9 @@ static int accel_finish_startup(void)
4478
4481
}
4479
4482
4480
4483
if (ZCG (accel_directives ).preload && * ZCG (accel_directives ).preload ) {
4484
+ #ifndef ZEND_WIN32
4485
+ int in_child = 0 ;
4486
+ #endif
4481
4487
int ret = SUCCESS ;
4482
4488
int rc ;
4483
4489
int orig_error_reporting ;
@@ -4510,6 +4516,67 @@ static int accel_finish_startup(void)
4510
4516
return SUCCESS ;
4511
4517
}
4512
4518
4519
+ #ifndef ZEND_WIN32
4520
+ if (geteuid () == 0 ) {
4521
+ pid_t pid ;
4522
+ struct passwd * pw ;
4523
+
4524
+ if (!ZCG (accel_directives ).preload_user
4525
+ || !* ZCG (accel_directives ).preload_user ) {
4526
+ zend_shared_alloc_unlock ();
4527
+ zend_accel_error (ACCEL_LOG_FATAL , "\"opcache.preload_user\" has not been defined" );
4528
+ return FAILURE ;
4529
+ }
4530
+
4531
+ pw = getpwnam (ZCG (accel_directives ).preload_user );
4532
+ if (pw == NULL ) {
4533
+ zend_shared_alloc_unlock ();
4534
+ zend_accel_error (ACCEL_LOG_FATAL , "Preloading failed to getpwnam(\"%s\")" , ZCG (accel_directives ).preload_user );
4535
+ return FAILURE ;
4536
+ }
4537
+
4538
+ pid = fork ();
4539
+ if (pid == -1 ) {
4540
+ zend_shared_alloc_unlock ();
4541
+ zend_accel_error (ACCEL_LOG_FATAL , "Preloading failed to fork()" );
4542
+ return FAILURE ;
4543
+ } else if (pid == 0 ) { /* children */
4544
+ if (setgid (pw -> pw_gid ) < 0 ) {
4545
+ zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to setgid(%d)" , pw -> pw_gid );
4546
+ exit (1 );
4547
+ }
4548
+ if (initgroups (pw -> pw_name , pw -> pw_gid ) < 0 ) {
4549
+ zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to initgroups(\"%s\", %d)" , pw -> pw_name , pw -> pw_uid );
4550
+ exit (1 );
4551
+ }
4552
+ if (setuid (pw -> pw_uid ) < 0 ) {
4553
+ zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to setuid(%d)" , pw -> pw_uid );
4554
+ exit (1 );
4555
+ }
4556
+ in_child = 1 ;
4557
+ } else { /* parent */
4558
+ int status ;
4559
+
4560
+ if (waitpid (pid , & status , 0 ) < 0 ) {
4561
+ zend_shared_alloc_unlock ();
4562
+ zend_accel_error (ACCEL_LOG_FATAL , "Preloading failed to waitpid(%d)" , pid );
4563
+ return FAILURE ;
4564
+ }
4565
+ zend_shared_alloc_unlock ();
4566
+ if (WIFEXITED (status ) && WEXITSTATUS (status ) == 0 ) {
4567
+ return SUCCESS ;
4568
+ } else {
4569
+ return FAILURE ;
4570
+ }
4571
+ }
4572
+ } else {
4573
+ if (ZCG (accel_directives ).preload_user
4574
+ && * ZCG (accel_directives ).preload_user ) {
4575
+ zend_accel_error (ACCEL_LOG_WARNING , "\"opcache.preload_user\" is ignored" );
4576
+ }
4577
+ }
4578
+ #endif
4579
+
4513
4580
sapi_module .activate = NULL ;
4514
4581
sapi_module .deactivate = NULL ;
4515
4582
sapi_module .register_server_variables = NULL ;
@@ -4585,6 +4652,16 @@ static int accel_finish_startup(void)
4585
4652
4586
4653
sapi_activate ();
4587
4654
4655
+ #ifndef ZEND_WIN32
4656
+ if (in_child ) {
4657
+ if (ret == SUCCESS ) {
4658
+ exit (0 );
4659
+ } else {
4660
+ exit (2 );
4661
+ }
4662
+ }
4663
+ #endif
4664
+
4588
4665
return ret ;
4589
4666
}
4590
4667
0 commit comments