diff options
author | Eric Paris <eparis@redhat.com> | 2006-09-26 02:32:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 11:48:53 -0400 |
commit | 23970741720360de9dd0a4e87fbeb1d5927aa474 (patch) | |
tree | 2dc28ddfeae751a673d43e1925fd131d6ed3e222 /security | |
parent | 296fddf7513c155adbd3a443d12add1f62b5cddb (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>
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/hooks.c | 30 | ||||
-rw-r--r-- | security/selinux/include/objsec.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 4 |
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 | ||
989 | out_unlock: | ||
990 | mutex_unlock(&isec->lock); | ||
990 | out: | 991 | out: |
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 | } |