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
 [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

Pull Requests

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
 [2022-12-14 05:19 UTC] fariba dot shami326 at gmail dot com
That's great. I was impressed by your writing. I am happy to see such a topic. Please come to my blog and read it.


(https://www.mykplan.me/)php.net
 [2022-12-29 11:12 UTC] janettabloomquist at gmail dot com
Preserving extended attributes​​ mv silently discards extended attributes when the target file system does not support them. When you rename a file, only the first part of the name of the file is selected, not the file extension (the part after the last .).  (https://www.skywardalpine.net/)github.com
 [2023-06-12 17:22 UTC] kmfusa dot one at gmail dot com
Thanks for the information, I will try to figure it out for more. Keep sharing such informative post keep suggesting such post.


(https://www.kmfusa.one/)php.net
 [2024-04-29 08:42 UTC] mykplan dot life at gmail dot com
It helped me on a current project, thank you!

(https://github.com/php/php-src/blob/php-8.1.0/NEWS)(https://www.mykplan.life/)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 07 04:01:29 2024 UTC