]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
UBUNTU: SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params
authorJohn Johansen <john.johansen@canonical.com>
Tue, 26 Sep 2017 15:06:30 +0000 (11:06 -0400)
committerSeth Forshee <seth.forshee@canonical.com>
Tue, 10 Apr 2018 18:06:17 +0000 (13:06 -0500)
BugLink: http://bugs.launchpad.net/bugs/1763062
The base stacking code does not provide a way for users to specify the
desired stack using the kernel boot parameters. Enable specifying an
LSM stack on the command line by providing a comma separated list

ie.
  security=apparmor,selinux

Signed-off-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
include/linux/lsm_hooks.h
security/security.c

index 8bb315d31bd56483b77d468ba1ab51be63968218..5905d88e9d28fa1e3414a01c294ba72cf8c67253 100644 (file)
@@ -1968,6 +1968,19 @@ struct security_hook_list {
        char                            *lsm;
 } __randomize_layout;
 
+/*
+ * The maximum number of major security modules.
+ * Used to avoid excessive memory management while
+ * mapping global and module specific secids.
+ *
+ * Currently SELinux, Smack, AppArmor, TOMOYO
+ * Oh, but Casey needs to come up with the right way
+ * to identify a "major" module, so use the total number
+ * of modules (including minor) for now.
+ * Minor: Capability, Yama, LoadPin
+ */
+#define        LSM_MAX_MAJOR   8
+
 /*
  * Security blob size or offset data.
  */
index 2b5f81df6a3629e83fc04e28195fc2c74dddb4e8..5e3b8aa48b7db8a91cf0f9eb98c7cb4fd9abc449 100644 (file)
@@ -36,6 +36,7 @@
 
 /* Maximum number of letters for an LSM name string */
 #define SECURITY_NAME_MAX      10
+#define SECURITY_CHOSEN_NAMES_MAX (SECURITY_NAME_MAX * LSM_MAX_MAJOR)
 #define MODULE_STACK           "(stacking)"
 
 struct security_hook_heads security_hook_heads __lsm_ro_after_init;
@@ -48,7 +49,7 @@ char *lsm_names;
 static struct lsm_blob_sizes blob_sizes;
 
 /* Boot-time LSM user choice */
-static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
+static __initdata char chosen_lsms[SECURITY_CHOSEN_NAMES_MAX + 1] =
 #ifdef CONFIG_SECURITY_STACKING
        MODULE_STACK;
 #else
@@ -131,7 +132,9 @@ int __init security_init(void)
 /* Save user chosen LSM */
 static int __init choose_lsm(char *str)
 {
-       strncpy(chosen_lsm, str, SECURITY_NAME_MAX);
+       strncpy(chosen_lsms, str, SECURITY_CHOSEN_NAMES_MAX);
+       pr_info("LSM: command line set '%s' security module(s).\n",
+               chosen_lsms);
        return 1;
 }
 __setup("security=", choose_lsm);
@@ -189,26 +192,43 @@ static int lsm_append(char *new, char **result)
  *
  * Otherwise, return false.
  */
+#ifdef CONFIG_SECURITY_STACKING
+static bool __init cmp_lsms(const char *lsm)
+{
+       const char *str = chosen_lsms;
+       const char *split;
+       int len = strlen(lsm);
+
+       if (len > SECURITY_NAME_MAX) {
+               pr_info("LSM: security module name '%s' exceeds limit\n", lsm);
+               return false;
+       }
+       for (split = strchr(str, ','); split; split = strchr(str, ',')) {
+               if ((len == split - str) && !strncmp(lsm, str, split - str))
+                       return true;
+               str = split + 1;
+       }
+       if ((len == strlen(str)) && !strncmp(lsm, str, strlen(str)))
+               return true;
+       return false;
+}
+#endif
+
 bool __init security_module_enable(const char *lsm, const bool stacked)
 {
 #ifdef CONFIG_SECURITY_STACKING
        /*
         * Module defined on the command line security=XXXX
         */
-       if (strcmp(chosen_lsm, MODULE_STACK)) {
-               if (!strcmp(lsm, chosen_lsm)) {
-                       pr_info("Command line sets the %s security module.\n",
-                               lsm);
-                       return true;
-               }
-               return false;
-       }
+       if (strcmp(chosen_lsms, MODULE_STACK))
+               return cmp_lsms(lsm);
+
        /*
         * Module configured as stacked.
         */
        return stacked;
 #else
-       if (strcmp(lsm, chosen_lsm) == 0)
+       if (strcmp(lsm, chosen_lsms) == 0)
                return true;
        return false;
 #endif