Protected FIFOs and regular files

Posted by Marcus Folkesson on Monday, October 21, 2024

Protected FIFOs and regular files

Since version 4.19 [1], Linux has the default behaviour to prevents opening of regular files and FIFOs that is not owned by the user in world writable sticky directories. Example on such directory is /tmp/ which usually has the sticky bit set.

This may sound obvious, but what is not so obvious is that this restriction also applies to the root user. You can therefore end up in a situation where e.g. the root user cannot open a file owned by another user - something that normally works.

/media/protected-fifo.png

The purpose is to make data spoofing attacks harder. A similar restriction has been applied to symlinks and hardlinks since 2012 [2], but not for FIFOs and regular files.

The documentation [3] describes the features as follows

protected_fifos
---------------

The intent of this protection is to avoid unintentional writes to
an attacker-controlled FIFO, where a program expected to create a regular
file.

When set to "0", writing to FIFOs is unrestricted.

When set to "1" don't allow ``O_CREAT`` open on FIFOs that we don't own
in world writable sticky directories, unless they are owned by the
owner of the directory.

When set to "2" it also applies to group writable sticky directories.

and

protected_regular
-----------------

This protection is similar to `protected_fifos`_, but it
avoids writes to an attacker-controlled regular file, where a program
expected to create one.

When set to "0", writing to regular files is unrestricted.

When set to "1" don't allow ``O_CREAT`` open on regular files that we
don't own in world writable sticky directories, unless they are
owned by the owner of the directory.

When set to "2" it also applies to group writable sticky directories.

Turn it on and off

The protection can be turned on and off separately for FIFOs and regular files via proteced_fifos and protected_regular respectively, just like the symlink/hardlinks protection.

Either use sysctl to set the wanted value:

1$ sysctl -w fs.protected_fifos=0
2$ sysctl -w fs.protected_regular=0

Or use procfs:

1$ echo 0 > /proc/sys/fs/protected_fifos
2$ echo 0 > /proc/sys/fs/protected_regular