[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1429630329-21748-144-git-send-email-luis.henriques@canonical.com>
Date: Tue, 21 Apr 2015 16:32:08 +0100
From: Luis Henriques <luis.henriques@...onical.com>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org,
kernel-team@...ts.ubuntu.com
Cc: Andrew Elble <aweits@....edu>, Al Viro <viro@...iv.linux.org.uk>,
"J. Bruce Fields" <bfields@...ldses.org>,
Luis Henriques <luis.henriques@...onical.com>
Subject: [PATCH 3.16.y-ckt 143/144] NFS: fix BUG() crash in notify_change() with patch to chown_common()
3.16.7-ckt10 -stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Elble <aweits@....edu>
commit c1b8940b42bb6487b10f2267a96b486276ce9ff7 upstream.
We have observed a BUG() crash in fs/attr.c:notify_change(). The crash
occurs during an rsync into a filesystem that is exported via NFS.
1.) fs/attr.c:notify_change() modifies the caller's version of attr.
2.) 6de0ec00ba8d ("VFS: make notify_change pass ATTR_KILL_S*ID to
setattr operations") introduced a BUG() restriction such that "no
function will ever call notify_change() with both ATTR_MODE and
ATTR_KILL_S*ID set". Under some circumstances though, it will have
assisted in setting the caller's version of attr to this very
combination.
3.) 27ac0ffeac80 ("locks: break delegations on any attribute
modification") introduced code to handle breaking
delegations. This can result in notify_change() being re-called. attr
_must_ be explicitly reset to avoid triggering the BUG() established
in #2.
4.) The path that that triggers this is via fs/open.c:chmod_common().
The combination of attr flags set here and in the first call to
notify_change() along with a later failed break_deleg_wait()
results in notify_change() being called again via retry_deleg
without resetting attr.
Solution is to move retry_deleg in chmod_common() a bit further up to
ensure attr is completely reset.
There are other places where this seemingly could occur, such as
fs/utimes.c:utimes_common(), but the attr flags are not initially
set in such a way to trigger this.
Fixes: 27ac0ffeac80 ("locks: break delegations on any attribute modification")
Reported-by: Eric Meddaugh <etmsys@....edu>
Tested-by: Eric Meddaugh <etmsys@....edu>
Signed-off-by: Andrew Elble <aweits@....edu>
Signed-off-by: Al Viro <viro@...iv.linux.org.uk>
Cc: J. Bruce Fields <bfields@...ldses.org>
Signed-off-by: Luis Henriques <luis.henriques@...onical.com>
---
fs/open.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/open.c b/fs/open.c
index d6fd3acde134..50f5144f31ab 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -558,6 +558,7 @@ static int chown_common(struct path *path, uid_t user, gid_t group)
uid = make_kuid(current_user_ns(), user);
gid = make_kgid(current_user_ns(), group);
+retry_deleg:
newattrs.ia_valid = ATTR_CTIME;
if (user != (uid_t) -1) {
if (!uid_valid(uid))
@@ -574,7 +575,6 @@ static int chown_common(struct path *path, uid_t user, gid_t group)
if (!S_ISDIR(inode->i_mode))
newattrs.ia_valid |=
ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
-retry_deleg:
mutex_lock(&inode->i_mutex);
error = security_path_chown(path, uid, gid);
if (!error)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists