4.16-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Al Viro <v...@zeniv.linux.org.uk>

commit b127125d9db23e4856156a7c909a3c8e18b69f99 upstream.

"VFS: don't keep disconnected dentries on d_anon" had a non-trivial
side-effect - d_unhashed() now returns true for those dentries,
making d_find_alias() skip them altogether.  For most of its callers
that's fine - we really want a connected alias there.  However,
there is a codepath where we relied upon picking such aliases
if nothing else could be found - selinux delayed initialization
of contexts for inodes on already mounted filesystems used to
rely upon that.

Cc: sta...@kernel.org # f1ee616214cb "VFS: don't keep disconnected dentries on 
d_anon"
Signed-off-by: Al Viro <v...@zeniv.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 security/selinux/hooks.c |   20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1532,8 +1532,15 @@ static int inode_doinit_with_dentry(stru
                        /* Called from d_instantiate or d_splice_alias. */
                        dentry = dget(opt_dentry);
                } else {
-                       /* Called from selinux_complete_init, try to find a 
dentry. */
+                       /*
+                        * Called from selinux_complete_init, try to find a 
dentry.
+                        * Some filesystems really want a connected one, so try
+                        * that first.  We could split SECURITY_FS_USE_XATTR in
+                        * two, depending upon that...
+                        */
                        dentry = d_find_alias(inode);
+                       if (!dentry)
+                               dentry = d_find_any_alias(inode);
                }
                if (!dentry) {
                        /*
@@ -1636,14 +1643,19 @@ static int inode_doinit_with_dentry(stru
                if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
                        /* We must have a dentry to determine the label on
                         * procfs inodes */
-                       if (opt_dentry)
+                       if (opt_dentry) {
                                /* Called from d_instantiate or
                                 * d_splice_alias. */
                                dentry = dget(opt_dentry);
-                       else
+                       } else {
                                /* Called from selinux_complete_init, try to
-                                * find a dentry. */
+                                * find a dentry.  Some filesystems really want
+                                * a connected one, so try that first.
+                                */
                                dentry = d_find_alias(inode);
+                               if (!dentry)
+                                       dentry = d_find_any_alias(inode);
+                       }
                        /*
                         * This can be hit on boot when a file is accessed
                         * before the policy is loaded.  When we load policy we


Reply via email to