]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
Revert "fs: Allow unprivileged linkat(..., AT_EMPTY_PATH) aka flink"
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Aug 2013 16:18:05 +0000 (09:18 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Aug 2013 16:18:05 +0000 (09:18 -0700)
This reverts commit bb2314b47996491bbc5add73633905c3120b6268.

It wasn't necessarily wrong per se, but we're still busily discussing
the exact details of this all, so I'm going to revert it for now.

It's true that you can already do flink() through /proc and that flink()
isn't new.  But as Brad Spengler points out, some secure environments do
not mount proc, and flink adds a new interface that can avoid path
lookup of the source for those kinds of environments.

We may re-do this (and even mark it for stable backporting back in 3.11
and possibly earlier) once the whole discussion about the interface is done.

Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Brad Spengler <spender@grsecurity.net>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/namei.c

index 89a612e392ebb28e9a00bfa1c2c8562d8a3fb7c6..8b61d103a8a7a15b0c5e8eab070e92f940a64b88 100644 (file)
@@ -3671,11 +3671,15 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
        if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
                return -EINVAL;
        /*
-        * Using empty names is equivalent to using AT_SYMLINK_FOLLOW
-        * on /proc/self/fd/<fd>.
+        * To use null names we require CAP_DAC_READ_SEARCH
+        * This ensures that not everyone will be able to create
+        * handlink using the passed filedescriptor.
         */
-       if (flags & AT_EMPTY_PATH)
+       if (flags & AT_EMPTY_PATH) {
+               if (!capable(CAP_DAC_READ_SEARCH))
+                       return -ENOENT;
                how = LOOKUP_EMPTY;
+       }
 
        if (flags & AT_SYMLINK_FOLLOW)
                how |= LOOKUP_FOLLOW;