@@ -2085,7 +2085,6 @@ static inline void security_delete_hooks(struct security_hook_list *hooks,
#define __lsm_ro_after_init __ro_after_init
#endif /* CONFIG_SECURITY_WRITABLE_HOOKS */
-extern int __init security_module_enable(const char *module);
extern void __init capability_add_hooks(void);
#ifdef CONFIG_SECURITY_YAMA
extern void __init yama_add_hooks(void);
@@ -1662,12 +1662,6 @@ static int __init apparmor_init(void)
{
int error;
- if (!apparmor_enabled || !security_module_enable("apparmor")) {
- aa_info_message("AppArmor disabled by boot time parameter");
- apparmor_enabled = false;
- return 0;
- }
-
aa_secids_init();
error = aa_setup_dfa_engine();
@@ -52,33 +52,96 @@ static __initdata bool debug;
pr_info(__VA_ARGS__); \
} while (0)
+static bool __init is_enabled(struct lsm_info *lsm)
+{
+ if (!lsm->enabled || *lsm->enabled)
+ return true;
+
+ return false;
+}
+
+/* Mark an LSM's enabled flag. */
+static int lsm_enabled_true __initdata = 1;
+static int lsm_enabled_false __initdata = 0;
+static void __init set_enabled(struct lsm_info *lsm, bool enabled)
+{
+ /*
+ * When an LSM hasn't configured an enable variable, we can use
+ * a hard-coded location for storing the default enabled state.
+ */
+ if (!lsm->enabled) {
+ if (enabled)
+ lsm->enabled = &lsm_enabled_true;
+ else
+ lsm->enabled = &lsm_enabled_false;
+ } else if (lsm->enabled == &lsm_enabled_true) {
+ if (!enabled)
+ lsm->enabled = &lsm_enabled_false;
+ } else if (lsm->enabled == &lsm_enabled_false) {
+ if (enabled)
+ lsm->enabled = &lsm_enabled_true;
+ } else {
+ *lsm->enabled = enabled;
+ }
+}
+
+/* Is an LSM allowed to be initialized? */
+static bool __init lsm_allowed(struct lsm_info *lsm)
+{
+ /* Skip if the LSM is disabled. */
+ 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_lsm) != 0)
+ return false;
+
+ return true;
+}
+
+/* Check if LSM should be initialized. */
+static void __init maybe_initialize_lsm(struct lsm_info *lsm)
+{
+ int enabled = lsm_allowed(lsm);
+
+ /* Record enablement (to handle any following exclusive LSMs). */
+ set_enabled(lsm, enabled);
+
+ /* If selected, initialize the LSM. */
+ if (enabled) {
+ int ret;
+
+ init_debug("initializing %s\n", lsm->name);
+ ret = lsm->init();
+ WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
+ }
+}
+
static void __init ordered_lsm_init(void)
{
struct lsm_info *lsm;
- int ret;
for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) != 0)
continue;
- init_debug("initializing %s\n", lsm->name);
- ret = lsm->init();
- WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
+ maybe_initialize_lsm(lsm);
}
}
static void __init major_lsm_init(void)
{
struct lsm_info *lsm;
- int ret;
for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0)
continue;
- init_debug("initializing %s\n", lsm->name);
- ret = lsm->init();
- WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
+ maybe_initialize_lsm(lsm);
}
}
@@ -168,29 +231,6 @@ static int lsm_append(char *new, char **result)
return 0;
}
-/**
- * security_module_enable - Load given security module on boot ?
- * @module: the name of the module
- *
- * Each LSM must pass this method before registering its own operations
- * to avoid security registration races. This method may also be used
- * to check if your LSM is currently loaded during kernel initialization.
- *
- * Returns:
- *
- * true if:
- *
- * - The passed LSM is the one chosen by user at boot time,
- * - or the passed LSM is configured as the default and the user did not
- * choose an alternate LSM at boot time.
- *
- * Otherwise, return false.
- */
-int __init security_module_enable(const char *module)
-{
- return !strcmp(module, chosen_lsm);
-}
-
/**
* security_add_hooks - Add a modules hooks to the hook lists.
* @hooks: the hooks to add
@@ -7138,16 +7138,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
static __init int selinux_init(void)
{
- if (!security_module_enable("selinux")) {
- selinux_enabled = 0;
- return 0;
- }
-
- if (!selinux_enabled) {
- pr_info("SELinux: Disabled at boot.\n");
- return 0;
- }
-
pr_info("SELinux: Initializing.\n");
memset(&selinux_state, 0, sizeof(selinux_state));
@@ -4841,9 +4841,6 @@ static __init int smack_init(void)
struct cred *cred;
struct task_smack *tsp;
- if (!security_module_enable("smack"))
- return 0;
-
smack_inode_cache = KMEM_CACHE(inode_smack, 0);
if (!smack_inode_cache)
return -ENOMEM;
@@ -540,8 +540,6 @@ static int __init tomoyo_init(void)
{
struct cred *cred = (struct cred *) current_cred();
- if (!security_module_enable("tomoyo"))
- 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");