aboutsummaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-01-27 14:57:25 +0000
committerMark Brown <broonie@linaro.org>2014-01-27 14:57:25 +0000
commit51ad557e21b8713f3abc286c14bca4ed01b8e56d (patch)
tree357ddab632db8023c5b534309269b20fd50346e3 /security
parent9d069f462c65190c5116e750e7b376793cd32a15 (diff)
parent020abbc91120ddf052e2c303a8c598c3be4dc459 (diff)
downloadlinaro-lsk-51ad557e21b8713f3abc286c14bca4ed01b8e56d.tar.gz
Merge tag 'v3.10.28' into linux-linaro-lsklsk-14.01
This is the 3.10.28 stable release
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c20
-rw-r--r--security/selinux/include/objsec.h5
2 files changed, 22 insertions, 3 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 57f14185cf1..a7096e130c0 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -219,6 +219,14 @@ static int inode_alloc_security(struct inode *inode)
return 0;
}
+static void inode_free_rcu(struct rcu_head *head)
+{
+ struct inode_security_struct *isec;
+
+ isec = container_of(head, struct inode_security_struct, rcu);
+ kmem_cache_free(sel_inode_cache, isec);
+}
+
static void inode_free_security(struct inode *inode)
{
struct inode_security_struct *isec = inode->i_security;
@@ -229,8 +237,16 @@ static void inode_free_security(struct inode *inode)
list_del_init(&isec->list);
spin_unlock(&sbsec->isec_lock);
- inode->i_security = NULL;
- kmem_cache_free(sel_inode_cache, isec);
+ /*
+ * The inode may still be referenced in a path walk and
+ * a call to selinux_inode_permission() can be made
+ * after inode_free_security() is called. Ideally, the VFS
+ * wouldn't do this, but fixing that is a much harder
+ * job. For now, simply free the i_security via RCU, and
+ * leave the current inode->i_security pointer intact.
+ * The inode will be freed after the RCU grace period too.
+ */
+ call_rcu(&isec->rcu, inode_free_rcu);
}
static int file_alloc_security(struct file *file)
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index aa47bcabb5f..6fd9dd256a6 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -38,7 +38,10 @@ struct task_security_struct {
struct inode_security_struct {
struct inode *inode; /* back pointer to inode object */
- struct list_head list; /* list of inode_security_struct */
+ union {
+ struct list_head list; /* list of inode_security_struct */
+ struct rcu_head rcu; /* for freeing the inode_security_struct */
+ };
u32 task_sid; /* SID of creating task */
u32 sid; /* SID of this object */
u16 sclass; /* security class of this object */