5

I experience a strange behaviour in my /tmp directory. Although a user belong to a group has permissions to read/write a file, he cannot do so.

In this example, I create a new file /tmp/test.txt as user max. I give it the 777 permissions and make the file belong to the group root, but user root still cannot edit it.

su max
touch /tmp/test.txt
chmod 777 /tmp/test.txt

su root
chown max:root /tmp/test.txt

# ls -l /tmp/test.txt 
-rwxrwxrwx 1 max root 0 26. Feb 12:08 test.txt

# echo "foobar" > /tmp/test.txt
bash: /tmp/test.txt: Permission denied

When moving test.txt to a different directory, everything works as expected.

/tmp is a tmpfs mounted via fstab via the following options:

tmpfs       /tmp    tmpfs   nodev,nosuid,size=5G    0 0

When running ls -l /, the tmp folder looks like the following:

drwxrwxrwt  20 root root   640 26. Feb 12:01 tmp/

I am running Manjaro, an Arch Linux derivate.

Did I do something wrong with mounting tmpfs?

6

The behavior you are showing seems to depend on the fs.protected_regular Linux kernel parameter, introduced along with fs.protected_fifos by this commit (converged in version 4.19, I believe), with the aim to fix security vulnerabilities.

Excerpt of the commit message (emphasis mine):

namei: allow restricted O_CREAT of FIFOs and regular files

Disallows open of FIFOs or regular files not owned by the user in world writable sticky directories, unless the owner is the same as that of the directory or the file is opened without the O_CREAT flag. The purpose is to make data spoofing attacks harder. ...

The same commit message also reports a list of related Common Vulnerabilities and Exposures (CVE) numbers.

Thus, provided that userX is root or is otherwise granted write access to /tmp/file, and that /tmp is a world writable directory with the sticky bit set, they can open file for writing only if:

  • userX is the owner of file;
  • both file and directory /tmp are owned by the same user.

In your test, root has write permissions on /tmp/test.txt, but is not the owner of the file, nor have /tmp/test.txt and /tmp the same owner (respectively max and root).

The issue appears to be totally unrelated to the way /tmp is mounted.

The relevant documentation is in Documentation/sysctl/fs.txt:

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.

...

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.

That is, the protection described above can be disabled with the command:

sysctl fs.protected_regular=0

A bit of testing to confirm our theory:

$ su - root
# sysctl fs.protected_regular
fs.protected_regular = 1
# cd /
# mkdir test
# chmod 1777 test
# su - otheruser
$ echo hello >/test/somefile
$ exit
logout
# cat /test/somefile
hello
# ls -lah test/somefile
-rw-r--r-- 1 otheruser otheruser 6 Feb 26 17:21 test/somefile
# echo root >>test/somefile
-bash: test/somefile: Permission denied
# sysctl fs.protected_regular=0
fs.protected_regular = 0
# echo root >>test/somefile
# cat /test/somefile
hello
root
# sysctl fs.protected_regular=1
fs.protected_regular = 1
# echo root >>test/somefile
-bash: test/somefile: Permission denied
# chmod 0777 /test/
# echo root >>test/somefile
# cat test/somefile 
hello
root
root

Unlike fs.protected_hardlinks and fs.protected_symlinks, fs.protected_regular and fs.protected_fifos are not enabled by default in the kernel code.
Enabling them is a backward incompatible change (as the example you provided in this comment points out) and, as far as I can tell, systemd did it in version 241, with this recent commit.

Credits: thanks to JdeBP for pointing in the right direction with a comment to the question.

  • It works, thank you very much! It also affects Docker containers running on a system with fs.protected_regular=1. This for example causes an error when running openproject/community:8 – mxmehl Feb 27 at 8:34
  • 1
    @mxmehl Glad to hear that. I added to my answer some words on how these settings are now enabled by default. – fra-san Feb 27 at 9:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.