From: Roberto Sassu <roberto.sassu@xxxxxxxxxx> The ordering of LSM_ORDER_LAST LSMs depends on how they are placed in the .lsm_info.init section of the kernel image. Without making any assumption on the LSM ordering based on how they are compiled, enforce that ordering at LSM infrastructure level. Signed-off-by: Roberto Sassu <roberto.sassu@xxxxxxxxxx> --- security/security.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/security/security.c b/security/security.c index 351a124b771c..b98db79ca500 100644 --- a/security/security.c +++ b/security/security.c @@ -263,6 +263,18 @@ static void __init initialize_lsm(struct lsm_info *lsm) } } +/* Find an LSM with a given name. */ +static struct lsm_info __init *find_lsm(const char *name) +{ + struct lsm_info *lsm; + + for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) + if (!strcmp(lsm->name, name)) + return lsm; + + return NULL; +} + /* * Current index to use while initializing the lsm id list. */ @@ -333,10 +345,23 @@ static void __init ordered_lsm_parse(const char *order, const char *origin) /* LSM_ORDER_LAST is always last. */ for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { + /* Do it later, to enforce the expected ordering. */ + if (!strcmp(lsm->name, "ima") || !strcmp(lsm->name, "evm")) + continue; + if (lsm->order == LSM_ORDER_LAST) append_ordered_lsm(lsm, " last"); } + /* Ensure that the 'ima' and 'evm' LSMs are last and in this order. */ + lsm = find_lsm("ima"); + if (lsm) + append_ordered_lsm(lsm, " last"); + + lsm = find_lsm("evm"); + if (lsm) + append_ordered_lsm(lsm, " last"); + /* Disable all LSMs not in the ordered list. */ for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { if (exists_ordered_lsm(lsm)) -- 2.34.1