diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 30 |
1 files changed, 14 insertions, 16 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 | ||