39
39
#include <sys/resource.h>
40
40
#endif
41
41
42
+ #if defined(HAVE_EXECVEAT )
43
+ #include <fcntl.h>
44
+ #include <unistd.h>
45
+ #endif
46
+
42
47
#ifdef HAVE_WAITID
43
48
#if defined (HAVE_DECL_P_ALL ) && HAVE_DECL_P_ALL == 1
44
49
#define HAVE_POSIX_IDTYPES 1
@@ -617,6 +622,40 @@ PHP_FUNCTION(pcntl_wstopsig)
617
622
}
618
623
/* }}} */
619
624
625
+ #ifdef HAVE_EXECVEAT
626
+ static zend_always_inline zend_result php_execve (const char * path , char * * argv , char * * envp ) {
627
+ int fd = open (path , O_RDONLY | O_CLOEXEC );
628
+ if (fd < 0 ) {
629
+ return FAILURE ;
630
+ }
631
+ #ifdef AT_EXECVE_CHECK
632
+ // Linux >= 6.14 allows to check if `path` is allowed
633
+ // for execution per kernel security policy (w/o actually running it)
634
+ if (execveat (fd , "" , argv , envp , AT_EMPTY_PATH | AT_EXECVE_CHECK ) < 0 ) {
635
+ close (fd );
636
+ return FAILURE ;
637
+ }
638
+ #endif
639
+ if (execveat (fd , "" , argv , envp , AT_EMPTY_PATH ) < 0 ) {
640
+ close (fd );
641
+ return FAILURE ;
642
+ }
643
+ return SUCCESS ;
644
+ }
645
+
646
+ static zend_always_inline zend_result php_execv (const char * path , char * * argv ) {
647
+ return php_execve (path , argv , 0 );
648
+ }
649
+ #else
650
+ static zend_always_inline zend_result php_execve (const char * path , char * * argv , char * * envp ) {
651
+ return execve (path , argv , envp ) == 0 ? SUCCESS : FAILURE ;
652
+ }
653
+
654
+ static zend_always_inline zend_result php_execv (const char * path , char * * argv ) {
655
+ return execv (path , argv ) == 0 ? SUCCESS : FAILURE ;
656
+ }
657
+ #endif
658
+
620
659
/* {{{ Executes specified program in current process space as defined by exec(2) */
621
660
PHP_FUNCTION (pcntl_exec )
622
661
{
@@ -716,7 +755,7 @@ PHP_FUNCTION(pcntl_exec)
716
755
} ZEND_HASH_FOREACH_END ();
717
756
* (pair ) = NULL ;
718
757
719
- if (execve (path , argv , envp ) == -1 ) {
758
+ if (php_execve (path , argv , envp ) == FAILURE ) {
720
759
PCNTL_G (last_error ) = errno ;
721
760
php_error_docref (NULL , E_WARNING , "Error has occurred: (errno %d) %s" , errno , strerror (errno ));
722
761
}
@@ -727,7 +766,7 @@ PHP_FUNCTION(pcntl_exec)
727
766
efree (envp );
728
767
} else {
729
768
730
- if (execv (path , argv ) == -1 ) {
769
+ if (php_execv (path , argv ) == FAILURE ) {
731
770
PCNTL_G (last_error ) = errno ;
732
771
php_error_docref (NULL , E_WARNING , "Error has occurred: (errno %d) %s" , errno , strerror (errno ));
733
772
}
0 commit comments