diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-04-25 10:28:38 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-05-13 15:47:58 -0400 |
commit | b127125d9db23e4856156a7c909a3c8e18b69f99 (patch) | |
tree | 82ea9af2ccc31d709a71f4990323e0b8d98ca9aa /security/selinux/hooks.c | |
parent | 79f546a696bff2590169fb5684e23d65f4d9f591 (diff) |
fix breakage caused by d_find_alias() semantics change
"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: stable@kernel.org # f1ee616214cb "VFS: don't keep disconnected dentries on d_anon"
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4cafe6a19167..398d165f884e 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1568,8 +1568,15 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1568 | /* Called from d_instantiate or d_splice_alias. */ | 1568 | /* Called from d_instantiate or d_splice_alias. */ |
1569 | dentry = dget(opt_dentry); | 1569 | dentry = dget(opt_dentry); |
1570 | } else { | 1570 | } else { |
1571 | /* Called from selinux_complete_init, try to find a dentry. */ | 1571 | /* |
1572 | * Called from selinux_complete_init, try to find a dentry. | ||
1573 | * Some filesystems really want a connected one, so try | ||
1574 | * that first. We could split SECURITY_FS_USE_XATTR in | ||
1575 | * two, depending upon that... | ||
1576 | */ | ||
1572 | dentry = d_find_alias(inode); | 1577 | dentry = d_find_alias(inode); |
1578 | if (!dentry) | ||
1579 | dentry = d_find_any_alias(inode); | ||
1573 | } | 1580 | } |
1574 | if (!dentry) { | 1581 | if (!dentry) { |
1575 | /* | 1582 | /* |
@@ -1674,14 +1681,19 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1674 | if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) { | 1681 | if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) { |
1675 | /* We must have a dentry to determine the label on | 1682 | /* We must have a dentry to determine the label on |
1676 | * procfs inodes */ | 1683 | * procfs inodes */ |
1677 | if (opt_dentry) | 1684 | if (opt_dentry) { |
1678 | /* Called from d_instantiate or | 1685 | /* Called from d_instantiate or |
1679 | * d_splice_alias. */ | 1686 | * d_splice_alias. */ |
1680 | dentry = dget(opt_dentry); | 1687 | dentry = dget(opt_dentry); |
1681 | else | 1688 | } else { |
1682 | /* Called from selinux_complete_init, try to | 1689 | /* Called from selinux_complete_init, try to |
1683 | * find a dentry. */ | 1690 | * find a dentry. Some filesystems really want |
1691 | * a connected one, so try that first. | ||
1692 | */ | ||
1684 | dentry = d_find_alias(inode); | 1693 | dentry = d_find_alias(inode); |
1694 | if (!dentry) | ||
1695 | dentry = d_find_any_alias(inode); | ||
1696 | } | ||
1685 | /* | 1697 | /* |
1686 | * This can be hit on boot when a file is accessed | 1698 | * This can be hit on boot when a file is accessed |
1687 | * before the policy is loaded. When we load policy we | 1699 | * before the policy is loaded. When we load policy we |