Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to lock a file against external processes

I need to create a lock file that can not be deleted by other scripts or processes. I tried this:

    $f = fopen($pidFile, 'w');
    fwrite($f, getmypid());
    flock($f, LOCK_EX);

but any other process started from the current user can delete the $f file even if the file handle is still opened by the running script. How to solve this problem and prevent others (i.e. non-PHP processes too) from deleting the file? And the lock to be released automatically when the process exits? All similar questions ends with an RTM flock(), but none of them answer how to lock a file against external processes.

OS is Linux 2.6.32-431.el6.x86_64

like image 441
Alexander Pravdin Avatar asked Dec 21 '15 09:12

Alexander Pravdin


1 Answers

flock on Linux uses "advisory locking" by default, which means it does not prevent any other processes from manipulating that file. See the note in the PHP Manual.

flock() uses mandatory locking instead of advisory locking on Windows. Mandatory locking is also supported on Linux and System V based operating systems via the usual mechanism supported by the fcntl() system call: that is, if the file in question has the setgid permission bit set and the group execution bit cleared. On Linux, the file system will also need to be mounted with the mand option for this to work.

Also see https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt

A file is marked as a candidate for mandatory locking by setting the group-id bit in its file mode but removing the group-execute bit. This is an otherwise meaningless combination, and was chosen by the System V implementors so as not to break existing user programs.

Note that the group-id bit is usually automatically cleared by the kernel when a setgid file is written to. This is a security measure. The kernel has been modified to recognize the special case of a mandatory lock candidate and to refrain from clearing this bit. Similarly the kernel has been modified not to run mandatory lock candidates with setgid privileges.

Also mind the warning:

Not even root can override a mandatory lock, so runaway processes can wreak havoc if they lock crucial files. The way around it is to change the file permissions (remove the setgid bit) before trying to read or write to it.

like image 178
Gordon Avatar answered Sep 19 '22 01:09

Gordon