]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - security/tomoyo/tomoyo.c
security: smack: Fix possible null-pointer dereferences in smack_socket_sock_rcv_skb()
[mirror_ubuntu-bionic-kernel.git] / security / tomoyo / tomoyo.c
index 213b8c593668f260a44e9a6993c42f7a68eb4575..eb4b886b6076005f3c7a6d5fcdaa06a1f2d57555 100644 (file)
@@ -18,7 +18,9 @@
  */
 static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
 {
-       new->security = NULL;
+       struct tomoyo_domain_info **blob = tomoyo_cred(new);
+
+       *blob = NULL;
        return 0;
 }
 
@@ -34,8 +36,13 @@ static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
 static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
                               gfp_t gfp)
 {
-       struct tomoyo_domain_info *domain = old->security;
-       new->security = domain;
+       struct tomoyo_domain_info **old_blob = tomoyo_cred(old);
+       struct tomoyo_domain_info **new_blob = tomoyo_cred(new);
+       struct tomoyo_domain_info *domain;
+
+       domain = *old_blob;
+       *new_blob = domain;
+
        if (domain)
                atomic_inc(&domain->users);
        return 0;
@@ -59,7 +66,9 @@ static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
  */
 static void tomoyo_cred_free(struct cred *cred)
 {
-       struct tomoyo_domain_info *domain = cred->security;
+       struct tomoyo_domain_info **blob = tomoyo_cred(cred);
+       struct tomoyo_domain_info *domain = *blob;
+
        if (domain)
                atomic_dec(&domain->users);
 }
@@ -73,6 +82,9 @@ static void tomoyo_cred_free(struct cred *cred)
  */
 static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
 {
+       struct tomoyo_domain_info **blob;
+       struct tomoyo_domain_info *domain;
+
        /*
         * Do only if this function is called for the first time of an execve
         * operation.
@@ -93,13 +105,14 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
         * stored inside "bprm->cred->security" will be acquired later inside
         * tomoyo_find_next_domain().
         */
-       atomic_dec(&((struct tomoyo_domain_info *)
-                    bprm->cred->security)->users);
+       blob = tomoyo_cred(bprm->cred);
+       domain = *blob;
+       atomic_dec(&domain->users);
        /*
         * Tell tomoyo_bprm_check_security() is called for the first time of an
         * execve operation.
         */
-       bprm->cred->security = NULL;
+       *blob = NULL;
        return 0;
 }
 
@@ -112,8 +125,11 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
  */
 static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
 {
-       struct tomoyo_domain_info *domain = bprm->cred->security;
+       struct tomoyo_domain_info **blob;
+       struct tomoyo_domain_info *domain;
 
+       blob = tomoyo_cred(bprm->cred);
+       domain = *blob;
        /*
         * Execute permission is checked against pathname passed to do_execve()
         * using current domain.
@@ -493,6 +509,10 @@ static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg,
        return tomoyo_socket_sendmsg_permission(sock, msg, size);
 }
 
+struct lsm_blob_sizes tomoyo_blob_sizes = {
+       .lbs_cred = sizeof(struct tomoyo_domain_info *),
+};
+
 /*
  * tomoyo_security_ops is a "struct security_operations" which is used for
  * registering TOMOYO.
@@ -531,6 +551,8 @@ static struct security_hook_list tomoyo_hooks[] __lsm_ro_after_init = {
 /* Lock for GC. */
 DEFINE_SRCU(tomoyo_ss);
 
+bool tomoyo_enabled;
+
 /**
  * tomoyo_init - Register TOMOYO Linux as a LSM module.
  *
@@ -538,14 +560,29 @@ DEFINE_SRCU(tomoyo_ss);
  */
 static int __init tomoyo_init(void)
 {
+       static int finish;
        struct cred *cred = (struct cred *) current_cred();
+       struct tomoyo_domain_info **blob;
+
+       if (!security_module_enable("tomoyo",
+                               IS_ENABLED(CONFIG_SECURITY_TOMOYO_STACKED))) {
+               tomoyo_enabled = false;
+               return 0;
+       }
+       tomoyo_enabled = true;
 
-       if (!security_module_enable("tomoyo"))
+       if (!finish) {
+               security_add_blobs(&tomoyo_blob_sizes);
+               finish = 1;
                return 0;
+       }
+
        /* register ourselves with the security framework */
        security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo");
        printk(KERN_INFO "TOMOYO Linux initialized\n");
-       cred->security = &tomoyo_kernel_domain;
+       lsm_early_cred(cred);
+       blob = tomoyo_cred(cred);
+       *blob = &tomoyo_kernel_domain;
        tomoyo_mm_init();
        return 0;
 }