Bug #74357 [Ver]: lchown fails to change ownership of symlink with ZTS
| From: | bukka@php.net | Date: | Sun, 30 Nov 2025 14:35:20 +0000 |
| Subject: | Bug #74357 [Ver]: lchown fails to change ownership of symlink with ZTS | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-251339@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=74357&edit=1
ID: 74357
Updated by: bukka@php.net
Reported by: msaladna at apisnetworks dot com
Summary: lchown fails to change ownership of symlink with ZTS
Status: Verified
Type: Bug
Package: Filesystem function related
Operating System: CentOS 7.3
PHP Version: 7.4.23
-Assigned To:
+Assigned To: bukka
Block user comment: N
Private report: N
New Comment:
So this is really a bug in ZTS. The reason is that virtual_chown calls:
if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH)) {
The problem is that this calls tsrm_realpath_r which resolves the simlink in
if (save && S_ISLNK(st.st_mode)) {
if (++(*ll) > LINK_MAX || (j = (size_t)php_sys_readlink(tmp, path, MAXPATHLEN)) == (size_t)-1)
{
/* too many links or broken symlinks */
free_alloca(tmp, use_heap);
return (size_t)-1;
}
path[j] = 0;
if (IS_ABSOLUTE_PATH(path, j)) {
j = tsrm_realpath_r(path, 1, j, ll, t, use_realpath, is_dir, &directory);
if (j == (size_t)-1) {
free_alloca(tmp, use_heap);
return (size_t)-1;
}
} else {
if (i + j >= MAXPATHLEN-1) {
free_alloca(tmp, use_heap);
return (size_t)-1; /* buffer overflow */
}
memmove(path+i, path, j+1);
memcpy(path, tmp, i-1);
path[i-1] = DEFAULT_SLASH;
j = tsrm_realpath_r(path, start, i + j, ll, t, use_realpath, is_dir, &directory);
if (j == (size_t)-1) {
free_alloca(tmp, use_heap);
return (size_t)-1;
}
}
if (link_is_dir) {
*link_is_dir = directory;
}
}
Currently it seems that it does not get resolved only for CWD_EXPAND but not 100% sure if it's
safe. Anyway I created https://github.com/php/php-src/pull/20626 so it
will be checked there.
Previous Comments:
------------------------------------------------------------------------
[2024-07-13 09:12:29] ewverb654 at gmail dot com
This information is really helpful for who really needs this. I hope you will many more write post
like this. (https://github.com)(https://www.mgh-patientgateway.com)
------------------------------------------------------------------------
[2021-09-10 14:40:05] cmb@php.net
I can confirm the reported behavior (PHP-7.4). It is apparently
not related to the realpath cache, since disabling the cache in
the first place doesn't make a difference.
------------------------------------------------------------------------
[2021-09-09 16:26:25] msaladna at apisnetworks dot com
Problem still persists. Sample code amended for clarity:
<?php
echo "TS: ", PHP_ZTS, " ", PHP_VERSION, "\n";
echo posix_getuid(), ":", posix_geteuid(), "\n";
is_link("foo") && unlink("foo");
symlink("/tmp", "foo");
lchown("foo", 99);
clearstatcache(true);
var_dump(lstat("foo")['uid']);
?>
This is on a CentOS 7/PHP 7.4 machine.
TS: 1 7.4.23
0:0
int(0)
And on a Rocky Linux (CentOS 8)/PHP 8 machine:
TS: 1 8.0.6
0:0
int(0)
------------------------------------------------------------------------
[2021-09-09 12:20:04] cmb@php.net
What is the output of the following script:
<?php
echo "TS: ", PHP_ZTS, "\n";
is_link("foo") && unlink("foo");
symlink("/tmp", "foo");
lchown("foo", 99);
clearstatcache(true);
var_dump(lstat("foo")['uid']);
?>
And please check with any of the actively supported PHP
versions[1]?
[1] <https://www.php.net/supported-versions.php>
------------------------------------------------------------------------
[2017-04-01 04:07:34] msaladna at apisnetworks dot com
Description:
------------
Compiling PHP with ZTS affects performance of lchown and lchgrp.
PHP CLI compiled without ZTS:
./configure --disable-all
ZTS is above + '--enable-maintainer-zts'
Test script:
---------------
<?php
echo "TS: ", PHP_ZTS, "\n";
is_link("foo") && unlink("foo");
symlink("/tmp", "foo");
lchown("foo", 99);
var_dump(lstat("foo")['uid']);
?>
Expected result:
----------------
TS: 1
int(99)
Actual result:
--------------
TS: 1
int(0)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74357&edit=1