linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] vfs: Tighten up linkat(..., AT_EMPTY_PATH)
@ 2013-08-21 19:14 Andy Lutomirski
       [not found] ` <CA+55aFxi-ps2f2M8xPhfbuQ0pToqupPrDsLi2+GPUK2sqdYfUw@mail.gmail.com>
  2013-08-22 18:48 ` Linus Torvalds
  0 siblings, 2 replies; 66+ messages in thread
From: Andy Lutomirski @ 2013-08-21 19:14 UTC (permalink / raw)
  To: Linus Torvalds, security
  Cc: Ingo Molnar, Willy Tarreau, linux-kernel, oleg, Al Viro,
	Linux FS Devel, spender, Andy Lutomirski

There have long been two ways to ask the kernel to create a new
hardlink to the inode represented by an fd: linkat(..., AT_EMPTY_PATH)
and AT_SYMLINK_FOLLOW on /proc/self/fd/N.  The latter has no
particular security restrictions, but the former required privilege
until:

    commit bb2314b47996491bbc5add73633905c3120b6268
    Author: Andy Lutomirski <luto@amacapital.net>
    Date:   Thu Aug 1 21:44:31 2013 -0700

        fs: Allow unprivileged linkat(..., AT_EMPTY_PATH) aka flink

Spender pointed out that there could be code that passes an fd to an
untrusted, chrooted process, and allowing that process to flink the
fd could be dangerous.  (I'm not aware of any actual known attack.)

So let's be careful for now: only allow linkat(..., AT_EMPTY_PATH)
if the target is I_LINKABLE.  I_LINKABLE is only set for inodes
created by O_TMPFILE without O_EXCL, which is an explicit request
for flinkability.

Reported-by: Brad Spengler <spender@grsecurity.net>
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---

Changes from v1: Removed an unnecessary spin_lock.

 fs/namei.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 89a612e..9802d51 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3652,6 +3652,26 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
 }
 
 /*
+ * flink is dangerous.  For now, only allow it when specifically requested
+ * or when the caller is privileged.
+ *
+ * NB: This is not currently enforced for AT_SYMLINK_FOLLOW on procfs.
+ *     Fixing that would be intrusive and could break something.
+ */
+static bool may_flink(const struct path *path)
+{
+	struct inode *inode = path->dentry->d_inode;
+
+	/*
+	 * This is racy: I_LINKABLE could be cleared between this check
+	 * and the actual link operation.  This is odd but not a security
+	 * problem: the caller could get the same effect by flinking once
+	 * and then using normal link(2) to create a second link.
+	 */
+	return (inode->i_state & I_LINKABLE) || capable(CAP_DAC_READ_SEARCH);
+}
+
+/*
  * Hardlinks are often used in delicate situations.  We avoid
  * security-related surprises by not following symlinks on the
  * newname.  --KAB
@@ -3670,10 +3690,7 @@ 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>.
-	 */
+
 	if (flags & AT_EMPTY_PATH)
 		how = LOOKUP_EMPTY;
 
@@ -3684,6 +3701,11 @@ retry:
 	if (error)
 		return error;
 
+	if ((flags & AT_EMPTY_PATH) && !may_flink(&old_path)) {
+		error = -EPERM;
+		goto out;
+	}
+
 	new_dentry = user_path_create(newdfd, newname, &new_path,
 					(how & LOOKUP_REVAL));
 	error = PTR_ERR(new_dentry);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

