Skip to contentSkip to conversation

SELinux: 3/3 eliminate sbsec->sem altogether

PATCH In review Eric Paris 2 participants 2 messages Jul 27, 2006 SELinux security module

lore
Share & tools
lore

Eric Paris

author
#0 lore raw

PATCH 1/1 SELinux: 3/3 eliminate sbsec->sem altogether

This patch completely eliminates the sbsec->sem. This was held around the updating of the superblock security struct inside superblock_doinit. superblock_doinit is only called from vfs_kern_mount and from selinux_complete_init. The operation with vfs_kern_mount is protected from races because the &mnt->mnt_sb->s_umount write lock will always be held in the call to security_sb_kern_mount (which works down to superblock_doinit) so the only thing I was really concerned about was selinux_complete_init. It seems to me though that the ss_initialized variable will stop infinite recursion between the two even without locking and that we need not worry about races between vfs_kern_mount and selinux_complete_init since nothing should be able to mount while we are still processing the initial policy load in init. Please though, let me know if I am misunderstanding the race potentials of selinux_complete_init.

Likely if we ever in the future had a way to update the superblock security information after mounting this lock would need to be reintroduced, but as of today I don't see it's need.

 security/selinux/hooks.c          |    4 ----
 security/selinux/include/objsec.h |    1 -
 2 files changed, 5 deletions(-)
security/selinux/include/objsec.h renamed from security/selinux/include/objsec.h.drop.sbsec.sem +0 -1
@@ -63,7 +63,6 @@ struct superblock_security_struct {
 	unsigned int behavior;          /* labeling behavior */
 	unsigned char initialized;      /* initialization flag */
 	unsigned char proc;             /* proc fs */
-	struct semaphore sem;
 	struct list_head isec_head;
 	spinlock_t isec_lock;
 };
security/selinux/hooks.c renamed from security/selinux/hooks.c.drop.sbsec.sem +0 -4
@@ -49,7 +49,6 @@
 #include <net/ip.h>		/* for sysctl_local_port_range[] */
 #include <net/tcp.h>		/* struct or_callable used in sock_rcv_skb */
 #include <asm/uaccess.h>
-#include <asm/semaphore.h>
 #include <asm/ioctls.h>
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
@@ -240,7 +239,6 @@ static int superblock_alloc_security(str
 	if (!sbsec)
 		return -ENOMEM;
 
-	init_MUTEX(&sbsec->sem);
 	INIT_LIST_HEAD(&sbsec->list);
 	INIT_LIST_HEAD(&sbsec->isec_head);
 	spin_lock_init(&sbsec->isec_lock);
@@ -595,7 +593,6 @@ static int superblock_doinit(struct supe
 	struct inode *inode = root->d_inode;
 	int rc = 0;
 
-	down(&sbsec->sem);
 	if (sbsec->initialized)
 		goto out;
 
@@ -690,7 +687,6 @@ next_inode:
 	}
 	spin_unlock(&sbsec->isec_lock);
 out:
-	up(&sbsec->sem);
 	return rc;
 }
 

--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.

#1 lore raw
Quoted 15 lines · Eric Paris

This patch completely eliminates the sbsec->sem. This was held around the updating of the superblock security struct inside superblock_doinit. superblock_doinit is only called from vfs_kern_mount and from selinux_complete_init. The operation with vfs_kern_mount is protected from races because the &mnt->mnt_sb->s_umount write lock will always be held in the call to security_sb_kern_mount (which works down to superblock_doinit) so the only thing I was really concerned about was selinux_complete_init. It seems to me though that the ss_initialized variable will stop infinite recursion between the two even without locking and that we need not worry about races between vfs_kern_mount and selinux_complete_init since nothing should be able to mount while we are still processing the initial policy load in init. Please though, let me know if I am misunderstanding the race potentials of selinux_complete_init.

Quoted 3 lines

Likely if we ever in the future had a way to update the superblock security information after mounting this lock would need to be reintroduced, but as of today I don't see it's need.

I'm hesitant about this one, as I don't like relying on a lock in the core kernel to protect our own security structures, especially as that could change in the future.

Strictly speaking, anything could happen in userspace during selinux_complete_init; that is why it goes to such great pains to take refcounts and locks appropriately during that processing. We actually have seen issues where we get interleavings of hotplug invocation with the initial policy load and selinux_complete_init setup, which yields hotplug suddenly encountering denials as the system moves into an enforcing state without completely labeled inodes (or even with hotplug still left running in kernel_t since transitions weren't set up at the time it fired).

Quoted 52 lines
 security/selinux/hooks.c          |    4 ----
 security/selinux/include/objsec.h |    1 -
 2 files changed, 5 deletions(-)
security/selinux/include/objsec.h renamed from security/selinux/include/objsec.h.drop.sbsec.sem +0 -1
@@ -63,7 +63,6 @@ struct superblock_security_struct {
 	unsigned int behavior;          /* labeling behavior */
 	unsigned char initialized;      /* initialization flag */
 	unsigned char proc;             /* proc fs */
-	struct semaphore sem;
 	struct list_head isec_head;
 	spinlock_t isec_lock;
 };
security/selinux/hooks.c renamed from security/selinux/hooks.c.drop.sbsec.sem +0 -4
@@ -49,7 +49,6 @@
 #include <net/ip.h>		/* for sysctl_local_port_range[] */
 #include <net/tcp.h>		/* struct or_callable used in sock_rcv_skb */
 #include <asm/uaccess.h>
-#include <asm/semaphore.h>
 #include <asm/ioctls.h>
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
@@ -240,7 +239,6 @@ static int superblock_alloc_security(str
 	if (!sbsec)
 		return -ENOMEM;
 
-	init_MUTEX(&sbsec->sem);
 	INIT_LIST_HEAD(&sbsec->list);
 	INIT_LIST_HEAD(&sbsec->isec_head);
 	spin_lock_init(&sbsec->isec_lock);
@@ -595,7 +593,6 @@ static int superblock_doinit(struct supe
 	struct inode *inode = root->d_inode;
 	int rc = 0;
 
-	down(&sbsec->sem);
 	if (sbsec->initialized)
 		goto out;
 
@@ -690,7 +687,6 @@ next_inode:
 	}
 	spin_unlock(&sbsec->isec_lock);
 out:
-	up(&sbsec->sem);
 	return rc;
 }
 
Signature · 8 lines
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to [email protected] with
the words "unsubscribe selinux" without quotes as the message.