aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-04-13 21:23:14 -0400
committerJames Morris <james.l.morris@oracle.com>2014-04-13 21:23:14 -0400
commitecd740c6f2f092b90b95fa35f757973589eaaca2 (patch)
treece02b1e18c4fc5729699251460cd8be7604d8401 /security/selinux/hooks.c
parentf64410ec665479d7b4b77b7519e814253ed0f686 (diff)
parent455c6fdbd219161bd09b1165f11699d6d73de11c (diff)
Merge commit 'v3.14' into next
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index d5d67c93b65c..869c2f1e0da1 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -233,6 +233,14 @@ static int inode_alloc_security(struct inode *inode)
233 return 0; 233 return 0;
234} 234}
235 235
236static void inode_free_rcu(struct rcu_head *head)
237{
238 struct inode_security_struct *isec;
239
240 isec = container_of(head, struct inode_security_struct, rcu);
241 kmem_cache_free(sel_inode_cache, isec);
242}
243
236static void inode_free_security(struct inode *inode) 244static void inode_free_security(struct inode *inode)
237{ 245{
238 struct inode_security_struct *isec = inode->i_security; 246 struct inode_security_struct *isec = inode->i_security;
@@ -243,8 +251,16 @@ static void inode_free_security(struct inode *inode)
243 list_del_init(&isec->list); 251 list_del_init(&isec->list);
244 spin_unlock(&sbsec->isec_lock); 252 spin_unlock(&sbsec->isec_lock);
245 253
246 inode->i_security = NULL; 254 /*
247 kmem_cache_free(sel_inode_cache, isec); 255 * The inode may still be referenced in a path walk and
256 * a call to selinux_inode_permission() can be made
257 * after inode_free_security() is called. Ideally, the VFS
258 * wouldn't do this, but fixing that is a much harder
259 * job. For now, simply free the i_security via RCU, and
260 * leave the current inode->i_security pointer intact.
261 * The inode will be freed after the RCU grace period too.
262 */
263 call_rcu(&isec->rcu, inode_free_rcu);
248} 264}
249 265
250static int file_alloc_security(struct file *file) 266static int file_alloc_security(struct file *file)
@@ -652,7 +668,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
652 if (flags[i] == SBLABEL_MNT) 668 if (flags[i] == SBLABEL_MNT)
653 continue; 669 continue;
654 rc = security_context_to_sid(mount_options[i], 670 rc = security_context_to_sid(mount_options[i],
655 strlen(mount_options[i]), &sid); 671 strlen(mount_options[i]), &sid, GFP_KERNEL);
656 if (rc) { 672 if (rc) {
657 printk(KERN_WARNING "SELinux: security_context_to_sid" 673 printk(KERN_WARNING "SELinux: security_context_to_sid"
658 "(%s) failed for (dev %s, type %s) errno=%d\n", 674 "(%s) failed for (dev %s, type %s) errno=%d\n",
@@ -2491,7 +2507,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
2491 if (flags[i] == SBLABEL_MNT) 2507 if (flags[i] == SBLABEL_MNT)
2492 continue; 2508 continue;
2493 len = strlen(mount_options[i]); 2509 len = strlen(mount_options[i]);
2494 rc = security_context_to_sid(mount_options[i], len, &sid); 2510 rc = security_context_to_sid(mount_options[i], len, &sid,
2511 GFP_KERNEL);
2495 if (rc) { 2512 if (rc) {
2496 printk(KERN_WARNING "SELinux: security_context_to_sid" 2513 printk(KERN_WARNING "SELinux: security_context_to_sid"
2497 "(%s) failed for (dev %s, type %s) errno=%d\n", 2514 "(%s) failed for (dev %s, type %s) errno=%d\n",
@@ -2895,7 +2912,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2895 if (rc) 2912 if (rc)
2896 return rc; 2913 return rc;
2897 2914
2898 rc = security_context_to_sid(value, size, &newsid); 2915 rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
2899 if (rc == -EINVAL) { 2916 if (rc == -EINVAL) {
2900 if (!capable(CAP_MAC_ADMIN)) { 2917 if (!capable(CAP_MAC_ADMIN)) {
2901 struct audit_buffer *ab; 2918 struct audit_buffer *ab;
@@ -3052,7 +3069,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
3052 if (!value || !size) 3069 if (!value || !size)
3053 return -EACCES; 3070 return -EACCES;
3054 3071
3055 rc = security_context_to_sid((void *)value, size, &newsid); 3072 rc = security_context_to_sid((void *)value, size, &newsid, GFP_KERNEL);
3056 if (rc) 3073 if (rc)
3057 return rc; 3074 return rc;
3058 3075
@@ -5527,7 +5544,7 @@ static int selinux_setprocattr(struct task_struct *p,
5527 str[size-1] = 0; 5544 str[size-1] = 0;
5528 size--; 5545 size--;
5529 } 5546 }
5530 error = security_context_to_sid(value, size, &sid); 5547 error = security_context_to_sid(value, size, &sid, GFP_KERNEL);
5531 if (error == -EINVAL && !strcmp(name, "fscreate")) { 5548 if (error == -EINVAL && !strcmp(name, "fscreate")) {
5532 if (!capable(CAP_MAC_ADMIN)) { 5549 if (!capable(CAP_MAC_ADMIN)) {
5533 struct audit_buffer *ab; 5550 struct audit_buffer *ab;
@@ -5636,7 +5653,7 @@ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
5636 5653
5637static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) 5654static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
5638{ 5655{
5639 return security_context_to_sid(secdata, seclen, secid); 5656 return security_context_to_sid(secdata, seclen, secid, GFP_KERNEL);
5640} 5657}
5641 5658
5642static void selinux_release_secctx(char *secdata, u32 seclen) 5659static void selinux_release_secctx(char *secdata, u32 seclen)