@@ -2020,6 +2020,16 @@ struct security_hook_list {
char *lsm;
} __randomize_layout;
+/*
+ * The set of hooks that may be selected for a specific module.
+ */
+struct lsm_one_hooks {
+ char *lsm;
+ union security_list_options secid_to_secctx;
+ union security_list_options secctx_to_secid;
+ union security_list_options socket_getpeersec_stream;
+};
+
/*
* Security blob size or offset data.
*/
@@ -431,6 +431,9 @@ static int lsm_append(char *new, char **result)
return 0;
}
+/* Base list of once-only hooks */
+struct lsm_one_hooks lsm_base_one;
+
/**
* security_add_hooks - Add a modules hooks to the hook lists.
* @hooks: the hooks to add
@@ -447,6 +450,25 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
for (i = 0; i < count; i++) {
hooks[i].lsm = lsm;
hlist_add_tail_rcu(&hooks[i].list, hooks[i].head);
+
+ /*
+ * Check for the special hooks that are restricted to
+ * a single module to create the base set. Use the hooks
+ * from that module for the set, which may not be complete.
+ */
+ if (lsm_base_one.lsm && strcmp(lsm_base_one.lsm, hooks[i].lsm))
+ continue;
+ if (hooks[i].head == &security_hook_heads.secid_to_secctx)
+ lsm_base_one.secid_to_secctx = hooks[i].hook;
+ else if (hooks[i].head == &security_hook_heads.secctx_to_secid)
+ lsm_base_one.secctx_to_secid = hooks[i].hook;
+ else if (hooks[i].head ==
+ &security_hook_heads.socket_getpeersec_stream)
+ lsm_base_one.socket_getpeersec_stream = hooks[i].hook;
+ else
+ continue;
+ if (lsm_base_one.lsm == NULL)
+ lsm_base_one.lsm = kstrdup(hooks[i].lsm, GFP_KERNEL);
}
if (lsm_append(lsm, &lsm_names) < 0)
panic("%s - Cannot get early memory.\n", __func__);
@@ -725,14 +747,8 @@ int lsm_superblock_alloc(struct super_block *sb)
#define call_one_int_hook(FUNC, IRC, ...) ({ \
int RC = IRC; \
- do { \
- struct security_hook_list *P; \
- \
- hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
- RC = P->hook.FUNC(__VA_ARGS__); \
- break; \
- } \
- } while (0); \
+ if (lsm_base_one.FUNC.FUNC) \
+ RC = lsm_base_one.FUNC.FUNC(__VA_ARGS__); \
RC; \
})
Create a special set of LSM hooks for the translation to human readable security data. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> --- include/linux/lsm_hooks.h | 10 ++++++++++ security/security.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 8 deletions(-)