How to save ownership and permissions when replacing an atomic file?

So, the usual POSIX way to safely, atomically replace the contents of a file:

  • fopen(3) temporary file on the same volume
  • fwrite(3) new contents to temporary file
  • fflush(3)/ fsync(2)so that the contents are written to disk
  • fclose(3) temporary file
  • rename(2) temporary file to replace target file

However, on my Linux system (Ubuntu 16.04 LTS), one of the consequences of this process is that the ownership and permissions of the target file are changed to the ownership and permissions of the temporary file, by default - uid/ gidand current umask.

I thought I would add the code to the stat(2)target file before overwriting and fchown(2)/ the fchmod(2)temporary file before the call rename, but this may fail due to EPERM.

The only solution to ensure that the file uid/ gidfile matches the current user and the process group overwriting the file? Is there a safe way to back down in this case, or are we sure to lose the atomic guarantee?

+6
source share
3 answers

Is the only solution guaranteeing that the uid / gid of the file matches the current user and the process group overwriting the file?

No.

Linux CAP_LEASE , /proc/sys/fs/lease-break-time . , , , ( ).

, CAP_CHOWN ( ).

[ , uid gid ], ?

, ACL xattr s, , , ACL , (, , .new-################, # - ), (getuid(), getgid(), getgroups()) . CAP_CHOWN ( ). (, - , / , - . , root.)

, , mktemp, , . , , , fork()/exec() .

, : () . , , ( ) , . , . ( ACL .) , fchown(), , , fchmod(), , .

+3

, , . , , . .

. , .

  • .

    :

    : /

  • .

    , .

    : /

    : . . "" .

  • , .

    : /

    . ( , , ). .

  • daemon/, . . .

    : / . , .

    . . . . . () . .

+1
  • , , , - ?
  • , (st_nlink > 1).
  • ?
  • ACL?
  • , ?
  • ?

.

; realpath() , . .

, (), , , , , , ACL , , , - rename().

TOCTOU - , - . , , , . , . , , , . , , , .

, ACL , , - :

  • , ;
  • () , ;
  • - , 1 2, - ;
  • , ;
  • - 4, , 2;
  • - 5, ( , , ) ;
  • .

, , , , , , ACLS, . - , 3 ( size(old) + size(new) + max(size(old), size(new))). , , - - SIGKILL - ( ).

SIGKILL, , . SIGSTOP ; , .

, , .

( ), , . ? , , - -, .

answer Nominal animal mentions Linux features. Since the question is labeled POSIX and not Linux, it is unclear whether they apply to you. However, if they can be used, then it CAP_LEASEsounds useful.

  • How important is atomicity and accuracy?
  • How important is POSIX compliance and Linux (or any other specific POSIX implementation)?
+1
source

All Articles