Skip to content

Commit e2a5909

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. close GH-21256
1 parent 70b2761 commit e2a5909

File tree

2 files changed

+10
-5
lines changed

2 files changed

+10
-5
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ PHP NEWS
4141
- OpenSSL:
4242
. Fix a bunch of leaks and error propagation. (ndossche)
4343

44+
- PCNTL:
45+
. Fixed pcntl_setns() internal errors handling regarding errnos.
46+
(David Carlier)
47+
4448
- PDO_PGSQL:
4549
. Fixed bug GH-21055 (connection attribute status typo for GSS negotiation).
4650
(lsaos)

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)