aboutsummaryrefslogtreecommitdiff
path: root/security/smack/smack_lsm.c
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2018-11-12 09:30:56 -0800
committerKees Cook <keescook@chromium.org>2019-01-08 13:18:44 -0800
commitbbd3662a834813730912a58efb44dd6df6d952e6 (patch)
treef4c0252814e717185845bde03fe88d341d5967b5 /security/smack/smack_lsm.c
parent43fc460907dc56a3450654efc6ba1dfbcd4594eb (diff)
downloadlinux-bbd3662a834813730912a58efb44dd6df6d952e6.tar.gz
Infrastructure management of the cred security blob
Move management of the cred security blob out of the security modules and into the security infrastructre. Instead of allocating and freeing space the security modules tell the infrastructure how much space they require. 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/smack/smack_lsm.c')
-rw-r--r--security/smack/smack_lsm.c79
1 files changed, 25 insertions, 54 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 9a050ca17296..bad27a8e1631 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -326,29 +326,20 @@ static struct inode_smack *new_inode_smack(struct smack_known *skp)
}
/**
- * new_task_smack - allocate a task security blob
+ * init_task_smack - initialize a task security blob
+ * @tsp: blob to initialize
* @task: a pointer to the Smack label for the running task
* @forked: a pointer to the Smack label for the forked task
- * @gfp: type of the memory for the allocation
*
- * Returns the new blob or NULL if there's no memory available
*/
-static struct task_smack *new_task_smack(struct smack_known *task,
- struct smack_known *forked, gfp_t gfp)
+static void init_task_smack(struct task_smack *tsp, struct smack_known *task,
+ struct smack_known *forked)
{
- struct task_smack *tsp;
-
- tsp = kzalloc(sizeof(struct task_smack), gfp);
- if (tsp == NULL)
- return NULL;
-
tsp->smk_task = task;
tsp->smk_forked = forked;
INIT_LIST_HEAD(&tsp->smk_rules);
INIT_LIST_HEAD(&tsp->smk_relabel);
mutex_init(&tsp->smk_rules_lock);
-
- return tsp;
}
/**
@@ -1881,14 +1872,7 @@ static int smack_file_open(struct file *file)
*/
static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
{
- struct task_smack *tsp;
-
- tsp = new_task_smack(NULL, NULL, gfp);
- if (tsp == NULL)
- return -ENOMEM;
-
- cred->security = tsp;
-
+ init_task_smack(smack_cred(cred), NULL, NULL);
return 0;
}
@@ -1905,10 +1889,6 @@ static void smack_cred_free(struct cred *cred)
struct list_head *l;
struct list_head *n;
- if (tsp == NULL)
- return;
- cred->security = NULL;
-
smk_destroy_label_list(&tsp->smk_relabel);
list_for_each_safe(l, n, &tsp->smk_rules) {
@@ -1916,7 +1896,6 @@ static void smack_cred_free(struct cred *cred)
list_del(&rp->list);
kfree(rp);
}
- kfree(tsp);
}
/**
@@ -1931,14 +1910,10 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old,
gfp_t gfp)
{
struct task_smack *old_tsp = smack_cred(old);
- struct task_smack *new_tsp;
+ struct task_smack *new_tsp = smack_cred(new);
int rc;
- new_tsp = new_task_smack(old_tsp->smk_task, old_tsp->smk_task, gfp);
- if (new_tsp == NULL)
- return -ENOMEM;
-
- new->security = new_tsp;
+ init_task_smack(new_tsp, old_tsp->smk_task, old_tsp->smk_task);
rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp);
if (rc != 0)
@@ -1946,10 +1921,7 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old,
rc = smk_copy_relabel(&new_tsp->smk_relabel, &old_tsp->smk_relabel,
gfp);
- if (rc != 0)
- return rc;
-
- return 0;
+ return rc;
}
/**
@@ -4581,6 +4553,10 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode,
return 0;
}
+struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = {
+ .lbs_cred = sizeof(struct task_smack),
+};
+
static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
@@ -4758,20 +4734,25 @@ static __init void init_smack_known_list(void)
*/
static __init int smack_init(void)
{
- struct cred *cred;
+ struct cred *cred = (struct cred *) current->cred;
struct task_smack *tsp;
smack_inode_cache = KMEM_CACHE(inode_smack, 0);
if (!smack_inode_cache)
return -ENOMEM;
- tsp = new_task_smack(&smack_known_floor, &smack_known_floor,
- GFP_KERNEL);
- if (tsp == NULL) {
- kmem_cache_destroy(smack_inode_cache);
- return -ENOMEM;
- }
+ lsm_early_cred(cred);
+ /*
+ * Set the security state for the initial task.
+ */
+ tsp = smack_cred(cred);
+ init_task_smack(tsp, &smack_known_floor, &smack_known_floor);
+
+ /*
+ * Register with LSM
+ */
+ security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack");
smack_enabled = 1;
pr_info("Smack: Initializing.\n");
@@ -4785,20 +4766,9 @@ static __init int smack_init(void)
pr_info("Smack: IPv6 Netfilter enabled.\n");
#endif
- /*
- * Set the security state for the initial task.
- */
- cred = (struct cred *) current->cred;
- cred->security = tsp;
-
/* initialize the smack_known_list */
init_smack_known_list();
- /*
- * Register with LSM
- */
- security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack");
-
return 0;
}
@@ -4809,5 +4779,6 @@ static __init int smack_init(void)
DEFINE_LSM(smack) = {
.name = "smack",
.flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
+ .blobs = &smack_blob_sizes,
.init = smack_init,
};