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-11-24 18:12:09 +03:00
# include <linux/ima.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 )
2021-03-23 00:51:51 +03:00
static const struct bpf_func_proto bpf_bprm_opts_set_proto = {
2020-11-18 02:29:28 +03:00
. 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-11-24 18:12:09 +03:00
BPF_CALL_3 ( bpf_ima_inode_hash , struct inode * , inode , void * , dst , u32 , size )
{
return ima_inode_hash ( inode , dst , size ) ;
}
static bool bpf_ima_inode_hash_allowed ( const struct bpf_prog * prog )
{
return bpf_lsm_is_sleepable_hook ( prog - > aux - > attach_btf_id ) ;
}
BTF_ID_LIST_SINGLE ( bpf_ima_inode_hash_btf_ids , struct , inode )
2021-03-23 00:51:51 +03:00
static const struct bpf_func_proto bpf_ima_inode_hash_proto = {
2020-11-24 18:12:09 +03:00
. func = bpf_ima_inode_hash ,
. gpl_only = false ,
. ret_type = RET_INTEGER ,
. arg1_type = ARG_PTR_TO_BTF_ID ,
. arg1_btf_id = & bpf_ima_inode_hash_btf_ids [ 0 ] ,
. arg2_type = ARG_PTR_TO_UNINIT_MEM ,
. arg3_type = ARG_CONST_SIZE ,
. allowed = bpf_ima_inode_hash_allowed ,
} ;
2022-03-02 14:13:58 +03:00
BPF_CALL_3 ( bpf_ima_file_hash , struct file * , file , void * , dst , u32 , size )
{
return ima_file_hash ( file , dst , size ) ;
}
BTF_ID_LIST_SINGLE ( bpf_ima_file_hash_btf_ids , struct , file )
static const struct bpf_func_proto bpf_ima_file_hash_proto = {
. func = bpf_ima_file_hash ,
. gpl_only = false ,
. ret_type = RET_INTEGER ,
. arg1_type = ARG_PTR_TO_BTF_ID ,
. arg1_btf_id = & bpf_ima_file_hash_btf_ids [ 0 ] ,
. arg2_type = ARG_PTR_TO_UNINIT_MEM ,
. arg3_type = ARG_CONST_SIZE ,
. allowed = bpf_ima_inode_hash_allowed ,
} ;
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 ;
2021-05-25 21:35:29 +03:00
# ifdef CONFIG_NET
2020-08-25 21:29:18 +03:00
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 ;
2021-05-25 21:35:29 +03:00
# endif /* CONFIG_NET */
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-18 02:29:28 +03:00
case BPF_FUNC_bprm_opts_set :
return & bpf_bprm_opts_set_proto ;
2020-11-24 18:12:09 +03:00
case BPF_FUNC_ima_inode_hash :
return prog - > aux - > sleepable ? & bpf_ima_inode_hash_proto : NULL ;
2022-03-02 14:13:58 +03:00
case BPF_FUNC_ima_file_hash :
return prog - > aux - > sleepable ? & bpf_ima_file_hash_proto : NULL ;
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
2021-06-16 05:04:36 +03:00
* to " sleep " and thus can be used for sleepable BPF programs .
2020-11-13 03:59:29 +03:00
*/
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 )
2021-01-25 09:39:36 +03:00
# ifdef CONFIG_SECURITY_NETWORK
2020-11-13 03:59:29 +03:00
BTF_ID ( func , bpf_lsm_inet_conn_established )
2021-01-25 09:39:36 +03:00
# endif /* CONFIG_SECURITY_NETWORK */
2020-11-13 03:59:29 +03:00
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 )
2022-03-02 14:14:02 +03:00
BTF_ID ( func , bpf_lsm_kernel_read_file )
2020-11-13 03:59:29 +03:00
BTF_ID ( func , bpf_lsm_kernfs_init_security )
2021-01-25 09:39:36 +03:00
# ifdef CONFIG_KEYS
2020-11-13 03:59:29 +03:00
BTF_ID ( func , bpf_lsm_key_free )
2021-01-25 09:39:36 +03:00
# endif /* CONFIG_KEYS */
2020-11-13 03:59:29 +03:00
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 )
2021-01-25 09:39:36 +03:00
# ifdef CONFIG_SECURITY_NETWORK
2020-11-13 03:59:29 +03:00
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 )
2021-01-25 09:39:36 +03:00
# endif /* CONFIG_SECURITY_NETWORK */
2020-11-13 03:59:29 +03:00
BTF_ID ( func , bpf_lsm_syslog )
BTF_ID ( func , bpf_lsm_task_alloc )
2022-01-25 07:20:51 +03:00
BTF_ID ( func , bpf_lsm_current_getsecid_subj )
2021-02-19 22:26:21 +03:00
BTF_ID ( func , bpf_lsm_task_getsecid_obj )
2020-11-13 03:59:29 +03:00
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 ,
} ;