All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@ZenIV.linux.org.uk>
To: Dave Jones <davej@redhat.com>,
	Linux Kernel <linux-kernel@vger.kernel.org>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: Re: BUG_ON(nd->inode->i_op->follow_link);
Date: Sun, 10 Mar 2013 23:04:43 +0000	[thread overview]
Message-ID: <20130310230442.GB21522@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20130307153052.GA18246@redhat.com>

On Thu, Mar 07, 2013 at 10:30:52AM -0500, Dave Jones wrote:

> Code: 44 24 08 48 89 43 08 48 8b 40 30 81 4b 38 00 10 00 00 48 89 43 30 48 8b 40 20 48 83 78 08 00 75 0a 48 8b 5d f0 4c 8b 65 f8 c9 c3 <0f> 0b 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 ba 10 00 
> RIP  [<ffffffff811c1414>] nd_jump_link+0x54/0x60
>  RSP <ffff880112e31c78>

Attempt to follow procfs symlink resolving in a symlink inode.  Interesting...
Oh, hell...

OK, I can easily reproduce that one: open a symlink with O_PATH|O_NOFOLLOW,
then try to open /proc/self/fd/<fd>.  Boom...

The interesting part is what to do with it; it's not enough to make that
BUG_ON() to STFU, unfortunately.  I'm not sure what's the right behaviour
here - the thing is, following a symlink depends on which directory it's
in and with procfs ones we really don't know that; don't even know if the
bugger is still linked, for that matter.

Basically, the target of symlink is a function of symlink contents *and*
the directory it's in.  Consider somebody doing O_PATH open of a symlink
(with O_NOFOLLOW).  Then unlink it.  What should following
/proc/self/fd/<that descriptor> mean?

FWIW, I'm seriously tempted to turn that BUG_ON() into return -ELOOP, rather
than attempt to invent a semantics for following those guys.  I think we'd
discussed that corner case when doing O_PATH patchset, and IIRC decided to
go with "fail with -ELOOP"; looks like that had slipped through the cracks
and never got done.  IOW, how about the following?

make nd_jump_link() fail sanely when asked to jump into a symlink

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/fs/namei.c b/fs/namei.c
index 57ae9c8..9029d60 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -682,13 +682,18 @@ static inline void path_to_nameidata(const struct path *path,
  * Helper to directly jump to a known parsed path from ->follow_link,
  * caller must have taken a reference to path beforehand.
  */
-void nd_jump_link(struct nameidata *nd, struct path *path)
+void *nd_jump_link(struct nameidata *nd, struct path *path)
 {
+	if (unlikely(path->dentry->d_inode->i_op->follow_link)) {
+		path_put(path);
+		return ERR_PTR(-ELOOP);
+	}
 	path_put(&nd->path);
 
 	nd->path = *path;
 	nd->inode = nd->path.dentry->d_inode;
 	nd->flags |= LOOKUP_JUMPED;
+	return NULL;
 }
 
 static inline void put_link(struct nameidata *nd, struct path *link, void *cookie)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 69078c7..b323ee6 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1437,8 +1437,7 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
 	if (error)
 		goto out;
 
-	nd_jump_link(nd, &path);
-	return NULL;
+	return nd_jump_link(nd, &path);
 out:
 	return ERR_PTR(error);
 }
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index 66b51c0..11c7b97 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -135,8 +135,7 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
 	}
 
 	ns_path.mnt = mntget(nd->path.mnt);
-	nd_jump_link(nd, &ns_path);
-	error = NULL;
+	error = nd_jump_link(nd, &ns_path);
 
 out_put_task:
 	put_task_struct(task);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 5a5ff57..bf55ed9 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -82,7 +82,7 @@ extern int follow_up(struct path *);
 extern struct dentry *lock_rename(struct dentry *, struct dentry *);
 extern void unlock_rename(struct dentry *, struct dentry *);
 
