aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2014-03-19 16:46:18 -0400
committerPaul Moore <pmoore@redhat.com>2014-03-19 16:46:18 -0400
commitf64410ec665479d7b4b77b7519e814253ed0f686 (patch)
tree6aedc263f0acb291bc76e1fc5fe7139049b88097 /security
parent98883bfd9d603a2760f6d53eccfaa3ae2c053e72 (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 1dd948485e48..d5d67c93b65c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1402,15 +1402,33 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1402 isec->sid = sbsec->sid; 1402 isec->sid = sbsec->sid;
1403 1403
1404 if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) { 1404 if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
1405 if (opt_dentry) { 1405 /* We must have a dentry to determine the label on
1406 isec->sclass = inode_mode_to_security_class(inode->i_mode); 1406 * procfs inodes */
1407 rc = selinux_proc_get_sid(opt_dentry, 1407 if (opt_dentry)
1408 isec->sclass, 1408 /* Called from d_instantiate or
1409 &sid); 1409 * d_splice_alias. */
1410 if (rc) 1410 dentry = dget(opt_dentry);
1411 goto out_unlock; 1411 else
1412 isec->sid = sid; 1412 /* Called from selinux_complete_init, try to
1413 } 1413 * find a dentry. */
1414 dentry = d_find_alias(inode);
1415 /*
1416 * This can be hit on boot when a file is accessed
1417 * before the policy is loaded. When we load policy we
1418 * may find inodes that have no dentry on the
1419 * sbsec->isec_head list. No reason to complain as
1420 * these will get fixed up the next time we go through
1421 * inode_doinit() with a dentry, before these inodes
1422 * could be used again by userspace.
1423 */
1424 if (!dentry)
1425 goto out_unlock;
1426 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1427 rc = selinux_proc_get_sid(dentry, isec->sclass, &sid);
1428 dput(dentry);
1429 if (rc)
1430 goto out_unlock;
1431 isec->sid = sid;
1414 } 1432 }
1415 break; 1433 break;
1416 } 1434 }