2020-03-29 03:43:49 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright ( C ) 2020 Google LLC .
*/
# include <linux/filter.h>
# include <linux/bpf.h>
# include <linux/btf.h>
2020-11-18 02:29:28 +03:00
# include <linux/binfmts.h>
2020-03-29 03:43:51 +03:00
# include <linux/lsm_hooks.h>
# include <linux/bpf_lsm.h>
2020-03-29 03:43:52 +03:00
# include <linux/kallsyms.h>
# include <linux/bpf_verifier.h>
2020-08-25 21:29:18 +03:00
# include <net/bpf_sk_storage.h>
# include <linux/bpf_local_storage.h>
2020-11-06 02:06:51 +03:00
# include <linux/btf_ids.h>
2020-03-29 03:43:51 +03:00
/* For every LSM hook that allows attachment of BPF programs, declare a nop
* function where a BPF program can be attached .
*/
# define LSM_HOOK(RET, DEFAULT, NAME, ...) \
noinline RET bpf_lsm_ # # NAME ( __VA_ARGS__ ) \
{ \
return DEFAULT ; \
}
# include <linux/lsm_hook_defs.h>
# undef LSM_HOOK
2020-03-29 03:43:49 +03:00
2020-11-06 02:06:51 +03:00
# define LSM_HOOK(RET, DEFAULT, NAME, ...) BTF_ID(func, bpf_lsm_##NAME)
BTF_SET_START ( bpf_lsm_hooks )
# include <linux/lsm_hook_defs.h>
# undef LSM_HOOK
BTF_SET_END ( bpf_lsm_hooks )
2020-03-29 03:43:52 +03:00
int bpf_lsm_verify_prog ( struct bpf_verifier_log * vlog ,
const struct bpf_prog * prog )
{
if ( ! prog - > gpl_compatible ) {
bpf_log ( vlog ,
" LSM programs must have a GPL compatible license \n " ) ;
return - EINVAL ;
}
2020-11-06 02:06:51 +03:00
if ( ! btf_id_set_contains ( & bpf_lsm_hooks , prog - > aux - > attach_btf_id ) ) {
2020-03-29 03:43:52 +03:00
bpf_log ( vlog , " attach_btf_id %u points to wrong type name %s \n " ,
prog - > aux - > attach_btf_id , prog - > aux - > attach_func_name ) ;
return - EINVAL ;
}
return 0 ;
}
2020-11-18 02:29:28 +03:00
/* Mask for all the currently supported BPRM option flags */
# define BPF_F_BRPM_OPTS_MASK BPF_F_BPRM_SECUREEXEC
BPF_CALL_2 ( bpf_bprm_opts_set , struct linux_binprm * , bprm , u64 , flags )
{
if ( flags & ~ BPF_F_BRPM_OPTS_MASK )
return - EINVAL ;
bprm - > secureexec = ( flags & BPF_F_BPRM_SECUREEXEC ) ;
return 0 ;
}
BTF_ID_LIST_SINGLE ( bpf_bprm_opts_set_btf_ids , struct , linux_binprm )
const static struct bpf_func_proto bpf_bprm_opts_set_proto = {
. func = bpf_bprm_opts_set ,
. gpl_only = false ,
. ret_type = RET_INTEGER ,
. arg1_type = ARG_PTR_TO_BTF_ID ,
. arg1_btf_id = & bpf_bprm_opts_set_btf_ids [ 0 ] ,
. arg2_type = ARG_ANYTHING ,
} ;
2020-08-25 21:29:18 +03:00
static const struct bpf_func_proto *
bpf_lsm_func_proto ( enum bpf_func_id func_id , const struct bpf_prog * prog )
{
switch ( func_id ) {
case BPF_FUNC_inode_storage_get :
return & bpf_inode_storage_get_proto ;
case BPF_FUNC_inode_storage_delete :
return & bpf_inode_storage_delete_proto ;
case BPF_FUNC_sk_storage_get :
2020-09-25 03:04:02 +03:00
return & bpf_sk_storage_get_proto ;
2020-08-25 21:29:18 +03:00
case BPF_FUNC_sk_storage_delete :
2020-09-25 03:04:02 +03:00
return & bpf_sk_storage_delete_proto ;
2020-11-06 13:37:39 +03:00
case BPF_FUNC_spin_lock :
return & bpf_spin_lock_proto ;
case BPF_FUNC_spin_unlock :
return & bpf_spin_unlock_proto ;
2020-11-06 13:37:40 +03:00
case BPF_FUNC_task_storage_get :
return & bpf_task_storage_get_proto ;
case BPF_FUNC_task_storage_delete :
return & bpf_task_storage_delete_proto ;
2020-11-18 02:29:28 +03:00
case BPF_FUNC_bprm_opts_set :
return & bpf_bprm_opts_set_proto ;
2020-08-25 21:29:18 +03:00
default :
return tracing_prog_func_proto ( func_id , prog ) ;
}
}
2020-11-13 03:59:29 +03:00
/* The set of hooks which are called without pagefaults disabled and are allowed
* to " sleep " and thus can be used for sleeable BPF programs .
*/
BTF_SET_START ( sleepable_lsm_hooks )
BTF_ID ( func , bpf_lsm_bpf )
BTF_ID ( func , bpf_lsm_bpf_map )
BTF_ID ( func , bpf_lsm_bpf_map_alloc_security )
BTF_ID ( func , bpf_lsm_bpf_map_free_security )
BTF_ID ( func , bpf_lsm_bpf_prog )
BTF_ID ( func , bpf_lsm_bprm_check_security )
BTF_ID ( func , bpf_lsm_bprm_committed_creds )
BTF_ID ( func , bpf_lsm_bprm_committing_creds )
BTF_ID ( func , bpf_lsm_bprm_creds_for_exec )
BTF_ID ( func , bpf_lsm_bprm_creds_from_file )
BTF_ID ( func , bpf_lsm_capget )
BTF_ID ( func , bpf_lsm_capset )
BTF_ID ( func , bpf_lsm_cred_prepare )
BTF_ID ( func , bpf_lsm_file_ioctl )
BTF_ID ( func , bpf_lsm_file_lock )
BTF_ID ( func , bpf_lsm_file_open )
BTF_ID ( func , bpf_lsm_file_receive )
BTF_ID ( func , bpf_lsm_inet_conn_established )
BTF_ID ( func , bpf_lsm_inode_create )
BTF_ID ( func , bpf_lsm_inode_free_security )
BTF_ID ( func , bpf_lsm_inode_getattr )
BTF_ID ( func , bpf_lsm_inode_getxattr )
BTF_ID ( func , bpf_lsm_inode_mknod )
BTF_ID ( func , bpf_lsm_inode_need_killpriv )
BTF_ID ( func , bpf_lsm_inode_post_setxattr )
BTF_ID ( func , bpf_lsm_inode_readlink )
BTF_ID ( func , bpf_lsm_inode_rename )
BTF_ID ( func , bpf_lsm_inode_rmdir )
BTF_ID ( func , bpf_lsm_inode_setattr )
BTF_ID ( func , bpf_lsm_inode_setxattr )
BTF_ID ( func , bpf_lsm_inode_symlink )
BTF_ID ( func , bpf_lsm_inode_unlink )
BTF_ID ( func , bpf_lsm_kernel_module_request )
BTF_ID ( func , bpf_lsm_kernfs_init_security )
BTF_ID ( func , bpf_lsm_key_free )
BTF_ID ( func , bpf_lsm_mmap_file )
BTF_ID ( func , bpf_lsm_netlink_send )
BTF_ID ( func , bpf_lsm_path_notify )
BTF_ID ( func , bpf_lsm_release_secctx )
BTF_ID ( func , bpf_lsm_sb_alloc_security )
BTF_ID ( func , bpf_lsm_sb_eat_lsm_opts )
BTF_ID ( func , bpf_lsm_sb_kern_mount )
BTF_ID ( func , bpf_lsm_sb_mount )
BTF_ID ( func , bpf_lsm_sb_remount )
BTF_ID ( func , bpf_lsm_sb_set_mnt_opts )
BTF_ID ( func , bpf_lsm_sb_show_options )
BTF_ID ( func , bpf_lsm_sb_statfs )
BTF_ID ( func , bpf_lsm_sb_umount )
BTF_ID ( func , bpf_lsm_settime )
BTF_ID ( func , bpf_lsm_socket_accept )
BTF_ID ( func , bpf_lsm_socket_bind )
BTF_ID ( func , bpf_lsm_socket_connect )
BTF_ID ( func , bpf_lsm_socket_create )
BTF_ID ( func , bpf_lsm_socket_getpeername )
BTF_ID ( func , bpf_lsm_socket_getpeersec_dgram )
BTF_ID ( func , bpf_lsm_socket_getsockname )
BTF_ID ( func , bpf_lsm_socket_getsockopt )
BTF_ID ( func , bpf_lsm_socket_listen )
BTF_ID ( func , bpf_lsm_socket_post_create )
BTF_ID ( func , bpf_lsm_socket_recvmsg )
BTF_ID ( func , bpf_lsm_socket_sendmsg )
BTF_ID ( func , bpf_lsm_socket_shutdown )
BTF_ID ( func , bpf_lsm_socket_socketpair )
BTF_ID ( func , bpf_lsm_syslog )
BTF_ID ( func , bpf_lsm_task_alloc )
BTF_ID ( func , bpf_lsm_task_getsecid )
BTF_ID ( func , bpf_lsm_task_prctl )
BTF_ID ( func , bpf_lsm_task_setscheduler )
BTF_ID ( func , bpf_lsm_task_to_inode )
BTF_SET_END ( sleepable_lsm_hooks )
bool bpf_lsm_is_sleepable_hook ( u32 btf_id )
{
return btf_id_set_contains ( & sleepable_lsm_hooks , btf_id ) ;
}
2020-03-29 03:43:49 +03:00
const struct bpf_prog_ops lsm_prog_ops = {
} ;
const struct bpf_verifier_ops lsm_verifier_ops = {
2020-08-25 21:29:18 +03:00
. get_func_proto = bpf_lsm_func_proto ,
2020-03-29 03:43:49 +03:00
. is_valid_access = btf_ctx_access ,
} ;