--- /dev/null
+From f64410ec665479d7b4b77b7519e814253ed0f686 Mon Sep 17 00:00:00 2001
+From: Paul Moore <pmoore@redhat.com>
+Date: Wed, 19 Mar 2014 16:46:18 -0400
+Subject: selinux: correctly label /proc inodes in use before the policy is loaded
+
+From: Paul Moore <pmoore@redhat.com>
+
+commit f64410ec665479d7b4b77b7519e814253ed0f686 upstream.
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/selinux/hooks.c | 36 +++++++++++++++++++++++++++---------
+ 1 file changed, 27 insertions(+), 9 deletions(-)
+
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -1329,15 +1329,33 @@ static int inode_doinit_with_dentry(stru
+ isec->sid = sbsec->sid;
+
+ if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
+- if (opt_dentry) {
+- isec->sclass = inode_mode_to_security_class(inode->i_mode);
+- rc = selinux_proc_get_sid(opt_dentry,
+- isec->sclass,
+- &sid);
+- if (rc)
+- goto out_unlock;
+- isec->sid = sid;
+- }
++ /* We must have a dentry to determine the label on
++ * procfs inodes */
++ if (opt_dentry)
++ /* Called from d_instantiate or
++ * d_splice_alias. */
++ dentry = dget(opt_dentry);
++ else
++ /* Called from selinux_complete_init, try to
++ * find a dentry. */
++ dentry = d_find_alias(inode);
++ /*
++ * This can be hit on boot when a file is accessed
++ * before the policy is loaded. When we load policy we
++ * may find inodes that have no dentry on the
++ * sbsec->isec_head list. No reason to complain as
++ * these will get fixed up the next time we go through
++ * inode_doinit() with a dentry, before these inodes
++ * could be used again by userspace.
++ */
++ if (!dentry)
++ goto out_unlock;
++ isec->sclass = inode_mode_to_security_class(inode->i_mode);
++ rc = selinux_proc_get_sid(dentry, isec->sclass, &sid);
++ dput(dentry);
++ if (rc)
++ goto out_unlock;
++ isec->sid = sid;
+ }
+ break;
+ }