php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81404 rename() does not keep extended file attributes
Submitted: 2021-08-31 17:05 UTC Modified: 2021-09-06 08:58 UTC
From: rdueck at mcmillan-mcgee dot com Assigned:
Status: Open Package: Filesystem function related
PHP Version: 7.4.23 OS: Debian 10, Linux 4.19.0-17-amd64
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2021-08-31 17:05 UTC] rdueck at mcmillan-mcgee dot com
Description:
------------
When running from Apache2 using apache-mod-php, rename() strips extended attributes.  The same code works from the command line, and the system 'mv' command works in both cases.

move_uploaded_file() has the same problem as rename().

Test script:
---------------
<?php
// Requires xattr:
//   pecl install xattr
// then add 'extension=xattr.so' to php.ini
// ASSUME: current directory is not /tmp
$a = tempnam('/tmp','my');
$b = basename($a);
for ($i=0; $i<2; $i++) {
  file_put_contents($a,'TestData');
  xattr_set($a,'owner','me');
  switch($i){
    case 0: rename($a,$b); $fn='rename'; break;
    case 1: `mv $a $b`; $fn='mv'; break;
  }
  $owner = xattr_get($b,'owner');
  echo "$fn ".($owner=='me'?'SUCCEEDED':'FAILED')."\n";
}

Expected result:
----------------
rename SUCCEEDED
mv SUCCEEDED

Actual result:
--------------
rename FAILED
mv SUCCEEDED

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-08-31 17:17 UTC] cmb@php.net
For files, PHP's rename tries to rename(2), but if that fails for
whatever reason, it actually copies the file, and removes the
original.  The latter would indeed ignore extended file attributes.
I'm not sure though, whether this is the reason in your case.
 [2021-08-31 17:40 UTC] rdueck at mcmillan-mcgee dot com
-PHP Version: 8.0.10 +PHP Version: 7.4.23
 [2021-08-31 17:40 UTC] rdueck at mcmillan-mcgee dot com
I tried the test script from the command-line as the www-data user, and rename() still works correctly.

I've also corrected the PHP version; I have not tested PHP 8.0.
 [2021-08-31 20:00 UTC] rdueck at mcmillan-mcgee dot com
I added an inode check and confirmed that both rename() and 'mv' are being performed as copy-and-delete when run from apache. 'mv' preserves extended attributes when copying, but rename() does not.

Test script:

<?php
// Requires xattr:
//   pecl install xattr
// then add 'extension=xattr.so' to php.ini
// ASSUME: current directory is not /tmp
$a = tempnam('/tmp','my');
$b = basename($a);
for ($i=0; $i<2; $i++) {
  file_put_contents($a,'TestData');
  $inode_a = stat($a)['ino'];
  xattr_set($a,'owner','me');
  switch($i){
    case 0: rename($a,$b); $fn='rename'; break;
    case 1: `mv $a $b`; $fn='mv'; break;
  }
  $inode_b = stat($b)['ino'];
  $owner = xattr_get($b,'owner');
  echo "$fn ".($owner=='me'?'SUCCEEDED':'FAILED').", internal operation: ".($inode_a==$inode_b?'move':'copy')."\n";
}
 [2021-09-01 09:33 UTC] cmb@php.net
-Type: Bug +Type: Feature/Change Request -Package: *General Issues +Package: Filesystem function related
 [2021-09-01 09:33 UTC] cmb@php.net
> I added an inode check and confirmed that both rename() and 'mv'
> are being performed as copy-and-delete when run from apache.

Thanks for checking.  In this case this is more like a feature
request to me (and something that should be documented).
 [2021-09-01 14:50 UTC] rdueck at mcmillan-mcgee dot com
I disagree with it being a feature request.  If rename() switches to copy internally, it must still produce the same result.  If it fails to produce exactly the same result, it should be reported as an error, such as, "PHP Warning: extended attributes not moved".  Documentation would certainly help, for example, "Extended attributes may or may not stay with the new file", but unambiguous behaviour would be better.  I think it is most reasonable to expect that rename() and the system 'mv' command would behave the same.
 [2021-09-01 20:22 UTC] cmb@php.net
Okay, switching back to bug than.  However, this will be hard to
implement for all possible information (e.g. NTFS streams come to
mind), and might not be possible in a fully backwards compatible
way.
 [2021-09-06 08:58 UTC] cmb@php.net
-Type: Feature/Change Request +Type: Bug
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Wed Oct 20 18:03:38 2021 UTC