|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-02-25 21:10 UTC] dan at syneto dot net
Description:
------------
This is a bug in function php_get_current_user (main.c) when compiling in a standards compliant environment on Illumos or Solaris based systems. It might also be happening on Linux or other Unix systems that follow the below semantics of getpwuid.
This is the relevant section from the getpwnam_r() manual from Illumos:
=== (illumos) man getpwuid_r ===
...
The standard-conforming functions getpwnam_r() and getpwuid_r() can
return 0 even on an error, particularly in the case where the requested
entry is not found. The application needs to check the return value and
that the pwd pointer is non-null. Otherwise, an error value is returned
to indicate the error.
...
The same issue is pointed to by the equivalent section on Linux systems:
=== (linux) man getpwuid_r ===
...
If no matching password record was found, these functions return 0 and store NULL in *result
...
When running the test script, make sure you are root and able to run sudo to change its owner to a non-existent UID using:
$ sudo chown 31415 get_current_user.php
You will not need to run the script as root. Just make sure its owner UID does not exist in /etc/passwd.
I also attached a patch that properly checks for a NULL result.
Test script:
---------------
=== First code:
<?php
echo "Owner: " . get_current_user() . "\n";
=== Second code:
<?php
array_fill(5, 6, 'banana');
echo "Owner: " . get_current_user() . "\n";
Expected result:
----------------
=== First code output:
Owner:
=== Second code output:
Owner:
Actual result:
--------------
=== First code output:
Owner: d��
=== Second code output:
Segmentation Fault (core dumped)
admin@vmbox-desk:/tmp/test$ pstack core
core 'core' of 8560: php ./get_current_user.php
fffffd7fff130474 strlen () + 14
000000000065df1b zif_get_current_user () + 2b
000000000072eb91 dtrace_execute_internal () + 91
00000000007f6e21 zend_do_fcall_common_helper_SPEC () + 661
000000000077d51b execute_ex () + 4b
000000000072ea6b dtrace_execute_ex () + 13b
00000000007442b2 zend_execute_scripts () + 1d2
00000000006d03af php_execute_script () + 1ef
00000000007f92cc do_cli () + 12bc
00000000008092aa main () + 63a
00000000004d8a7c _start () + 6c
Patchesphp-5.6.6-getpwuid_r-segfault.patch (last revision 2015-02-25 21:11 UTC by dan at syneto dot net)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Nov 05 14:00:01 2025 UTC |
On Ubuntu 14.04 x64, getpwuid_r behaves the same way: returns 0 with result=NULL, but my PHP doesn't crash so it's probably using the getpwuid fallback. Compare php_get_current_user [1] with posix_getpwuid [2] which has ret = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr); if (ret || retpwptr == NULL) { POSIX_G(last_error) = ret; efree(pwbuf); RETURN_FALSE; } I certainly wouldn't call myself a C dev, but #include <sys/types.h> #include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> int main(int argc, char* argv[]) { int ret; uid_t uid; struct passwd pwd; char* buf; size_t buflen; struct passwd* result; if (argc != 2) { printf("usage: %s uid\n", argv[0]); return 0; } uid = atoi(argv[1]); printf("uid=%d\n", uid); buf = (char*)malloc(100 * sizeof(char)); buflen = 99; result = NULL; ret = getpwuid_r(uid, &pwd, buf, buflen, &result); printf("ret=%d\n", ret); printf("errno=%d\n", errno); if (ret != 0) goto end; printf("result=%p\n", result); if (result == NULL) goto end; printf("pwd=%p\n", &pwd); printf("pwd.pw_name=%s\n", pwd.pw_name); printf("pwd.pw_passwd=%s\n", pwd.pw_passwd); printf("pwd.pw_uid=%d\n", pwd.pw_uid); printf("pwd.pw_gid=%d\n", pwd.pw_gid); printf("pwd.pw_gecos=%s\n", pwd.pw_gecos); printf("pwd.pw_dir=%s\n", pwd.pw_dir); printf("pwd.pw_shell=%s\n", pwd.pw_shell); printf("buf=%s\n", buf); end: free(buf); return 0; } which produces (eg,) uid=9999 ret=0 errno=0 result=(nil) [1] https://github.com/php/php-src/blob/4629f8978e86aa20e6254e7282e6c5a4fb26796c/main/main.c#L1258 [2] https://github.com/php/php-src/blob/4629f8978e86aa20e6254e7282e6c5a4fb26796c/ext/posix/posix.c#L1157