LSM: Refactor "security=" in terms of enable/disable
authorKees Cook <keescook@chromium.org>
Wed, 19 Sep 2018 20:32:15 +0000 (13:32 -0700)
committerKees Cook <keescook@chromium.org>
Tue, 8 Jan 2019 21:18:43 +0000 (13:18 -0800)
For what are marked as the Legacy Major LSMs, make them effectively
exclusive when selected on the "security=" boot parameter, to handle
the future case of when a previously major LSMs become non-exclusive
(e.g. when TOMOYO starts blob-sharing).

Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
security/security.c

index 1e1f34285e967151d46577f1ef13c0b2f5cde22b..88de6b0732461d522274a39909424c79b5bb37f1 100644 (file)
@@ -129,14 +129,6 @@ static bool __init lsm_allowed(struct lsm_info *lsm)
        if (!is_enabled(lsm))
                return false;
 
-       /* Skip major-specific checks if not a major LSM. */
-       if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0)
-               return true;
-
-       /* Disabled if this LSM isn't the chosen one. */
-       if (strcmp(lsm->name, chosen_major_lsm) != 0)
-               return false;
-
        return true;
 }
 
@@ -164,8 +156,28 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
        struct lsm_info *lsm;
        char *sep, *name, *next;
 
+       /* Process "security=", if given. */
        if (!chosen_major_lsm)
                chosen_major_lsm = CONFIG_DEFAULT_SECURITY;
+       if (chosen_major_lsm) {
+               struct lsm_info *major;
+
+               /*
+                * To match the original "security=" behavior, this
+                * explicitly does NOT fallback to another Legacy Major
+                * if the selected one was separately disabled: disable
+                * all non-matching Legacy Major LSMs.
+                */
+               for (major = __start_lsm_info; major < __end_lsm_info;
+                    major++) {
+                       if ((major->flags & LSM_FLAG_LEGACY_MAJOR) &&
+                           strcmp(major->name, chosen_major_lsm) != 0) {
+                               set_enabled(major, false);
+                               init_debug("security=%s disabled: %s\n",
+                                          chosen_major_lsm, major->name);
+                       }
+               }
+       }
 
        sep = kstrdup(order, GFP_KERNEL);
        next = sep;