summaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2018-09-21 20:19:29 -0400
committerKees Cook <keescook@chromium.org>2019-01-08 16:18:45 -0500
commitafb1cbe37440c7f38b9cf46fc331cc9dfd5cce21 (patch)
tree050d1e2575f9a79e20c67634660aef927981694c /security/selinux
parentfb4021b6fb5818df1228a35b7e2645038d01bb9f (diff)
LSM: Infrastructure management of the inode security
Move management of the inode->i_security blob out of the individual security modules and into the security infrastructure. Instead of allocating the blobs from within the modules the modules tell the infrastructure how much space is required, and the space is allocated there. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Reviewed-by: Kees Cook <keescook@chromium.org> [kees: adjusted for ordered init series] Signed-off-by: Kees Cook <keescook@chromium.org>
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c37
-rw-r--r--security/selinux/include/objsec.h9
2 files changed, 10 insertions, 36 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2d691e8dfbbf..23da46cd6e37 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -145,8 +145,6 @@ static int __init checkreqprot_setup(char *str)
145} 145}
146__setup("checkreqprot=", checkreqprot_setup); 146__setup("checkreqprot=", checkreqprot_setup);
147 147
148static struct kmem_cache *sel_inode_cache;
149
150/** 148/**
151 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled 149 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
152 * 150 *
@@ -242,13 +240,9 @@ static inline u32 task_sid(const struct task_struct *task)
242 240
243static int inode_alloc_security(struct inode *inode) 241static int inode_alloc_security(struct inode *inode)
244{ 242{
245 struct inode_security_struct *isec; 243 struct inode_security_struct *isec = selinux_inode(inode);
246 u32 sid = current_sid(); 244 u32 sid = current_sid();
247 245
248 isec = kmem_cache_zalloc(sel_inode_cache, GFP_NOFS);
249 if (!isec)
250 return -ENOMEM;
251
252 spin_lock_init(&isec->lock); 246 spin_lock_init(&isec->lock);
253 INIT_LIST_HEAD(&isec->list); 247 INIT_LIST_HEAD(&isec->list);
254 isec->inode = inode; 248 isec->inode = inode;
@@ -256,7 +250,6 @@ static int inode_alloc_security(struct inode *inode)
256 isec->sclass = SECCLASS_FILE; 250 isec->sclass = SECCLASS_FILE;
257 isec->task_sid = sid; 251 isec->task_sid = sid;
258 isec->initialized = LABEL_INVALID; 252 isec->initialized = LABEL_INVALID;
259 inode->i_security = isec;
260 253
261 return 0; 254 return 0;
262} 255}
@@ -334,19 +327,14 @@ static struct inode_security_struct *backing_inode_security(struct dentry *dentr
334 return selinux_inode(inode); 327 return selinux_inode(inode);
335} 328}
336 329
337static void inode_free_rcu(struct rcu_head *head)
338{
339 struct inode_security_struct *isec;
340
341 isec = container_of(head, struct inode_security_struct, rcu);
342 kmem_cache_free(sel_inode_cache, isec);
343}
344
345static void inode_free_security(struct inode *inode) 330static void inode_free_security(struct inode *inode)
346{ 331{
347 struct inode_security_struct *isec = selinux_inode(inode); 332 struct inode_security_struct *isec = selinux_inode(inode);
348 struct superblock_security_struct *sbsec = inode->i_sb->s_security; 333 struct superblock_security_struct *sbsec;
349 334
335 if (!isec)
336 return;
337 sbsec = inode->i_sb->s_security;
350 /* 338 /*
351 * As not all inode security structures are in a list, we check for 339 * As not all inode security structures are in a list, we check for
352 * empty list outside of the lock to make sure that we won't waste 340 * empty list outside of the lock to make sure that we won't waste
@@ -362,17 +350,6 @@ static void inode_free_security(struct inode *inode)
362 list_del_init(&isec->list); 350 list_del_init(&isec->list);
363 spin_unlock(&sbsec->isec_lock); 351 spin_unlock(&sbsec->isec_lock);
364 } 352 }
365
366 /*
367 * The inode may still be referenced in a path walk and
368 * a call to selinux_inode_permission() can be made
369 * after inode_free_security() is called. Ideally, the VFS
370 * wouldn't do this, but fixing that is a much harder
371 * job. For now, simply free the i_security via RCU, and
372 * leave the current inode->i_security pointer intact.
373 * The inode will be freed after the RCU grace period too.
374 */
375 call_rcu(&isec->rcu, inode_free_rcu);
376} 353}
377 354
378static int file_alloc_security(struct file *file) 355static int file_alloc_security(struct file *file)
@@ -6629,6 +6606,7 @@ static void selinux_bpf_prog_free(struct bpf_prog_aux *aux)
6629struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = { 6606struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = {
6630 .lbs_cred = sizeof(struct task_security_struct), 6607 .lbs_cred = sizeof(struct task_security_struct),
6631 .lbs_file = sizeof(struct file_security_struct), 6608 .lbs_file = sizeof(struct file_security_struct),
6609 .lbs_inode = sizeof(struct inode_security_struct),
6632}; 6610};
6633 6611
6634static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { 6612static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
@@ -6881,9 +6859,6 @@ static __init int selinux_init(void)
6881 6859
6882 default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); 6860 default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
6883 6861
6884 sel_inode_cache = kmem_cache_create("selinux_inode_security",
6885 sizeof(struct inode_security_struct),
6886 0, SLAB_PANIC, NULL);
6887 avc_init(); 6862 avc_init();
6888 6863
6889 avtab_cache_init(); 6864 avtab_cache_init();
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 26b4ff6b4d81..562fad58c56b 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -57,10 +57,7 @@ enum label_initialized {
57 57
58struct inode_security_struct { 58struct inode_security_struct {
59 struct inode *inode; /* back pointer to inode object */ 59 struct inode *inode; /* back pointer to inode object */
60 union { 60 struct list_head list; /* list of inode_security_struct */
61 struct list_head list; /* list of inode_security_struct */
62 struct rcu_head rcu; /* for freeing the inode_security_struct */
63 };
64 u32 task_sid; /* SID of creating task */ 61 u32 task_sid; /* SID of creating task */
65 u32 sid; /* SID of this object */ 62 u32 sid; /* SID of this object */
66 u16 sclass; /* security class of this object */ 63 u16 sclass; /* security class of this object */
@@ -173,7 +170,9 @@ static inline struct file_security_struct *selinux_file(const struct file *file)
173static inline struct inode_security_struct *selinux_inode( 170static inline struct inode_security_struct *selinux_inode(
174 const struct inode *inode) 171 const struct inode *inode)
175{ 172{
176 return inode->i_security; 173 if (unlikely(!inode->i_security))
174 return NULL;
175 return inode->i_security + selinux_blob_sizes.lbs_inode;
177} 176}
178 177
179#endif /* _SELINUX_OBJSEC_H_ */ 178#endif /* _SELINUX_OBJSEC_H_ */