end of thread, other threads:[~2013-09-03 15:58 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-21 19:14 [PATCH v2] vfs: Tighten up linkat(..., AT_EMPTY_PATH) Andy Lutomirski
     [not found] ` <CA+55aFxi-ps2f2M8xPhfbuQ0pToqupPrDsLi2+GPUK2sqdYfUw@mail.gmail.com>
     [not found]   ` <CALCETrW7+LcexA6v6RQDKhni_yJAduOmiSDneCpq3v8sPDvwUQ@mail.gmail.com>
2013-08-21 20:16     ` Willy Tarreau
2013-08-22 18:48 ` Linus Torvalds
2013-08-22 18:53   ` Willy Tarreau
2013-08-22 19:05     ` Andy Lutomirski
2013-08-22 19:23       ` Linus Torvalds
2013-08-22 20:10         ` Andy Lutomirski
2013-08-22 20:15           ` Willy Tarreau
2013-08-22 20:22             ` Andy Lutomirski
2013-08-22 20:44               ` Linus Torvalds
2013-08-22 20:48                 ` Andy Lutomirski
2013-08-22 20:54                   ` Linus Torvalds
2013-08-22 20:58                     ` Andy Lutomirski
2013-08-23  1:07                     ` Al Viro
2013-08-25  3:37                       ` Al Viro
2013-08-25  7:26                         ` Andy Lutomirski
2013-08-25 14:23                           ` Al Viro
2013-08-25 17:04                             ` Andy Lutomirski
2013-08-25 19:57                         ` Linus Torvalds
2013-08-25 20:06                           ` Al Viro
2013-08-25 20:23                             ` Linus Torvalds
2013-08-26 17:37                               ` Linus Torvalds
2013-08-26 18:07                                 ` Linus Torvalds
2013-08-26 18:11                                   ` Andy Lutomirski
2013-08-27 19:16                                   ` [RFC PATCH] fs: Add user_file_or_path_at and use it for truncate Andy Lutomirski
2013-08-27 19:32                                     ` Linus Torvalds
2013-08-27 20:28                                       ` Andy Lutomirski
2013-08-28  6:16                                         ` Al Viro
2013-08-28 16:24                                           ` Linus Torvalds
2013-08-28 19:04                                           ` Andy Lutomirski
2013-08-28 19:59                                             ` Al Viro
2013-08-28 21:07                                               ` Andy Lutomirski
2013-08-27 23:08                                     ` Al Viro
2013-08-27 23:13                                       ` Andy Lutomirski
2013-08-24 18:29             ` /proc/pid/fd && anon_inode_fops Oleg Nesterov
2013-08-24 21:24               ` Willy Tarreau
2013-08-25  5:23                 ` Al Viro
2013-08-25  6:50                   ` Willy Tarreau
2013-08-25 18:51                     ` Linus Torvalds
2013-08-25 19:48                       ` Oleg Nesterov
2013-08-25 20:05                         ` Linus Torvalds
2013-08-26 15:33                           ` Oleg Nesterov
2013-08-26 16:37                             ` Oleg Nesterov
2013-08-26 17:54                               ` [PATCH] proc: make proc_fd_permission() thread-friendly Oleg Nesterov
2013-08-26 18:09                                 ` Linus Torvalds
2013-08-26 19:35                                   ` Linus Torvalds
2013-08-26 20:20                                     ` Willy Tarreau
2013-08-27 15:05                                       ` Oleg Nesterov
2013-08-27 14:39                                     ` [PATCH 0/1] proc: make /proc/self point to thread Oleg Nesterov
2013-08-27 14:40                                       ` [PATCH 1/1] " Oleg Nesterov
2013-08-27 16:39                                         ` Linus Torvalds
2013-08-27 17:49                                           ` Oleg Nesterov
2013-08-27 18:15                                             ` Linus Torvalds
2013-08-27 18:28                                               ` Oleg Nesterov
     [not found]                                     ` <CALCETrXP-mYBPRon=0NzexW1FK1Qxz2+Bwv7-WeHBQpvW7ywRg@mail.gmail.com>
2013-08-27 15:45                                       ` [PATCH] proc: make proc_fd_permission() thread-friendly Oleg Nesterov
2013-08-26 18:32                                 ` Eric W. Biederman
2013-08-26 18:46                                   ` Oleg Nesterov
2013-08-26 18:56                                     ` Oleg Nesterov
2013-08-26 19:10                                     ` Eric W. Biederman
2013-08-27 14:53                                       ` Oleg Nesterov
2013-08-25 18:32                   ` /proc/pid/fd && anon_inode_fops Linus Torvalds
2013-08-25 19:11                     ` Al Viro
2013-08-25 19:17                     ` Andy Lutomirski
2013-09-03 15:58                     ` Pavel Machek
2013-08-25 15:45                 ` Oleg Nesterov
2013-08-22 19:39       ` [PATCH v2] vfs: Tighten up linkat(..., AT_EMPTY_PATH) Willy Tarreau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).