@@ -2014,7 +2014,7 @@ struct lsm_info {
struct security_hook_list {
struct hlist_node list;
- struct hlist_head *head;
+ const unsigned int offset;
union security_list_options hook;
/* This field is not currently in use */
struct lsm_info *info;
@@ -2026,8 +2026,13 @@ struct security_hook_list {
* care of the common case and reduces the amount of
* text involved.
*/
+#define HOOK_OFFSET(HEAD) offsetof(struct security_hook_heads, HEAD)
+
#define LSM_HOOK_INIT(HEAD, HOOK) \
- { .head = &security_hook_heads.HEAD, .hook = { .HEAD = HOOK } }
+ { \
+ .offset = HOOK_OFFSET(HEAD), \
+ .hook = { .HEAD = HOOK } \
+ }
#define LSM_MODULE_INIT(NAME, HOOKS) \
{ \
@@ -2036,7 +2041,6 @@ struct security_hook_list {
.count = ARRAY_SIZE(HOOKS), \
}
-extern struct security_hook_heads security_hook_heads;
extern void security_add_hooks(struct lsm_info *lsm);
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
@@ -52,8 +52,6 @@ static const struct whitelist_entry whitelist[] = {
{ "net/unix/af_unix.c", "unix_skb_parms", "char" },
/* big_key payload.data struct splashing */
{ "security/keys/big_key.c", "path", "void *" },
- /* walk struct security_hook_heads as an array of struct hlist_head */
- { "security/security.c", "hlist_head", "security_hook_heads" },
{ }
};
@@ -41,9 +41,13 @@
DEFINE_MUTEX(lsm_info_lock);
struct hlist_head lsm_info_head __lsm_ro_after_init = HLIST_HEAD_INIT;
-struct security_hook_heads security_hook_heads __lsm_ro_after_init;
+static struct security_hook_heads security_hook_heads __lsm_ro_after_init;
static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
+struct security_hook_heads *get_security_hook_heads(void)
+{
+ return &security_hook_heads;
+}
/* Boot-time LSM user choice */
static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
@@ -70,12 +74,6 @@ static void __init do_security_initcalls(void)
*/
int __init security_init(void)
{
- int i;
- struct hlist_head *list = (struct hlist_head *) &security_hook_heads;
-
- for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head);
- i++)
- INIT_HLIST_HEAD(&list[i]);
pr_info("Security Framework initialized\n");
/*
@@ -152,6 +150,20 @@ void security_delete_hooks(struct lsm_info *info)
mutex_unlock(&lsm_info_lock);
}
#endif /* CONFIG_SECURITY_SELINUX_DISABLE */
+
+static void __init security_add_hook(struct security_hook_list *hook,
+ struct lsm_info *info)
+{
+ const unsigned int offset = hook->offset;
+ const unsigned int idx = offset / sizeof(struct hlist_head);
+ struct hlist_head *head;
+
+ WARN_ON(offset % sizeof(struct hlist_head));
+
+ hook->info = info;
+ head = (struct hlist_head *)(&security_hook_heads) + idx;
+ hlist_add_tail_rcu(&hook->list, head);
+}
/**
* security_add_hooks - Add a modules hooks to the hook lists.
* @lsm_info: The lsm_info struct for this security module
@@ -160,14 +172,10 @@ void security_delete_hooks(struct lsm_info *info)
*/
void __init security_add_hooks(struct lsm_info *info)
{
- struct security_hook_list *hook;
int i;
- for (i = 0; i < info->count; i++) {
- hook = &info->hooks[i];
- hook->info = info;
- hlist_add_tail_rcu(&hook->list, hook->head);
- }
+ for (i = 0; i < info->count; i++)
+ security_add_hook(&info->hooks[i], info);
mutex_lock(&lsm_info_lock);
hlist_add_tail_rcu(&info->list, &lsm_info_head);
@@ -5,6 +5,7 @@
#ifndef __SECURITY_SECURITY_H
#define __SECURITY_SECURITY_H
-extern struct hlist_head lsm_info_head;
extern struct mutex lsm_info_lock;
+extern struct hlist_head lsm_info_head;
+extern struct security_hook_heads *get_security_hook_heads(void);
#endif
This is in preparation for future patches. The pointer to the hook head is no longer embedded in the security_hook_list structure, and instead, now there is an offset. In addition, since struct security_hook_heads is a static defined in security.c, and it's full of hlist_heads, who's initialization involves setting them to null, there's no more reason for explicit initialization. Signed-off-by: Sargun Dhillon <sargun@sargun.me> --- include/linux/lsm_hooks.h | 10 +++++--- scripts/gcc-plugins/randomize_layout_plugin.c | 2 -- security/security.c | 34 +++++++++++++++++---------- security/security.h | 3 ++- 4 files changed, 30 insertions(+), 19 deletions(-)