diff options
| -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 | } |
