aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2006-09-26 02:32:01 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 11:48:53 -0400
commit23970741720360de9dd0a4e87fbeb1d5927aa474 (patch)
tree2dc28ddfeae751a673d43e1925fd131d6ed3e222
parent296fddf7513c155adbd3a443d12add1f62b5cddb (diff)
[PATCH] SELinux: change isec semaphore to a mutex
This patch converts the remaining isec->sem into a mutex. Very similar locking is provided as before only in the faster smaller mutex rather than a semaphore. An out_unlock path is introduced rather than the conditional unlocking found in the original code. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Acked-by: James Morris <jmorris@namei.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--security/selinux/hooks.c30
-rw-r--r--security/selinux/include/objsec.h2
-rw-r--r--security/selinux/ss/services.c4
3 files changed, 17 insertions, 19 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 14a78199ee1f..63ad57ab44fc 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -71,6 +71,7 @@
71#include <linux/audit.h> 71#include <linux/audit.h>
72#include <linux/string.h> 72#include <linux/string.h>
73#include <linux/selinux.h> 73#include <linux/selinux.h>
74#include <linux/mutex.h>
74 75
75#include "avc.h" 76#include "avc.h"
76#include "objsec.h" 77#include "objsec.h"
@@ -185,7 +186,7 @@ static int inode_alloc_security(struct inode *inode)
185 return -ENOMEM; 186 return -ENOMEM;
186 187
187 memset(isec, 0, sizeof(*isec)); 188 memset(isec, 0, sizeof(*isec));
188 init_MUTEX(&isec->sem); 189 mutex_init(&isec->lock);
189 INIT_LIST_HEAD(&isec->list); 190 INIT_LIST_HEAD(&isec->list);
190 isec->inode = inode; 191 isec->inode = inode;
191 isec->sid = SECINITSID_UNLABELED; 192 isec->sid = SECINITSID_UNLABELED;
@@ -843,15 +844,13 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
843 char *context = NULL; 844 char *context = NULL;
844 unsigned len = 0; 845 unsigned len = 0;
845 int rc = 0; 846 int rc = 0;
846 int hold_sem = 0;
847 847
848 if (isec->initialized) 848 if (isec->initialized)
849 goto out; 849 goto out;
850 850
851 down(&isec->sem); 851 mutex_lock(&isec->lock);
852 hold_sem = 1;
853 if (isec->initialized) 852 if (isec->initialized)
854 goto out; 853 goto out_unlock;
855 854
856 sbsec = inode->i_sb->s_security; 855 sbsec = inode->i_sb->s_security;
857 if (!sbsec->initialized) { 856 if (!sbsec->initialized) {
@@ -862,7 +861,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
862 if (list_empty(&isec->list)) 861 if (list_empty(&isec->list))
863 list_add(&isec->list, &sbsec->isec_head); 862 list_add(&isec->list, &sbsec->isec_head);
864 spin_unlock(&sbsec->isec_lock); 863 spin_unlock(&sbsec->isec_lock);
865 goto out; 864 goto out_unlock;
866 } 865 }
867 866
868 switch (sbsec->behavior) { 867 switch (sbsec->behavior) {
@@ -885,7 +884,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
885 printk(KERN_WARNING "%s: no dentry for dev=%s " 884 printk(KERN_WARNING "%s: no dentry for dev=%s "
886 "ino=%ld\n", __FUNCTION__, inode->i_sb->s_id, 885 "ino=%ld\n", __FUNCTION__, inode->i_sb->s_id,
887 inode->i_ino); 886 inode->i_ino);
888 goto out; 887 goto out_unlock;
889 } 888 }
890 889
891 len = INITCONTEXTLEN; 890 len = INITCONTEXTLEN;
@@ -893,7 +892,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
893 if (!context) { 892 if (!context) {
894 rc = -ENOMEM; 893 rc = -ENOMEM;
895 dput(dentry); 894 dput(dentry);
896 goto out; 895 goto out_unlock;
897 } 896 }
898 rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, 897 rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,
899 context, len); 898 context, len);
@@ -903,7 +902,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
903 NULL, 0); 902 NULL, 0);
904 if (rc < 0) { 903 if (rc < 0) {
905 dput(dentry); 904 dput(dentry);
906 goto out; 905 goto out_unlock;
907 } 906 }
908 kfree(context); 907 kfree(context);
909 len = rc; 908 len = rc;
@@ -911,7 +910,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
911 if (!context) { 910 if (!context) {
912 rc = -ENOMEM; 911 rc = -ENOMEM;
913 dput(dentry); 912 dput(dentry);
914 goto out; 913 goto out_unlock;
915 } 914 }
916 rc = inode->i_op->getxattr(dentry, 915 rc = inode->i_op->getxattr(dentry,
917 XATTR_NAME_SELINUX, 916 XATTR_NAME_SELINUX,
@@ -924,7 +923,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
924 "%d for dev=%s ino=%ld\n", __FUNCTION__, 923 "%d for dev=%s ino=%ld\n", __FUNCTION__,
925 -rc, inode->i_sb->s_id, inode->i_ino); 924 -rc, inode->i_sb->s_id, inode->i_ino);
926 kfree(context); 925 kfree(context);
927 goto out; 926 goto out_unlock;
928 } 927 }
929 /* Map ENODATA to the default file SID */ 928 /* Map ENODATA to the default file SID */
930 sid = sbsec->def_sid; 929 sid = sbsec->def_sid;
@@ -960,7 +959,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
960 isec->sclass, 959 isec->sclass,
961 &sid); 960 &sid);
962 if (rc) 961 if (rc)
963 goto out; 962 goto out_unlock;
964 isec->sid = sid; 963 isec->sid = sid;
965 break; 964 break;
966 case SECURITY_FS_USE_MNTPOINT: 965 case SECURITY_FS_USE_MNTPOINT:
@@ -978,7 +977,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
978 isec->sclass, 977 isec->sclass,
979 &sid); 978 &sid);
980 if (rc) 979 if (rc)
981 goto out; 980 goto out_unlock;
982 isec->sid = sid; 981 isec->sid = sid;
983 } 982 }
984 } 983 }
@@ -987,12 +986,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
987 986
988 isec->initialized = 1; 987 isec->initialized = 1;
989 988
989out_unlock:
990 mutex_unlock(&isec->lock);
990out: 991out:
991 if (isec->sclass == SECCLASS_FILE) 992 if (isec->sclass == SECCLASS_FILE)
992 isec->sclass = inode_mode_to_security_class(inode->i_mode); 993 isec->sclass = inode_mode_to_security_class(inode->i_mode);
993
994 if (hold_sem)
995 up(&isec->sem);
996 return rc; 994 return rc;
997} 995}
998 996
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 0a39bfd1319f..7d5a0289878b 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -44,7 +44,7 @@ struct inode_security_struct {
44 u32 sid; /* SID of this object */ 44 u32 sid; /* SID of this object */
45 u16 sclass; /* security class of this object */ 45 u16 sclass; /* security class of this object */
46 unsigned char initialized; /* initialization flag */ 46 unsigned char initialized; /* initialization flag */
47 struct semaphore sem; 47 struct mutex lock;
48 unsigned char inherit; /* inherit SID from parent entry */ 48 unsigned char inherit; /* inherit SID from parent entry */
49}; 49};
50 50
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 988079f45294..0c219a1b3243 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2578,7 +2578,7 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask)
2578 sock = SOCKET_I(inode); 2578 sock = SOCKET_I(inode);
2579 isec = inode->i_security; 2579 isec = inode->i_security;
2580 sksec = sock->sk->sk_security; 2580 sksec = sock->sk->sk_security;
2581 down(&isec->sem); 2581 mutex_lock(&isec->lock);
2582 if (unlikely(sksec->nlbl_state == NLBL_REQUIRE && 2582 if (unlikely(sksec->nlbl_state == NLBL_REQUIRE &&
2583 (mask & (MAY_WRITE | MAY_APPEND)))) { 2583 (mask & (MAY_WRITE | MAY_APPEND)))) {
2584 lock_sock(sock->sk); 2584 lock_sock(sock->sk);
@@ -2586,7 +2586,7 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask)
2586 release_sock(sock->sk); 2586 release_sock(sock->sk);
2587 } else 2587 } else
2588 rc = 0; 2588 rc = 0;
2589 up(&isec->sem); 2589 mutex_unlock(&isec->lock);
2590 2590
2591 return rc; 2591 return rc;
2592} 2592}