Skip to content

Commit c5c108a

Browse files
committed
ext/pcntl: fix pcntl_setns() error handling.
Save errno into a local int before calling close(fd), as close() may clobber errno on failure. Use int rather than errno_t because errno_t is defined in C11 Annex K (bounds-checking interfaces) which is optional and not widely implemented — many platforms (Linux/glibc, musl, macOS, FreeBSD) do not provide it.
1 parent fcb55f8 commit c5c108a

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

ext/pcntl/pcntl.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,7 +1584,7 @@ PHP_FUNCTION(pcntl_setns)
15841584

15851585
pid = pid_is_null ? getpid() : pid;
15861586
fd = syscall(SYS_pidfd_open, pid, 0);
1587-
if (errno) {
1587+
if (fd == -1) {
15881588
PCNTL_G(last_error) = errno;
15891589
switch (errno) {
15901590
case EINVAL:
@@ -1610,11 +1610,12 @@ PHP_FUNCTION(pcntl_setns)
16101610
RETURN_FALSE;
16111611
}
16121612
ret = setns(fd, (int)nstype);
1613+
int setns_errno = errno;
16131614
close(fd);
16141615

16151616
if (ret == -1) {
1616-
PCNTL_G(last_error) = errno;
1617-
switch (errno) {
1617+
PCNTL_G(last_error) = setns_errno;
1618+
switch (setns_errno) {
16181619
case ESRCH:
16191620
zend_argument_value_error(1, "process no longer available (" ZEND_LONG_FMT ")", pid);
16201621
RETURN_THROWS();
@@ -1624,11 +1625,11 @@ PHP_FUNCTION(pcntl_setns)
16241625
RETURN_THROWS();
16251626

16261627
case EPERM:
1627-
php_error_docref(NULL, E_WARNING, "Error %d: No required capability for this process", errno);
1628+
php_error_docref(NULL, E_WARNING, "Error %d: No required capability for this process", setns_errno);
16281629
break;
16291630

16301631
default:
1631-
php_error_docref(NULL, E_WARNING, "Error %d", errno);
1632+
php_error_docref(NULL, E_WARNING, "Error %d", setns_errno);
16321633
}
16331634
RETURN_FALSE;
16341635
} else {

0 commit comments

Comments
 (0)