[PATCH v4 14/19] LSM: Infrastructure management of the inode security
flat view
From: Kees Cook <hidden>
Date: 2018-09-22 08:47:36
Also in:
linux-fsdevel, lkml, selinux
On Fri, Sep 21, 2018 at 5:19 PM, Casey Schaufler [off-list ref] wrote:
quoted hunk ↗ jump to hunk
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> --- include/linux/lsm_hooks.h | 3 ++ security/security.c | 83 ++++++++++++++++++++++++++++++- security/selinux/hooks.c | 32 +----------- security/selinux/include/objsec.h | 5 +- security/smack/smack_lsm.c | 70 ++++---------------------- 5 files changed, 98 insertions(+), 95 deletions(-)diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 167ffbd4d0c0..416b20c3795b 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h@@ -2030,6 +2030,7 @@ struct security_hook_list { struct lsm_blob_sizes { int lbs_cred; int lbs_file; + int lbs_inode; }; /*@@ -2092,9 +2093,11 @@ static inline void loadpin_add_hooks(void) { }; #endif extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp); +extern int lsm_inode_alloc(struct inode *inode); #ifdef CONFIG_SECURITY void lsm_early_cred(struct cred *cred); +void lsm_early_inode(struct inode *inode); #endif #endif /* ! __LINUX_LSM_HOOKS_H */diff --git a/security/security.c b/security/security.c index 5430cae73cf6..a8f00fdff4d8 100644 --- a/security/security.c +++ b/security/security.c@@ -41,6 +41,7 @@ struct security_hook_heads security_hook_heads __lsm_ro_after_init; static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); static struct kmem_cache *lsm_file_cache; +static struct kmem_cache *lsm_inode_cache; char *lsm_names; static struct lsm_blob_sizes blob_sizes;@@ -101,6 +102,10 @@ int __init security_init(void) lsm_file_cache = kmem_cache_create("lsm_file_cache", blob_sizes.lbs_file, 0, SLAB_PANIC, NULL); + if (blob_sizes.lbs_inode) + lsm_inode_cache = kmem_cache_create("lsm_inode_cache", + blob_sizes.lbs_inode, 0, + SLAB_PANIC, NULL); /* * The second call to a module specific init function * adds hooks to the hook lists and does any other early@@ -111,6 +116,7 @@ int __init security_init(void) #ifdef CONFIG_SECURITY_LSM_DEBUG pr_info("LSM: cred blob size = %d\n", blob_sizes.lbs_cred); pr_info("LSM: file blob size = %d\n", blob_sizes.lbs_file); + pr_info("LSM: inode blob size = %d\n", blob_sizes.lbs_inode); #endif return 0;@@ -288,6 +294,13 @@ void __init security_add_blobs(struct lsm_blob_sizes *needed) { lsm_set_size(&needed->lbs_cred, &blob_sizes.lbs_cred); lsm_set_size(&needed->lbs_file, &blob_sizes.lbs_file); + /* + * The inode blob gets an rcu_head in addition to + * what the modules might need. + */ + if (needed->lbs_inode && blob_sizes.lbs_inode == 0) + blob_sizes.lbs_inode = sizeof(struct rcu_head); + lsm_set_size(&needed->lbs_inode, &blob_sizes.lbs_inode); } /**@@ -311,6 +324,46 @@ int lsm_file_alloc(struct file *file) return 0; } +/** + * lsm_inode_alloc - allocate a composite inode blob + * @inode: the inode that needs a blob + * + * Allocate the inode blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_inode_alloc(struct inode *inode) +{ + if (!lsm_inode_cache) { + inode->i_security = NULL; + return 0; + } + + inode->i_security = kmem_cache_zalloc(lsm_inode_cache, GFP_NOFS); + if (inode->i_security == NULL) + return -ENOMEM; + return 0; +} + +/** + * lsm_early_inode - during initialization allocate a composite inode blob + * @inode: the inode that needs a blob + * + * Allocate the inode blob for all the modules if it's not already there + */ +void lsm_early_inode(struct inode *inode) +{ + int rc; + + if (inode == NULL) + panic("%s: NULL inode.\n", __func__); + if (inode->i_security != NULL) + return; + rc = lsm_inode_alloc(inode); + if (rc) + panic("%s: Early inode alloc failed.\n", __func__); +}
I'm still advising against using panic(), but I'll leave it up to James. For everything else here: Reviewed-by: Kees Cook <redacted> -Kees -- Kees Cook Pixel Security