diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 37 |
1 files changed, 6 insertions, 31 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 | ||
148 | static 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 | ||
243 | static int inode_alloc_security(struct inode *inode) | 241 | static 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 | ||
337 | static 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 | |||
345 | static void inode_free_security(struct inode *inode) | 330 | static 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 | ||
378 | static int file_alloc_security(struct file *file) | 355 | static int file_alloc_security(struct file *file) |
@@ -6629,6 +6606,7 @@ static void selinux_bpf_prog_free(struct bpf_prog_aux *aux) | |||
6629 | struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = { | 6606 | struct 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 | ||
6634 | static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | 6612 | static 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(); |