-extern void nd_jump_link(struct nameidata *nd, struct path *path);
+extern void *nd_jump_link(struct nameidata *nd, struct path *path);
 
 static inline void nd_set_link(struct nameidata *nd, char *path)
 {

  parent reply	other threads:[~2013-03-10 23:04 UTC|newest]

Thread overview: 99+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-07  2:16 BUG_ON(nd->inode != parent->d_inode); Dave Jones
2013-03-07 15:30 ` BUG_ON(nd->inode->i_op->follow_link); Dave Jones
2013-03-07 17:30   ` BUG_ON(nd->inode->i_op->follow_link); Linus Torvalds
2013-03-07 19:35     ` BUG_ON(nd->inode->i_op->follow_link); Dave Jones
2013-03-07 20:33       ` BUG_ON(nd->inode->i_op->follow_link); Linus Torvalds
2013-03-07 21:38         ` ipc/testmsg GPF Dave Jones
2013-03-07 21:45           ` Linus Torvalds
2013-03-07 21:49             ` David Miller
2013-03-07 21:51               ` Linus Torvalds
2013-03-07 22:03             ` Dave Jones
2013-03-07 22:36               ` pipe_release oops Dave Jones
2013-03-07 23:14                 ` fasync_remove_entry oops Dave Jones
2013-03-07 23:46                   ` Linus Torvalds
2013-03-07 23:54                     ` Dave Jones
2013-03-08  0:20                       ` Dave Jones
2013-03-08  0:21                 ` pipe_release oops Linus Torvalds
2013-03-08 14:53                   ` Dave Jones
2013-03-08 18:30                     ` Linus Torvalds
2013-03-08 18:26                       ` Jörn Engel
2013-03-10 23:33                         ` Al Viro
2013-03-12 19:09                           ` Jörn Engel
2013-03-10 22:10                       ` Al Viro
2013-03-11  0:35                         ` Al Viro
2013-03-11 15:10                           ` Linus Torvalds
2013-03-11 18:05                             ` Al Viro
2013-03-12 13:06                               ` Al Viro
2013-03-12 15:31                                 ` Linus Torvalds
2013-03-12 19:43                                   ` Al Viro
2013-03-12 19:56                                     ` Dave Jones
2013-03-12 20:09                                     ` Linus Torvalds
2013-03-12 20:51                                       ` Al Viro
2013-03-27 13:51                                       ` Yet another pipe related oops Dave Jones
2013-03-27 15:20                                         ` Al Viro
2013-03-27 16:33                                           ` Linus Torvalds
2013-03-27 16:53                                             ` Raymond Jennings
2013-03-27 17:45                                             ` Al Viro
2013-04-01 20:34                                               ` Al Viro
2013-04-01 21:00                                                 ` Greg Kroah-Hartman
2013-04-01 21:21                                                   ` Al Viro
2013-04-01 21:44                                                     ` Greg Kroah-Hartman
2013-04-01 23:27                                                       ` Al Viro
2013-04-02  0:22                                                         ` Al Viro
2013-04-02  1:55                                                           ` Greg Kroah-Hartman
2013-03-12  1:27                       ` pipe_release oops Dave Jones
2013-03-09  0:27           ` ipc/testmsg GPF Peter Hurley
2013-03-09  0:32             ` Dave Jones
2013-03-11 18:26             ` Dave Jones
2013-03-11 19:03               ` Peter Hurley
2013-03-12 22:02                 ` Andrew Morton
2013-03-12 22:33                   ` Dave Jones
2013-03-15 21:21                   ` Dave Jones
2013-03-25 16:37                 ` Dave Jones
2013-03-25 18:28                   ` Peter Hurley
2013-03-25 18:39                     ` Dave Jones
2013-03-07 22:18         ` BUG_ON(nd->inode->i_op->follow_link); Dave Jones
2013-03-07 22:50           ` BUG_ON(nd->inode->i_op->follow_link); Linus Torvalds
2013-03-07 23:03             ` BUG_ON(nd->inode->i_op->follow_link); Dave Jones
2013-03-07 23:55             ` BUG_ON(nd->inode->i_op->follow_link); Linus Torvalds
2013-03-11  0:02             ` BUG_ON(nd->inode->i_op->follow_link); Al Viro
2013-03-10 23:04   ` Al Viro [this message]
2013-03-12 18:31     ` BUG_ON(nd->inode->i_op->follow_link); Linus Torvalds
2013-03-08 15:04 ` BUG_ON(nd->inode != parent->d_inode); Dave Jones
2013-03-08 18:51   ` Linus Torvalds
2013-03-08 19:18     ` Dave Jones
2013-03-08 19:20       ` Dave Jones
2013-03-08 19:36         ` Dave Jones
2013-03-08 19:47           ` Linus Torvalds
2013-03-08 21:04             ` Dave Jones
2013-03-08 22:41               ` Linus Torvalds
2013-03-08 23:07                 ` Dave Jones
2013-03-08 23:14                   ` Dave Jones
2013-03-08 23:20                   ` Linus Torvalds
2013-03-08 23:28                     ` Linus Torvalds
2013-03-08 23:34                       ` Dave Jones
2013-03-08 23:47                       ` Dave Jones
2013-03-08 23:51                         ` Linus Torvalds
2013-03-08 23:30                     ` Dave Jones
2013-03-08 23:45                       ` Linus Torvalds
2013-03-08 23:55                         ` Dave Jones
2013-03-09  0:02                           ` Linus Torvalds
2013-03-09  0:19                             ` Dave Jones
2013-03-09  0:29                               ` Raymond Jennings
2013-03-09  0:36                               ` Dave Jones
2013-03-09  1:18                                 ` Linus Torvalds
2013-03-09  2:03                                   ` Dave Jones
2013-03-09  2:08                                     ` Linus Torvalds
2013-03-09  2:26                                       ` Dave Jones
2013-03-09  2:56                                         ` Dave Jones
2013-03-09  2:57                                           ` Dave Jones
     [not found]                                             ` <CA+55aFxyOYXnzDoWr7Utr1QLjjMUCON5EGH3FMvGBHxnxMJmQQ@mail.gmail.com>
2013-03-09  3:25                                               ` Dave Jones
2013-03-09  3:38                                                 ` Eric W. Biederman
2013-03-09  4:26                                                   ` Dave Jones
2013-03-09  8:28                                                     ` Eric W. Biederman
     [not found]                                                 ` <CA+55aFweyfew3VU79ZQV4otJcWiF0=xKXxDtADXcccNxGaqMwA@mail.gmail.com>
2013-03-09  3:50                                                   ` Dave Jones
2013-03-09  4:31                                                     ` Linus Torvalds
2013-03-09  4:39                                                       ` Dave Jones
2013-03-09  5:13                                                         ` Sasha Levin
2013-03-09  5:16                                                           ` Dave Jones
2013-03-09  3:27                                             ` Eric W. Biederman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130310230442.GB21522@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=davej@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.