summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-01-18 00:55:41 -0800
committerDavid S. Miller <davem@davemloft.net>2014-01-18 00:55:41 -0800
commit41804420586ab41049a14ab7ef04eaa2280b8647 (patch)
treef05b39b0c5f1ed229b073f7a993ef717f9f1a363 /security
parent7b1e46c5a265b142dd05ff3463fa3e0a1f4e4172 (diff)
parent7d0d46da750a252371cb747b48ddda27d1047881 (diff)
downloadop-kernel-dev-41804420586ab41049a14ab7ef04eaa2280b8647.zip
op-kernel-dev-41804420586ab41049a14ab7ef04eaa2280b8647.tar.gz
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c net/ipv4/tcp_metrics.c Overlapping changes between the "don't create two tcp metrics objects with the same key" race fix in net and the addition of the destination address in the lookup key in net-next. Minor overlapping changes in bnx2x driver. Signed-off-by: David S. Miller <davem@davemloft.net>
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 6625699..57b0b49 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -234,6 +234,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;
@@ -244,8 +252,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 b1dfe10..078e553 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 */
OpenPOWER on IntegriCloud