Group permissions for root not working in /tmp

8,409

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; or
  • 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 backup our hypothesis:

$ 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.

Share:
8,409

Related videos on Youtube

mxmehl
Author by

mxmehl

Updated on September 18, 2022

Comments

  • mxmehl
    mxmehl almost 2 years

    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?

  • mxmehl
    mxmehl over 5 years
    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
  • BSalita
    BSalita about 3 years
    What happened to Linus' plea "Don't break user space!".?
  • Thomas Grainger
    Thomas Grainger almost 3 years
    user space isn't broken here, if user space sets a flag that later breaks user space than that's the user space's fault not Linux's