* [PATCH 4.1.y 1/2] dcache: Handle escaped paths in prepend_path
@ 2015-10-06 15:47 Chas Williams
2015-10-06 15:47 ` [PATCH 4.1.y 2/2] vfs: Test for and handle paths that are unreachable from their mnt_root Chas Williams
2015-10-06 16:09 ` [PATCH 4.1.y 1/2] dcache: Handle escaped paths in prepend_path Josh Boyer
0 siblings, 2 replies; 4+ messages in thread
From: Chas Williams @ 2015-10-06 15:47 UTC (permalink / raw)
To: stable; +Cc: Eric W. Biederman, Al Viro, Chas Williams
From: "Eric W. Biederman" <ebiederm@xmission.com>
commit cde93be45a8a90d8c264c776fab63487b5038a65 upstream.
A rename can result in a dentry that by walking up d_parent
will never reach it's mnt_root. For lack of a better term
I call this an escaped path.
prepend_path is called by four different functions __d_path,
d_absolute_path, d_path, and getcwd.
__d_path only wants to see paths are connected to the root it passes
in. So __d_path needs prepend_path to return an error.
d_absolute_path similarly wants to see paths that are connected to
some root. Escaped paths are not connected to any mnt_root so
d_absolute_path needs prepend_path to return an error greater
than 1. So escaped paths will be treated like paths on lazily
unmounted mounts.
getcwd needs to prepend "(unreachable)" so getcwd also needs
prepend_path to return an error.
d_path is the interesting hold out. d_path just wants to print
something, and does not care about the weird cases. Which raises
the question what should be printed?
Given that <escaped_path>/<anything> should result in -ENOENT I
believe it is desirable for escaped paths to be printed as empty
paths. As there are not really any meaninful path components when
considered from the perspective of a mount tree.
So tweak prepend_path to return an empty path with an new error
code of 3 when it encounters an escaped path.
Fixes: CVE-2015-2925
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Chas Williams <3chas3@gmail.com>
---
fs/dcache.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/fs/dcache.c b/fs/dcache.c
index 5d03eb0..2e8ddc1 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2923,6 +2923,13 @@ restart:
if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
struct mount *parent = ACCESS_ONCE(mnt->mnt_parent);
+ /* Escaped? */
+ if (dentry != vfsmnt->mnt_root) {
+ bptr = *buffer;
+ blen = *buflen;
+ error = 3;
+ break;
+ }
/* Global root? */
if (mnt != parent) {
dentry = ACCESS_ONCE(mnt->mnt_mountpoint);
--
2.1.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 4.1.y 2/2] vfs: Test for and handle paths that are unreachable from their mnt_root
2015-10-06 15:47 [PATCH 4.1.y 1/2] dcache: Handle escaped paths in prepend_path Chas Williams
@ 2015-10-06 15:47 ` Chas Williams
2015-10-06 16:09 ` [PATCH 4.1.y 1/2] dcache: Handle escaped paths in prepend_path Josh Boyer
1 sibling, 0 replies; 4+ messages in thread
From: Chas Williams @ 2015-10-06 15:47 UTC (permalink / raw)
To: stable; +Cc: Eric W. Biederman, Al Viro, Chas Williams
From: "Eric W. Biederman" <ebiederm@xmission.com>
commit 397d425dc26da728396e66d392d5dcb8dac30c37 upstream.
In rare cases a directory can be renamed out from under a bind mount.
In those cases without special handling it becomes possible to walk up
the directory tree to the root dentry of the filesystem and down
from the root dentry to every other file or directory on the filesystem.
Like division by zero .. from an unconnected path can not be given
a useful semantic as there is no predicting at which path component
the code will realize it is unconnected. We certainly can not match
the current behavior as the current behavior is a security hole.
Therefore when encounting .. when following an unconnected path
return -ENOENT.
- Add a function path_connected to verify path->dentry is reachable
from path->mnt.mnt_root. AKA to validate that rename did not do
something nasty to the bind mount.
To avoid races path_connected must be called after following a path
component to it's next path component.
Fixes: CVE-2015-2925
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[slight code refactoring for older kernel]
Signed-off-by: Chas Williams <3chas3@gmail.com>
---
fs/namei.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index fe30d3b..30b2198 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1172,6 +1172,24 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
!(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT);
}
+/**
+ * path_connected - Verify that a path->dentry is below path->mnt.mnt_root
+ * @path: nameidate to verify
+ *
+ * Rename can sometimes move a file or directory outside of a bind
+ * mount, path_connected allows those cases to be detected.
+ */
+static bool path_connected(const struct path *path)
+{
+ struct vfsmount *mnt = path->mnt;
+
+ /* Only bind mounts can have disconnected paths */
+ if (mnt->mnt_root == mnt->mnt_sb->s_root)
+ return true;
+
+ return is_subdir(path->dentry, mnt->mnt_root);
+}
+
static int follow_dotdot_rcu(struct nameidata *nd)
{
struct inode *inode = nd->inode;
@@ -1194,6 +1212,8 @@ static int follow_dotdot_rcu(struct nameidata *nd)
goto failed;
nd->path.dentry = parent;
nd->seq = seq;
+ if (unlikely(!path_connected(&nd->path)))
+ return -ENOENT;
break;
}
if (!follow_up_rcu(&nd->path))
@@ -1290,7 +1310,7 @@ static void follow_mount(struct path *path)
}
}
-static void follow_dotdot(struct nameidata *nd)
+static int follow_dotdot(struct nameidata *nd)
{
if (!nd->root.mnt)
set_root(nd);
@@ -1306,6 +1326,8 @@ static void follow_dotdot(struct nameidata *nd)
/* rare case of legitimate dget_parent()... */
nd->path.dentry = dget_parent(nd->path.dentry);
dput(old);
+ if (unlikely(!path_connected(&nd->path)))
+ return -ENOENT;
break;
}
if (!follow_up(&nd->path))
@@ -1313,6 +1335,7 @@ static void follow_dotdot(struct nameidata *nd)
}
follow_mount(&nd->path);
nd->inode = nd->path.dentry->d_inode;
+ return 0;
}
/*
@@ -1541,7 +1564,7 @@ static inline int handle_dots(struct nameidata *nd, int type)
if (follow_dotdot_rcu(nd))
return -ECHILD;
} else
- follow_dotdot(nd);
+ return follow_dotdot(nd);
}
return 0;
}
--
2.1.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH 4.1.y 1/2] dcache: Handle escaped paths in prepend_path
2015-10-06 15:47 [PATCH 4.1.y 1/2] dcache: Handle escaped paths in prepend_path Chas Williams
2015-10-06 15:47 ` [PATCH 4.1.y 2/2] vfs: Test for and handle paths that are unreachable from their mnt_root Chas Williams
@ 2015-10-06 16:09 ` Josh Boyer
2015-10-06 16:21 ` Charles (Chas) Williams
1 sibling, 1 reply; 4+ messages in thread
From: Josh Boyer @ 2015-10-06 16:09 UTC (permalink / raw)
To: Chas Williams; +Cc: stable@vger.kernel.org, Eric W. Biederman, Al Viro
On Tue, Oct 6, 2015 at 11:47 AM, Chas Williams <3chas3@gmail.com> wrote:
> From: "Eric W. Biederman" <ebiederm@xmission.com>
>
> commit cde93be45a8a90d8c264c776fab63487b5038a65 upstream.
Eric already sent patches for all actively maintained stable trees for
these commits last week. Was there something additional that you
needed to do or some other reason you sent this and your other patch
out?
josh
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 4.1.y 1/2] dcache: Handle escaped paths in prepend_path
2015-10-06 16:09 ` [PATCH 4.1.y 1/2] dcache: Handle escaped paths in prepend_path Josh Boyer
@ 2015-10-06 16:21 ` Charles (Chas) Williams
0 siblings, 0 replies; 4+ messages in thread
From: Charles (Chas) Williams @ 2015-10-06 16:21 UTC (permalink / raw)
To: Josh Boyer; +Cc: stable@vger.kernel.org, Eric W. Biederman, Al Viro
On Tue, 2015-10-06 at 12:09 -0400, Josh Boyer wrote:
> On Tue, Oct 6, 2015 at 11:47 AM, Chas Williams <3chas3@gmail.com> wrote:
> > From: "Eric W. Biederman" <ebiederm@xmission.com>
> >
> > commit cde93be45a8a90d8c264c776fab63487b5038a65 upstream.
>
> Eric already sent patches for all actively maintained stable trees for
> these commits last week. Was there something additional that you
> needed to do or some other reason you sent this and your other patch
> out?
>
> josh
Sorry, I didn't see those messages. I don't have anything to add then.
Please ignore these patches.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-10-06 16:21 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-06 15:47 [PATCH 4.1.y 1/2] dcache: Handle escaped paths in prepend_path Chas Williams
2015-10-06 15:47 ` [PATCH 4.1.y 2/2] vfs: Test for and handle paths that are unreachable from their mnt_root Chas Williams
2015-10-06 16:09 ` [PATCH 4.1.y 1/2] dcache: Handle escaped paths in prepend_path Josh Boyer
2015-10-06 16:21 ` Charles (Chas) Williams
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).