Commit 84d83425806 for php.net
commit 84d83425806217d970696a4bd52e6ab12e9f1ab3
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Sun Jun 21 08:05:21 2026 -0400
Fix posix_getpwnam()/posix_getpwuid() crash on NULL passwd fields
php_posix_passwd_to_array() passed pw_name, pw_passwd, pw_gecos, pw_dir
and pw_shell straight to add_assoc_string() with no NULL guard, so a NULL
field segfaults via zend_string_init(). glibc's files NSS backend
normalizes empty fields to "", but third-party NSS modules (nss-systemd,
nss-ldap, sssd and other directory backends) populate struct passwd
directly and may leave fields NULL. Guard each string field and emit null
instead, mirroring the existing pw/gr handling in php_posix_group_to_array().
Closes GH-22426
diff --git a/ext/posix/posix.c b/ext/posix/posix.c
index 8578056b28d..38f7eaa4186 100644
--- a/ext/posix/posix.c
+++ b/ext/posix/posix.c
@@ -910,13 +910,33 @@ int php_posix_passwd_to_array(struct passwd *pw, zval *return_value) /* {{{ */
if (NULL == return_value || Z_TYPE_P(return_value) != IS_ARRAY)
return 0;
- add_assoc_string(return_value, "name", pw->pw_name);
- add_assoc_string(return_value, "passwd", pw->pw_passwd);
- add_assoc_long (return_value, "uid", pw->pw_uid);
- add_assoc_long (return_value, "gid", pw->pw_gid);
- add_assoc_string(return_value, "gecos", pw->pw_gecos);
- add_assoc_string(return_value, "dir", pw->pw_dir);
- add_assoc_string(return_value, "shell", pw->pw_shell);
+ if (pw->pw_name) {
+ add_assoc_string(return_value, "name", pw->pw_name);
+ } else {
+ add_assoc_null(return_value, "name");
+ }
+ if (pw->pw_passwd) {
+ add_assoc_string(return_value, "passwd", pw->pw_passwd);
+ } else {
+ add_assoc_null(return_value, "passwd");
+ }
+ add_assoc_long(return_value, "uid", pw->pw_uid);
+ add_assoc_long(return_value, "gid", pw->pw_gid);
+ if (pw->pw_gecos) {
+ add_assoc_string(return_value, "gecos", pw->pw_gecos);
+ } else {
+ add_assoc_null(return_value, "gecos");
+ }
+ if (pw->pw_dir) {
+ add_assoc_string(return_value, "dir", pw->pw_dir);
+ } else {
+ add_assoc_null(return_value, "dir");
+ }
+ if (pw->pw_shell) {
+ add_assoc_string(return_value, "shell", pw->pw_shell);
+ } else {
+ add_assoc_null(return_value, "shell");
+ }
return 1;
}
/* }}} */