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: KP Singh <kpsingh@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Brendan Jackman <jackmanb@google.com> Reviewed-by: Florent Revest <revest@google.com> Reviewed-by: Kees Cook <keescook@chromium.org> Reviewed-by: Casey Schaufler <casey@schaufler-ca.com> Acked-by: James Morris <jamorris@linux.microsoft.com> Link: https://lore.kernel.org/bpf/20200329004356.27286-3-kpsingh@chromium.org
This commit is contained in:
committed by
Daniel Borkmann
parent
fc611f47f2
commit
98e828a065
@@ -668,6 +668,25 @@ static void __init lsm_early_task(struct task_struct *task)
|
||||
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.
|
||||
*
|
||||
@@ -1338,16 +1357,16 @@ int security_inode_getsecurity(struct inode *inode, const char *name, void **buf
|
||||
int rc;
|
||||
|
||||
if (unlikely(IS_PRIVATE(inode)))
|
||||
return -EOPNOTSUPP;
|
||||
return LSM_RET_DEFAULT(inode_getsecurity);
|
||||
/*
|
||||
* Only one module will provide an attribute with a given name.
|
||||
*/
|
||||
hlist_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) {
|
||||
rc = hp->hook.inode_getsecurity(inode, name, buffer, alloc);
|
||||
if (rc != -EOPNOTSUPP)
|
||||
if (rc != LSM_RET_DEFAULT(inode_getsecurity))
|
||||
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)
|
||||
@@ -1356,17 +1375,17 @@ int security_inode_setsecurity(struct inode *inode, const char *name, const void
|
||||
int rc;
|
||||
|
||||
if (unlikely(IS_PRIVATE(inode)))
|
||||
return -EOPNOTSUPP;
|
||||
return LSM_RET_DEFAULT(inode_setsecurity);
|
||||
/*
|
||||
* Only one module will provide an attribute with a given name.
|
||||
*/
|
||||
hlist_for_each_entry(hp, &security_hook_heads.inode_setsecurity, list) {
|
||||
rc = hp->hook.inode_setsecurity(inode, name, value, size,
|
||||
flags);
|
||||
if (rc != -EOPNOTSUPP)
|
||||
if (rc != LSM_RET_DEFAULT(inode_setsecurity))
|
||||
return rc;
|
||||
}
|
||||
return -EOPNOTSUPP;
|
||||
return LSM_RET_DEFAULT(inode_setsecurity);
|
||||
}
|
||||
|
||||
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,
|
||||
unsigned long arg4, unsigned long arg5)
|
||||
{
|
||||
int thisrc;
|
||||
int rc = -ENOSYS;
|
||||
int rc = LSM_RET_DEFAULT(task_prctl);
|
||||
struct security_hook_list *hp;
|
||||
|
||||
hlist_for_each_entry(hp, &security_hook_heads.task_prctl, list) {
|
||||
thisrc = hp->hook.task_prctl(option, arg2, arg3, arg4, arg5);
|
||||
if (thisrc != -ENOSYS) {
|
||||
if (thisrc != LSM_RET_DEFAULT(task_prctl)) {
|
||||
rc = thisrc;
|
||||
if (thisrc != 0)
|
||||
break;
|
||||
@@ -1917,7 +1936,7 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name,
|
||||
continue;
|
||||
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,
|
||||
@@ -1930,7 +1949,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value,
|
||||
continue;
|
||||
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)
|
||||
@@ -2315,7 +2334,7 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
|
||||
const struct flowi *fl)
|
||||
{
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user