fs: Kill setuid and setgid when writing regardless of capabilities
Currently, if you write to a setuid or setgid file, the setuid and
setgid bits are normally cleared. There is one major bizarre
exception: if you have the global capabilithy CAP_FSETID, the bits
are not cleared.
This means that:
(sudo -u garbage) 2>setuid_file
does *not* clear the setuid bit. On the other hand, if you are
privileged but you drop privileges across a write(2) call, the bit
is cleared.
I suspect that nothing relies on this behavior. In particular,
because it checks global capabilities, anything that works in a
userns is okay with setuid and setgid being cleared even on
privileged writes.
Change the kernel to just skip the capability check entirely and
clear the bits regardless of capabilities. This can mitigate
exploits that take advantage of world-writable setgid files or
directories.
Cc: Ben Hutchings <ben@decadent.org.uk>
Cc: Kees Cook <keescook@chromium.org>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Willy Tarreau <w@1wt.eu>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: yalin wang <yalin.wang2010@gmail.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Linux FS Devel <linux-fsdevel@vger.kernel.org>
Cc: Frank Filz <ffilzlnx@mindspring.com>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
1 file changed