aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c30
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
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