@@ -6,9 +6,20 @@
#ifndef _LSM_H_
#define _LSM_H_
+#include <linux/printk.h>
#include <linux/lsm_hooks.h>
#include <linux/lsm_count.h>
+/* LSM debugging */
+extern bool lsm_debug;
+#define lsm_pr(...) pr_info(__VA_ARGS__)
+#define lsm_pr_cont(...) pr_cont(__VA_ARGS__)
+#define lsm_pr_dbg(...) \
+ do { \
+ if (lsm_debug) \
+ pr_info(__VA_ARGS__); \
+ } while (0)
+
/* List of configured LSMs */
extern unsigned int lsm_count;
extern const struct lsm_id *lsm_idlist[];
@@ -30,13 +30,6 @@ static __initdata const char *lsm_order_legacy;
static __initdata struct lsm_info *lsm_exclusive;
static __initdata struct lsm_info *lsm_order[MAX_LSM_COUNT + 1];
-static __initdata bool debug;
-#define init_debug(...) \
- do { \
- if (debug) \
- pr_info(__VA_ARGS__); \
- } while (0)
-
#define lsm_order_for_each(iter) \
for ((iter) = lsm_order; *(iter); (iter)++)
#define lsm_for_each_raw(iter) \
@@ -77,7 +70,7 @@ __setup("lsm=", lsm_choose_lsm);
*/
static int __init lsm_debug_enable(char *str)
{
- debug = true;
+ lsm_debug = true;
return 1;
}
__setup("lsm.debug", lsm_debug_enable);
@@ -145,22 +138,28 @@ static void __init lsm_order_append(struct lsm_info *lsm, const char *src)
return;
/* Skip explicitly disabled LSMs. */
- if (lsm->enabled && !lsm_is_enabled(lsm))
- goto out;
+ if (lsm->enabled && !lsm_is_enabled(lsm)) {
+ lsm_pr_dbg("skip previously disabled LSM %s:%s\n",
+ src, lsm->id->name);
+ return;
+ }
- if (WARN(lsm_count == MAX_LSM_COUNT,
- "%s: out of LSM static calls!?\n", src)) {
+ if (lsm_count == MAX_LSM_COUNT) {
+ pr_warn("exceeded maximum LSM count on %s:%s\n",
+ src, lsm->id->name);
lsm_enabled_set(lsm, false);
- goto out;
+ return;
}
if (lsm->flags & LSM_FLAG_EXCLUSIVE) {
if (lsm_exclusive) {
- init_debug("exclusive disabled: %s\n", lsm->id->name);
+ lsm_pr_dbg("skip exclusive LSM conflict %s:%s\n",
+ src, lsm->id->name);
lsm_enabled_set(lsm, false);
- goto out;
+ return;
} else {
- init_debug("exclusive chosen: %s\n", lsm->id->name);
+ lsm_pr_dbg("select exclusive LSM %s:%s\n",
+ src, lsm->id->name);
lsm_exclusive = lsm;
}
}
@@ -169,9 +168,7 @@ static void __init lsm_order_append(struct lsm_info *lsm, const char *src)
lsm_order[lsm_count] = lsm;
lsm_idlist[lsm_count++] = lsm->id;
-out:
- init_debug("%s ordered: %s (%s)\n", src, lsm->id->name,
- lsm_is_enabled(lsm) ? "enabled" : "disabled");
+ lsm_pr_dbg("enabling LSM %s:%s\n", src, lsm->id->name);
}
/**
@@ -196,8 +193,8 @@ static void __init lsm_order_parse(const char *list, const char *src)
if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) &&
strcmp(lsm->id->name, lsm_order_legacy)) {
lsm_enabled_set(lsm, false);
- init_debug("security=%s disabled: %s (only one legacy major LSM)\n",
- lsm_order_legacy, lsm->id->name);
+ lsm_pr_dbg("skip legacy LSM conflict %s:%s\n",
+ src, lsm->id->name);
}
}
}
@@ -240,8 +237,7 @@ static void __init lsm_order_parse(const char *list, const char *src)
if (lsm_order_exists(lsm))
continue;
lsm_enabled_set(lsm, false);
- init_debug("%s skipped: %s (not in requested order)\n",
- src, lsm->id->name);
+ lsm_pr_dbg("skip disabled LSM %s:%s\n", src, lsm->id->name);
}
}
@@ -308,16 +304,18 @@ static void __init lsm_init_single(struct lsm_info *lsm)
if (!lsm_is_enabled(lsm))
return;
- init_debug("initializing %s\n", lsm->id->name);
+ lsm_pr_dbg("initialize LSM %s\n", lsm->id->name);
ret = lsm->init();
- WARN(ret, "%s failed to initialize: %d\n", lsm->id->name, ret);
+ if (ret)
+ pr_warn("failed to initialize LSM %s with errno %d\n",
+ lsm->id->name, ret);
}
/**
* lsm_static_call_init - Initialize a LSM's static calls
* @hl: LSM hook list
*/
-static void __init lsm_static_call_init(struct security_hook_list *hl)
+static int __init lsm_static_call_init(struct security_hook_list *hl)
{
struct lsm_static_call *scall = hl->scalls;
int i;
@@ -329,11 +327,12 @@ static void __init lsm_static_call_init(struct security_hook_list *hl)
hl->hook.lsm_func_addr);
scall->hl = hl;
static_branch_enable(scall->active);
- return;
+ return 0;
}
scall++;
}
- panic("%s - Ran out of static slots.\n", __func__);
+
+ return -ENOSPC;
}
/**
@@ -351,7 +350,9 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
for (i = 0; i < count; i++) {
hooks[i].lsmid = lsmid;
- lsm_static_call_init(&hooks[i]);
+ if (lsm_static_call_init(&hooks[i]))
+ panic("exhausted LSM callback slots with LSM %s\n",
+ lsmid->name);
}
}
@@ -382,18 +383,16 @@ int __init security_init(void)
{
unsigned int cnt;
struct lsm_info **lsm;
- struct lsm_info *early;
- init_debug("legacy security=%s\n", lsm_order_legacy ? : " *unspecified*");
- init_debug(" CONFIG_LSM=%s\n", lsm_order_builtin);
- init_debug("boot arg lsm=%s\n", lsm_order_cmdline ? : " *unspecified*");
+ if (lsm_debug) {
+ lsm_pr("built-in LSM list: %s\n", lsm_order_builtin);
+ lsm_pr("legacy LSM parameter: %s\n", lsm_order_legacy);
+ lsm_pr("boot LSM parameter: %s\n", lsm_order_cmdline);
+ }
if (lsm_order_cmdline) {
- if (lsm_order_legacy) {
- pr_warn("security=%s is ignored because it is superseded by lsm=%s\n",
- lsm_order_legacy, lsm_order_cmdline);
+ if (lsm_order_legacy)
lsm_order_legacy = NULL;
- }
lsm_order_parse(lsm_order_cmdline, "cmdline");
} else
lsm_order_parse(lsm_order_builtin, "builtin");
@@ -401,36 +400,22 @@ int __init security_init(void)
lsm_order_for_each(lsm)
lsm_prep_single(*lsm);
- pr_info("initializing lsm=");
- lsm_early_for_each_raw(early) {
- if (lsm_is_enabled(early))
- pr_cont("%s%s",
- early == __start_early_lsm_info ? "" : ",",
- early->id->name);
+ if (lsm_debug) {
+ lsm_pr("blob(cred) size %d\n", blob_sizes.lbs_cred);
+ lsm_pr("blob(file) size %d\n", blob_sizes.lbs_file);
+ lsm_pr("blob(ib) size %d\n", blob_sizes.lbs_ib);
+ lsm_pr("blob(inode) size %d\n", blob_sizes.lbs_inode);
+ lsm_pr("blob(ipc) size %d\n", blob_sizes.lbs_ipc);
+ lsm_pr("blob(key) size %d\n", blob_sizes.lbs_key);
+ lsm_pr("blob(msg_msg)_size %d\n", blob_sizes.lbs_msg_msg);
+ lsm_pr("blob(sock) size %d\n", blob_sizes.lbs_sock);
+ lsm_pr("blob(superblock) size %d\n", blob_sizes.lbs_superblock);
+ lsm_pr("blob(perf_event) size %d\n", blob_sizes.lbs_perf_event);
+ lsm_pr("blob(task) size %d\n", blob_sizes.lbs_task);
+ lsm_pr("blob(tun_dev) size %d\n", blob_sizes.lbs_tun_dev);
+ lsm_pr("blob(xattr) count %d\n", blob_sizes.lbs_xattr_count);
+ lsm_pr("blob(bdev) size %d\n", blob_sizes.lbs_bdev);
}
- lsm_order_for_each(lsm) {
- if (lsm_is_enabled(*lsm))
- pr_cont("%s%s",
- lsm == lsm_order ? "" : ",", (*lsm)->id->name);
- }
- pr_cont("\n");
-
- init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
- init_debug("file blob size = %d\n", blob_sizes.lbs_file);
- init_debug("ib blob size = %d\n", blob_sizes.lbs_ib);
- init_debug("inode blob size = %d\n", blob_sizes.lbs_inode);
- init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc);
-#ifdef CONFIG_KEYS
- init_debug("key blob size = %d\n", blob_sizes.lbs_key);
-#endif /* CONFIG_KEYS */
- init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg);
- init_debug("sock blob size = %d\n", blob_sizes.lbs_sock);
- init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
- init_debug("perf event blob size = %d\n", blob_sizes.lbs_perf_event);
- init_debug("task blob size = %d\n", blob_sizes.lbs_task);
- init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
- init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count);
- init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev);
if (blob_sizes.lbs_file)
lsm_file_cache = kmem_cache_create("lsm_file_cache",
@@ -442,9 +427,9 @@ int __init security_init(void)
SLAB_PANIC, NULL);
if (lsm_cred_alloc((struct cred *)current->cred, GFP_KERNEL))
- panic("%s: early cred alloc failed.\n", __func__);
+ panic("early LSM cred alloc failed\n");
if (lsm_task_alloc(current))
- panic("%s: early task alloc failed.\n", __func__);
+ panic("early LSM task alloc failed\n");
cnt = 0;
lsm_order_for_each(lsm) {
@@ -73,6 +73,8 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX + 1] = {
[LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
};
+bool lsm_debug __ro_after_init;
+
unsigned int lsm_count __ro_after_init;
const struct lsm_id *lsm_idlist[MAX_LSM_COUNT];
One part of a larger effort to cleanup the LSM framework initialization code. Signed-off-by: Paul Moore <paul@paul-moore.com> --- security/lsm.h | 11 ++++ security/lsm_init.c | 121 +++++++++++++++++++------------------------- security/security.c | 2 + 3 files changed, 66 insertions(+), 68 deletions(-)