Commit 98e828a0 authored by KP Singh's avatar KP Singh Committed by Daniel Borkmann

security: Refactor declaration of LSM hooks

The information about the different types of LSM hooks is scattered
in two locations i.e. union security_list_options and
struct security_hook_heads. Rather than duplicating this information
even further for BPF_PROG_TYPE_LSM, define all the hooks with the
LSM_HOOK macro in lsm_hook_defs.h which is then used to generate all
the data structures required by the LSM framework.

The LSM hooks are defined as:

  LSM_HOOK(<return_type>, <default_value>, <hook_name>, args...)

with <default_value> acccessible in security.c as:

  LSM_RET_DEFAULT(<hook_name>)
Signed-off-by: default avatarKP Singh <kpsingh@google.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Reviewed-by: default avatarBrendan Jackman <jackmanb@google.com>
Reviewed-by: default avatarFlorent Revest <revest@google.com>
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Reviewed-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
Acked-by: default avatarJames Morris <jamorris@linux.microsoft.com>
Link: https://lore.kernel.org/bpf/20200329004356.27286-3-kpsingh@chromium.org
parent fc611f47
This diff is collapsed.
This diff is collapsed.
...@@ -668,6 +668,25 @@ static void __init lsm_early_task(struct task_struct *task) ...@@ -668,6 +668,25 @@ static void __init lsm_early_task(struct task_struct *task)
panic("%s: Early task alloc failed.\n", __func__); panic("%s: Early task alloc failed.\n", __func__);
} }
/*
* The default value of the LSM hook is defined in linux/lsm_hook_defs.h and
* can be accessed with:
*
* LSM_RET_DEFAULT(<hook_name>)
*
* The macros below define static constants for the default value of each
* LSM hook.
*/
#define LSM_RET_DEFAULT(NAME) (NAME##_default)
#define DECLARE_LSM_RET_DEFAULT_void(DEFAULT, NAME)
#define DECLARE_LSM_RET_DEFAULT_int(DEFAULT, NAME) \
static const int LSM_RET_DEFAULT(NAME) = (DEFAULT);
#define LSM_HOOK(RET, DEFAULT, NAME, ...) \
DECLARE_LSM_RET_DEFAULT_##RET(DEFAULT, NAME)
#include <linux/lsm_hook_defs.h>
#undef LSM_HOOK
/* /*
* Hook list operation macros. * Hook list operation macros.
* *
...@@ -1338,16 +1357,16 @@ int security_inode_getsecurity(struct inode *inode, const char *name, void **buf ...@@ -1338,16 +1357,16 @@ int security_inode_getsecurity(struct inode *inode, const char *name, void **buf
int rc; int rc;
if (unlikely(IS_PRIVATE(inode))) if (unlikely(IS_PRIVATE(inode)))
return -EOPNOTSUPP; return LSM_RET_DEFAULT(inode_getsecurity);
/* /*
* Only one module will provide an attribute with a given name. * Only one module will provide an attribute with a given name.
*/ */
hlist_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); rc = hp->hook.inode_getsecurity(inode, name, buffer, alloc);
if (rc != -EOPNOTSUPP) if (rc != LSM_RET_DEFAULT(inode_getsecurity))
return rc; return rc;
} }
return -EOPNOTSUPP; return LSM_RET_DEFAULT(inode_getsecurity);
} }
int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
...@@ -1356,17 +1375,17 @@ int security_inode_setsecurity(struct inode *inode, const char *name, const void ...@@ -1356,17 +1375,17 @@ int security_inode_setsecurity(struct inode *inode, const char *name, const void
int rc; int rc;
if (unlikely(IS_PRIVATE(inode))) if (unlikely(IS_PRIVATE(inode)))
return -EOPNOTSUPP; return LSM_RET_DEFAULT(inode_setsecurity);
/* /*
* Only one module will provide an attribute with a given name. * Only one module will provide an attribute with a given name.
*/ */
hlist_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, rc = hp->hook.inode_setsecurity(inode, name, value, size,
flags); flags);
if (rc != -EOPNOTSUPP) if (rc != LSM_RET_DEFAULT(inode_setsecurity))
return rc; return rc;
} }
return -EOPNOTSUPP; return LSM_RET_DEFAULT(inode_setsecurity);
} }
int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
...@@ -1740,12 +1759,12 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, ...@@ -1740,12 +1759,12 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5) unsigned long arg4, unsigned long arg5)
{ {
int thisrc; int thisrc;
int rc = -ENOSYS; int rc = LSM_RET_DEFAULT(task_prctl);
struct security_hook_list *hp; struct security_hook_list *hp;
hlist_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); thisrc = hp->hook.task_prctl(option, arg2, arg3, arg4, arg5);
if (thisrc != -ENOSYS) { if (thisrc != LSM_RET_DEFAULT(task_prctl)) {
rc = thisrc; rc = thisrc;
if (thisrc != 0) if (thisrc != 0)
break; break;
...@@ -1917,7 +1936,7 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name, ...@@ -1917,7 +1936,7 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name,
continue; continue;
return hp->hook.getprocattr(p, name, value); return hp->hook.getprocattr(p, name, value);
} }
return -EINVAL; return LSM_RET_DEFAULT(getprocattr);
} }
int security_setprocattr(const char *lsm, const char *name, void *value, int security_setprocattr(const char *lsm, const char *name, void *value,
...@@ -1930,7 +1949,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, ...@@ -1930,7 +1949,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value,
continue; continue;
return hp->hook.setprocattr(name, value, size); return hp->hook.setprocattr(name, value, size);
} }
return -EINVAL; return LSM_RET_DEFAULT(setprocattr);
} }
int security_netlink_send(struct sock *sk, struct sk_buff *skb) int security_netlink_send(struct sock *sk, struct sk_buff *skb)
...@@ -2315,7 +2334,7 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x, ...@@ -2315,7 +2334,7 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
const struct flowi *fl) const struct flowi *fl)
{ {
struct security_hook_list *hp; struct security_hook_list *hp;
int rc = 1; int rc = LSM_RET_DEFAULT(xfrm_state_pol_flow_match);
/* /*
* Since this function is expected to return 0 or 1, the judgment * Since this function is expected to return 0 or 1, the judgment
......
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