]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - security/security.c
UBUNTU: SAUCE: LSM stacking: LSM: Manage task security blobs
[mirror_ubuntu-bionic-kernel.git] / security / security.c
index 5ffbb87938a6a1ab0be6eeb8647cf759294870d4..a26884a6001aadd74804ee0329ffaa736d6ea60b 100644 (file)
@@ -102,6 +102,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: task blob size       = %d\n", blob_sizes.lbs_task);
 #endif
 
        return 0;
@@ -277,6 +278,7 @@ 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);
+       lsm_set_size(&needed->lbs_task, &blob_sizes.lbs_task);
 }
 
 /**
@@ -300,6 +302,27 @@ int lsm_file_alloc(struct file *file)
        return 0;
 }
 
+/**
+ * lsm_task_alloc - allocate a composite task blob
+ * @task: the task that needs a blob
+ *
+ * Allocate the task blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+int lsm_task_alloc(struct task_struct *task)
+{
+       if (blob_sizes.lbs_task == 0) {
+               task->security = NULL;
+               return 0;
+       }
+
+       task->security = kzalloc(blob_sizes.lbs_task, GFP_KERNEL);
+       if (task->security == NULL)
+               return -ENOMEM;
+       return 0;
+}
+
 /*
  * Hook list operation macros.
  *
@@ -1116,12 +1139,22 @@ int security_file_open(struct file *file, const struct cred *cred)
 
 int security_task_alloc(struct task_struct *task, unsigned long clone_flags)
 {
-       return call_int_hook(task_alloc, 0, task, clone_flags);
+       int rc = lsm_task_alloc(task);
+
+       if (rc)
+               return rc;
+       rc = call_int_hook(task_alloc, 0, task, clone_flags);
+       if (unlikely(rc))
+               security_task_free(task);
+       return rc;
 }
 
 void security_task_free(struct task_struct *task)
 {
        call_void_hook(task_free, task);
+
+       kfree(task->security);
+       task->security = NULL;
 }
 
 int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)