Since we already have to do a pass through the LSMs to figure out if exclusive LSMs should be disabled after the first one is seen as enabled, this splits the logic up a bit more cleanly. Now we do a full "prepare" pass through the LSMs (which also allows for later use by the blob-sharing code), before starting the LSM initialization pass. Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx> --- security/security.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/security/security.c b/security/security.c index 4f52bd06705f..b40c4c212892 100644 --- a/security/security.c +++ b/security/security.c @@ -139,22 +139,28 @@ static bool __init lsm_allowed(struct lsm_info *lsm) return true; } -/* Check if LSM should be initialized. */ -static void __init maybe_initialize_lsm(struct lsm_info *lsm) +/* Prepare LSM for initialization. */ +static void __init prepare_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, do pre-initialization work. */ if (enabled) { - int ret; - if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) { exclusive = lsm; init_debug("exclusive chosen: %s\n", lsm->name); } + } +} + +/* Initialize a given LSM, if it is enabled. */ +static void __init initialize_lsm(struct lsm_info *lsm) +{ + if (is_enabled(lsm)) { + int ret; init_debug("initializing %s\n", lsm->name); ret = lsm->init(); @@ -230,7 +236,10 @@ static void __init ordered_lsm_init(void) ordered_lsm_parse(builtin_lsm_order, "builtin"); for (lsm = ordered_lsms; *lsm; lsm++) - maybe_initialize_lsm(*lsm); + prepare_lsm(*lsm); + + for (lsm = ordered_lsms; *lsm; lsm++) + initialize_lsm(*lsm); kfree(ordered_lsms); } -- 2.17.1