]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - security/security.c
x86/pti: Unbreak EFI old_memmap
[mirror_ubuntu-artful-kernel.git] / security / security.c
index 2701ca15f94968e7ad4d22d1465456b19abb4698..cdc1627e43ef0d7a52430c2644559383ac89ca10 100644 (file)
@@ -51,7 +51,7 @@ char *lsm_names;
  */
 static struct lsm_blob_sizes blob_sizes = {
 #ifdef CONFIG_SECURITY_STACKING
-       .lbs_task = SECURITY_NAME_MAX + 2,
+       .lbs_task = SECURITY_NAME_MAX + 6,
 #endif
 };
 
@@ -62,7 +62,11 @@ static __initdata char chosen_lsms[SECURITY_CHOSEN_NAMES_MAX + 1] =
 #else
        CONFIG_DEFAULT_SECURITY;
 #endif
-static __initdata char chosen_display_lsm[SECURITY_NAME_MAX + 1];
+static __initdata char chosen_display_lsm[SECURITY_NAME_MAX + 1]
+#ifdef CONFIG_SECURITY_STACKING
+       = CONFIG_SECURITY_DEFAULT_DISPLAY_NAME
+#endif
+;
 static char default_display_lsm[SECURITY_NAME_MAX + 1];
 
 static void __init do_security_initcalls(void)
@@ -1678,6 +1682,33 @@ int security_task_kill(struct task_struct *p, struct siginfo *info,
 static char *nolsm = "-default";
 #define NOLSMLEN       9
 
+static bool is_registered_lsm(const char *str, size_t size)
+{
+       struct security_hook_list *hp;
+
+       list_for_each_entry(hp, &security_hook_heads.getprocattr, list) {
+               if (size == strlen(hp->lsm) && !strncmp(str, hp->lsm, size))
+                       return true;
+       }
+
+       return false;
+}
+
+static bool set_lsm_of_current(const char *str, size_t size)
+{
+       char *lsm = lsm_of_task(current);
+
+       if (is_registered_lsm(str, size)) {
+               strncpy(lsm, str, size);
+               lsm[size] = '\0';
+       } else if (size == NOLSMLEN && !strncmp(str, nolsm, size)) {
+               lsm[0] = '\0';
+       } else {
+               return false;
+       }
+       return true;
+}
+
 static int lsm_task_prctl(int option, unsigned long arg2, unsigned long arg3,
                                unsigned long arg4, unsigned long arg5)
 {
@@ -1685,7 +1716,6 @@ static int lsm_task_prctl(int option, unsigned long arg2, unsigned long arg3,
        char buffer[SECURITY_NAME_MAX + 1];
        __user char *optval = (__user char *)arg2;
        __user int *optlen = (__user int *)arg3;
-       struct security_hook_list *hp;
        int dlen;
        int len;
 
@@ -1712,21 +1742,12 @@ static int lsm_task_prctl(int option, unsigned long arg2, unsigned long arg3,
                        return -EFAULT;
                buffer[len] = '\0';
                /* verify the requested LSM is registered */
-               list_for_each_entry(hp, &security_hook_heads.getprocattr, list) {
-                       if (!strcmp(buffer, hp->lsm)) {
-                               strcpy(lsm, hp->lsm);
-                               goto out;
-                       }
-               }
-               if (!strncmp(buffer, nolsm, NOLSMLEN))
-                       lsm[0] = '\0';
-               else
+               if (!set_lsm_of_current(buffer, len))
                        return -ENOENT;
                break;
        default:
                return -ENOSYS;
        }
-out:
        return 0;
 }
 #endif
@@ -1950,6 +1971,11 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name,
                if (rc > 0)
                        return strlen(*value);
                return rc;
+       } else if (strcmp(name, "display_lsm") == 0) {
+               *value = kstrdup(current->security, GFP_KERNEL);
+               if (*value == NULL)
+                       return -ENOMEM;
+               return strlen(*value);
        }
 
        list_for_each_entry(hp, &security_hook_heads.getprocattr, list) {
@@ -1981,6 +2007,9 @@ int security_setprocattr(const char *lsm, const char *name, void *value,
        char *temp;
        char *cp;
 
+       if (!size)
+               return -EINVAL;
+
        /*
         * If lsm is NULL look at all the modules to find one
         * that processes name. If lsm is not NULL only look at
@@ -2052,6 +2081,12 @@ free_out:
                if (rc >= 0)
                        return size;
                return rc;
+       } else if (strcmp(name, "display_lsm") == 0) {
+#ifdef CONFIG_SECURITY_STACKING
+               if (set_lsm_of_current(value, size))
+                       return size;
+#endif
+               return -EINVAL;
        }
 
        list_for_each_entry(hp, &security_hook_heads.setprocattr, list) {