Commit df0ce173 authored by Sargun Dhillon's avatar Sargun Dhillon Committed by James Morris

security: convert security hooks to use hlist

This changes security_hook_heads to use hlist_heads instead of
the circular doubly-linked list heads. This should cut down
the size of the struct by about half.

In addition, it allows mutation of the hooks at the tail of the
callback list without having to modify the head. The longer-term
purpose of this is to enable making the heads read only.
Signed-off-by: default avatarSargun Dhillon <sargun@sargun.me>
Reviewed-by: default avatarTetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Acked-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
Signed-off-by: default avatarJames Morris <james.morris@microsoft.com>
parent 5893ed18
This diff is collapsed.
......@@ -52,8 +52,8 @@ 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 list_head */
{ "security/security.c", "list_head", "security_hook_heads" },
/* walk struct security_hook_heads as an array of struct hlist_head */
{ "security/security.c", "hlist_head", "security_hook_heads" },
{ }
};
......
......@@ -61,11 +61,11 @@ static void __init do_security_initcalls(void)
int __init security_init(void)
{
int i;
struct list_head *list = (struct list_head *) &security_hook_heads;
struct hlist_head *list = (struct hlist_head *) &security_hook_heads;
for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct list_head);
for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head);
i++)
INIT_LIST_HEAD(&list[i]);
INIT_HLIST_HEAD(&list[i]);
pr_info("Security Framework initialized\n");
/*
......@@ -163,7 +163,7 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
for (i = 0; i < count; i++) {
hooks[i].lsm = lsm;
list_add_tail_rcu(&hooks[i].list, hooks[i].head);
hlist_add_tail_rcu(&hooks[i].list, hooks[i].head);
}
if (lsm_append(lsm, &lsm_names) < 0)
panic("%s - Cannot get early memory.\n", __func__);
......@@ -201,7 +201,7 @@ EXPORT_SYMBOL(unregister_lsm_notifier);
do { \
struct security_hook_list *P; \
\
list_for_each_entry(P, &security_hook_heads.FUNC, list) \
hlist_for_each_entry(P, &security_hook_heads.FUNC, list) \
P->hook.FUNC(__VA_ARGS__); \
} while (0)
......@@ -210,7 +210,7 @@ EXPORT_SYMBOL(unregister_lsm_notifier);
do { \
struct security_hook_list *P; \
\
list_for_each_entry(P, &security_hook_heads.FUNC, list) { \
hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
RC = P->hook.FUNC(__VA_ARGS__); \
if (RC != 0) \
break; \
......@@ -317,7 +317,7 @@ int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
* agree that it should be set it will. If any module
* thinks it should not be set it won't.
*/
list_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) {
hlist_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) {
rc = hp->hook.vm_enough_memory(mm, pages);
if (rc <= 0) {
cap_sys_admin = 0;
......@@ -805,7 +805,7 @@ int security_inode_getsecurity(struct inode *inode, const char *name, void **buf
/*
* Only one module will provide an attribute with a given name.
*/
list_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) {
hlist_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) {
rc = hp->hook.inode_getsecurity(inode, name, buffer, alloc);
if (rc != -EOPNOTSUPP)
return rc;
......@@ -823,7 +823,7 @@ int security_inode_setsecurity(struct inode *inode, const char *name, const void
/*
* Only one module will provide an attribute with a given name.
*/
list_for_each_entry(hp, &security_hook_heads.inode_setsecurity, list) {
hlist_for_each_entry(hp, &security_hook_heads.inode_setsecurity, list) {
rc = hp->hook.inode_setsecurity(inode, name, value, size,
flags);
if (rc != -EOPNOTSUPP)
......@@ -1126,7 +1126,7 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
int rc = -ENOSYS;
struct security_hook_list *hp;
list_for_each_entry(hp, &security_hook_heads.task_prctl, list) {
hlist_for_each_entry(hp, &security_hook_heads.task_prctl, list) {
thisrc = hp->hook.task_prctl(option, arg2, arg3, arg4, arg5);
if (thisrc != -ENOSYS) {
rc = thisrc;
......@@ -1629,7 +1629,7 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
* For speed optimization, we explicitly break the loop rather than
* using the macro
*/
list_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match,
hlist_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match,
list) {
rc = hp->hook.xfrm_state_pol_flow_match(x, xp, fl);
break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment