From c5c108a6e861ba835e2fb09cde7cc1018f43db91 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 19 Feb 2026 12:47:54 +0000 Subject: [PATCH] ext/pcntl: fix pcntl_setns() error handling. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- ext/pcntl/pcntl.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 2034ca80b05b8..853215e39f91d 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -1584,7 +1584,7 @@ PHP_FUNCTION(pcntl_setns) pid = pid_is_null ? getpid() : pid; fd = syscall(SYS_pidfd_open, pid, 0); - if (errno) { + if (fd == -1) { PCNTL_G(last_error) = errno; switch (errno) { case EINVAL: @@ -1610,11 +1610,12 @@ PHP_FUNCTION(pcntl_setns) RETURN_FALSE; } ret = setns(fd, (int)nstype); + int setns_errno = errno; close(fd); if (ret == -1) { - PCNTL_G(last_error) = errno; - switch (errno) { + PCNTL_G(last_error) = setns_errno; + switch (setns_errno) { case ESRCH: zend_argument_value_error(1, "process no longer available (" ZEND_LONG_FMT ")", pid); RETURN_THROWS(); @@ -1624,11 +1625,11 @@ PHP_FUNCTION(pcntl_setns) RETURN_THROWS(); case EPERM: - php_error_docref(NULL, E_WARNING, "Error %d: No required capability for this process", errno); + php_error_docref(NULL, E_WARNING, "Error %d: No required capability for this process", setns_errno); break; default: - php_error_docref(NULL, E_WARNING, "Error %d", errno); + php_error_docref(NULL, E_WARNING, "Error %d", setns_errno); } RETURN_FALSE; } else {