aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2014-03-05 15:54:57 -0500
committerPaul Moore <pmoore@redhat.com>2014-03-05 15:54:57 -0500
commiteee3094683fbc7fe6bcdaef58c1ef31f8460cdca (patch)
tree6aad3c095b75c9a714a109b7dbf743660b7f3ff3 /security
parent0909c0ae999c325b9d34c6f4710f40730ae3bc24 (diff)
selinux: correctly label /proc inodes in use before the policy is loaded
This patch is based on an earlier patch by Eric Paris, he describes the problem below: "If an inode is accessed before policy load it will get placed on a list of inodes to be initialized after policy load. After policy load we call inode_doinit() which calls inode_doinit_with_dentry() on all inodes accessed before policy load. In the case of inodes in procfs that means we'll end up at the bottom where it does: /* Default to the fs superblock SID. */ isec->sid = sbsec->sid; if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) { if (opt_dentry) { isec->sclass = inode_mode_to_security_class(...) rc = selinux_proc_get_sid(opt_dentry, isec->sclass, &sid); if (rc) goto out_unlock; isec->sid = sid; } } Since opt_dentry is null, we'll never call selinux_proc_get_sid() and will leave the inode labeled with the label on the superblock. I believe a fix would be to mimic the behavior of xattrs. Look for an alias of the inode. If it can't be found, just leave the inode uninitialized (and pick it up later) if it can be found, we should be able to call selinux_proc_get_sid() ..." On a system exhibiting this problem, you will notice a lot of files in /proc with the generic "proc_t" type (at least the ones that were accessed early in the boot), for example: # ls -Z /proc/sys/kernel/shmmax | awk '{ print $4 " " $5 }' system_u:object_r:proc_t:s0 /proc/sys/kernel/shmmax However, with this patch in place we see the expected result: # ls -Z /proc/sys/kernel/shmmax | awk '{ print $4 " " $5 }' system_u:object_r:sysctl_kernel_t:s0 /proc/sys/kernel/shmmax Cc: Eric Paris <eparis@redhat.com> Signed-off-by: Paul Moore <pmoore@redhat.com> Acked-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index a3230de656e4..8b1656f053f8 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1418,15 +1418,33 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1418 isec->sid = sbsec->sid; 1418 isec->sid = sbsec->sid;
1419 1419
1420 if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) { 1420 if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
1421 if (opt_dentry) { 1421 /* We must have a dentry to determine the label on
1422 isec->sclass = inode_mode_to_security_class(inode->i_mode); 1422 * procfs inodes */
1423 rc = selinux_proc_get_sid(opt_dentry, 1423 if (opt_dentry)
1424 isec->sclass, 1424 /* Called from d_instantiate or
1425 &sid); 1425 * d_splice_alias. */
1426 if (rc) 1426 dentry = dget(opt_dentry);
1427 goto out_unlock; 1427 else
1428 isec->sid = sid; 1428 /* Called from selinux_complete_init, try to
1429 } 1429 * find a dentry. */
1430 dentry = d_find_alias(inode);
1431 /*
1432 * This can be hit on boot when a file is accessed
1433 * before the policy is loaded. When we load policy we
1434 * may find inodes that have no dentry on the
1435 * sbsec->isec_head list. No reason to complain as
1436 * these will get fixed up the next time we go through
1437 * inode_doinit() with a dentry, before these inodes
1438 * could be used again by userspace.
1439 */
1440 if (!dentry)
1441 goto out_unlock;
1442 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1443 rc = selinux_proc_get_sid(dentry, isec->sclass, &sid);
1444 dput(dentry);
1445 if (rc)
1446 goto out_unlock;
1447 isec->sid = sid;
1430 } 1448 }
1431 break; 1449 break;
1432 } 1450 }