cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bpf_lsm.c (7825B)


      1// SPDX-License-Identifier: GPL-2.0
      2
      3/*
      4 * Copyright (C) 2020 Google LLC.
      5 */
      6
      7#include <linux/filter.h>
      8#include <linux/bpf.h>
      9#include <linux/btf.h>
     10#include <linux/binfmts.h>
     11#include <linux/lsm_hooks.h>
     12#include <linux/bpf_lsm.h>
     13#include <linux/kallsyms.h>
     14#include <linux/bpf_verifier.h>
     15#include <net/bpf_sk_storage.h>
     16#include <linux/bpf_local_storage.h>
     17#include <linux/btf_ids.h>
     18#include <linux/ima.h>
     19
     20/* For every LSM hook that allows attachment of BPF programs, declare a nop
     21 * function where a BPF program can be attached.
     22 */
     23#define LSM_HOOK(RET, DEFAULT, NAME, ...)	\
     24noinline RET bpf_lsm_##NAME(__VA_ARGS__)	\
     25{						\
     26	return DEFAULT;				\
     27}
     28
     29#include <linux/lsm_hook_defs.h>
     30#undef LSM_HOOK
     31
     32#define LSM_HOOK(RET, DEFAULT, NAME, ...) BTF_ID(func, bpf_lsm_##NAME)
     33BTF_SET_START(bpf_lsm_hooks)
     34#include <linux/lsm_hook_defs.h>
     35#undef LSM_HOOK
     36BTF_SET_END(bpf_lsm_hooks)
     37
     38int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog,
     39			const struct bpf_prog *prog)
     40{
     41	if (!prog->gpl_compatible) {
     42		bpf_log(vlog,
     43			"LSM programs must have a GPL compatible license\n");
     44		return -EINVAL;
     45	}
     46
     47	if (!btf_id_set_contains(&bpf_lsm_hooks, prog->aux->attach_btf_id)) {
     48		bpf_log(vlog, "attach_btf_id %u points to wrong type name %s\n",
     49			prog->aux->attach_btf_id, prog->aux->attach_func_name);
     50		return -EINVAL;
     51	}
     52
     53	return 0;
     54}
     55
     56/* Mask for all the currently supported BPRM option flags */
     57#define BPF_F_BRPM_OPTS_MASK	BPF_F_BPRM_SECUREEXEC
     58
     59BPF_CALL_2(bpf_bprm_opts_set, struct linux_binprm *, bprm, u64, flags)
     60{
     61	if (flags & ~BPF_F_BRPM_OPTS_MASK)
     62		return -EINVAL;
     63
     64	bprm->secureexec = (flags & BPF_F_BPRM_SECUREEXEC);
     65	return 0;
     66}
     67
     68BTF_ID_LIST_SINGLE(bpf_bprm_opts_set_btf_ids, struct, linux_binprm)
     69
     70static const struct bpf_func_proto bpf_bprm_opts_set_proto = {
     71	.func		= bpf_bprm_opts_set,
     72	.gpl_only	= false,
     73	.ret_type	= RET_INTEGER,
     74	.arg1_type	= ARG_PTR_TO_BTF_ID,
     75	.arg1_btf_id	= &bpf_bprm_opts_set_btf_ids[0],
     76	.arg2_type	= ARG_ANYTHING,
     77};
     78
     79BPF_CALL_3(bpf_ima_inode_hash, struct inode *, inode, void *, dst, u32, size)
     80{
     81	return ima_inode_hash(inode, dst, size);
     82}
     83
     84static bool bpf_ima_inode_hash_allowed(const struct bpf_prog *prog)
     85{
     86	return bpf_lsm_is_sleepable_hook(prog->aux->attach_btf_id);
     87}
     88
     89BTF_ID_LIST_SINGLE(bpf_ima_inode_hash_btf_ids, struct, inode)
     90
     91static const struct bpf_func_proto bpf_ima_inode_hash_proto = {
     92	.func		= bpf_ima_inode_hash,
     93	.gpl_only	= false,
     94	.ret_type	= RET_INTEGER,
     95	.arg1_type	= ARG_PTR_TO_BTF_ID,
     96	.arg1_btf_id	= &bpf_ima_inode_hash_btf_ids[0],
     97	.arg2_type	= ARG_PTR_TO_UNINIT_MEM,
     98	.arg3_type	= ARG_CONST_SIZE,
     99	.allowed	= bpf_ima_inode_hash_allowed,
    100};
    101
    102BPF_CALL_3(bpf_ima_file_hash, struct file *, file, void *, dst, u32, size)
    103{
    104	return ima_file_hash(file, dst, size);
    105}
    106
    107BTF_ID_LIST_SINGLE(bpf_ima_file_hash_btf_ids, struct, file)
    108
    109static const struct bpf_func_proto bpf_ima_file_hash_proto = {
    110	.func		= bpf_ima_file_hash,
    111	.gpl_only	= false,
    112	.ret_type	= RET_INTEGER,
    113	.arg1_type	= ARG_PTR_TO_BTF_ID,
    114	.arg1_btf_id	= &bpf_ima_file_hash_btf_ids[0],
    115	.arg2_type	= ARG_PTR_TO_UNINIT_MEM,
    116	.arg3_type	= ARG_CONST_SIZE,
    117	.allowed	= bpf_ima_inode_hash_allowed,
    118};
    119
    120BPF_CALL_1(bpf_get_attach_cookie, void *, ctx)
    121{
    122	struct bpf_trace_run_ctx *run_ctx;
    123
    124	run_ctx = container_of(current->bpf_ctx, struct bpf_trace_run_ctx, run_ctx);
    125	return run_ctx->bpf_cookie;
    126}
    127
    128static const struct bpf_func_proto bpf_get_attach_cookie_proto = {
    129	.func		= bpf_get_attach_cookie,
    130	.gpl_only	= false,
    131	.ret_type	= RET_INTEGER,
    132	.arg1_type	= ARG_PTR_TO_CTX,
    133};
    134
    135static const struct bpf_func_proto *
    136bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    137{
    138	switch (func_id) {
    139	case BPF_FUNC_inode_storage_get:
    140		return &bpf_inode_storage_get_proto;
    141	case BPF_FUNC_inode_storage_delete:
    142		return &bpf_inode_storage_delete_proto;
    143#ifdef CONFIG_NET
    144	case BPF_FUNC_sk_storage_get:
    145		return &bpf_sk_storage_get_proto;
    146	case BPF_FUNC_sk_storage_delete:
    147		return &bpf_sk_storage_delete_proto;
    148#endif /* CONFIG_NET */
    149	case BPF_FUNC_spin_lock:
    150		return &bpf_spin_lock_proto;
    151	case BPF_FUNC_spin_unlock:
    152		return &bpf_spin_unlock_proto;
    153	case BPF_FUNC_bprm_opts_set:
    154		return &bpf_bprm_opts_set_proto;
    155	case BPF_FUNC_ima_inode_hash:
    156		return prog->aux->sleepable ? &bpf_ima_inode_hash_proto : NULL;
    157	case BPF_FUNC_ima_file_hash:
    158		return prog->aux->sleepable ? &bpf_ima_file_hash_proto : NULL;
    159	case BPF_FUNC_get_attach_cookie:
    160		return bpf_prog_has_trampoline(prog) ? &bpf_get_attach_cookie_proto : NULL;
    161	default:
    162		return tracing_prog_func_proto(func_id, prog);
    163	}
    164}
    165
    166/* The set of hooks which are called without pagefaults disabled and are allowed
    167 * to "sleep" and thus can be used for sleepable BPF programs.
    168 */
    169BTF_SET_START(sleepable_lsm_hooks)
    170BTF_ID(func, bpf_lsm_bpf)
    171BTF_ID(func, bpf_lsm_bpf_map)
    172BTF_ID(func, bpf_lsm_bpf_map_alloc_security)
    173BTF_ID(func, bpf_lsm_bpf_map_free_security)
    174BTF_ID(func, bpf_lsm_bpf_prog)
    175BTF_ID(func, bpf_lsm_bprm_check_security)
    176BTF_ID(func, bpf_lsm_bprm_committed_creds)
    177BTF_ID(func, bpf_lsm_bprm_committing_creds)
    178BTF_ID(func, bpf_lsm_bprm_creds_for_exec)
    179BTF_ID(func, bpf_lsm_bprm_creds_from_file)
    180BTF_ID(func, bpf_lsm_capget)
    181BTF_ID(func, bpf_lsm_capset)
    182BTF_ID(func, bpf_lsm_cred_prepare)
    183BTF_ID(func, bpf_lsm_file_ioctl)
    184BTF_ID(func, bpf_lsm_file_lock)
    185BTF_ID(func, bpf_lsm_file_open)
    186BTF_ID(func, bpf_lsm_file_receive)
    187
    188#ifdef CONFIG_SECURITY_NETWORK
    189BTF_ID(func, bpf_lsm_inet_conn_established)
    190#endif /* CONFIG_SECURITY_NETWORK */
    191
    192BTF_ID(func, bpf_lsm_inode_create)
    193BTF_ID(func, bpf_lsm_inode_free_security)
    194BTF_ID(func, bpf_lsm_inode_getattr)
    195BTF_ID(func, bpf_lsm_inode_getxattr)
    196BTF_ID(func, bpf_lsm_inode_mknod)
    197BTF_ID(func, bpf_lsm_inode_need_killpriv)
    198BTF_ID(func, bpf_lsm_inode_post_setxattr)
    199BTF_ID(func, bpf_lsm_inode_readlink)
    200BTF_ID(func, bpf_lsm_inode_rename)
    201BTF_ID(func, bpf_lsm_inode_rmdir)
    202BTF_ID(func, bpf_lsm_inode_setattr)
    203BTF_ID(func, bpf_lsm_inode_setxattr)
    204BTF_ID(func, bpf_lsm_inode_symlink)
    205BTF_ID(func, bpf_lsm_inode_unlink)
    206BTF_ID(func, bpf_lsm_kernel_module_request)
    207BTF_ID(func, bpf_lsm_kernel_read_file)
    208BTF_ID(func, bpf_lsm_kernfs_init_security)
    209
    210#ifdef CONFIG_KEYS
    211BTF_ID(func, bpf_lsm_key_free)
    212#endif /* CONFIG_KEYS */
    213
    214BTF_ID(func, bpf_lsm_mmap_file)
    215BTF_ID(func, bpf_lsm_netlink_send)
    216BTF_ID(func, bpf_lsm_path_notify)
    217BTF_ID(func, bpf_lsm_release_secctx)
    218BTF_ID(func, bpf_lsm_sb_alloc_security)
    219BTF_ID(func, bpf_lsm_sb_eat_lsm_opts)
    220BTF_ID(func, bpf_lsm_sb_kern_mount)
    221BTF_ID(func, bpf_lsm_sb_mount)
    222BTF_ID(func, bpf_lsm_sb_remount)
    223BTF_ID(func, bpf_lsm_sb_set_mnt_opts)
    224BTF_ID(func, bpf_lsm_sb_show_options)
    225BTF_ID(func, bpf_lsm_sb_statfs)
    226BTF_ID(func, bpf_lsm_sb_umount)
    227BTF_ID(func, bpf_lsm_settime)
    228
    229#ifdef CONFIG_SECURITY_NETWORK
    230BTF_ID(func, bpf_lsm_socket_accept)
    231BTF_ID(func, bpf_lsm_socket_bind)
    232BTF_ID(func, bpf_lsm_socket_connect)
    233BTF_ID(func, bpf_lsm_socket_create)
    234BTF_ID(func, bpf_lsm_socket_getpeername)
    235BTF_ID(func, bpf_lsm_socket_getpeersec_dgram)
    236BTF_ID(func, bpf_lsm_socket_getsockname)
    237BTF_ID(func, bpf_lsm_socket_getsockopt)
    238BTF_ID(func, bpf_lsm_socket_listen)
    239BTF_ID(func, bpf_lsm_socket_post_create)
    240BTF_ID(func, bpf_lsm_socket_recvmsg)
    241BTF_ID(func, bpf_lsm_socket_sendmsg)
    242BTF_ID(func, bpf_lsm_socket_shutdown)
    243BTF_ID(func, bpf_lsm_socket_socketpair)
    244#endif /* CONFIG_SECURITY_NETWORK */
    245
    246BTF_ID(func, bpf_lsm_syslog)
    247BTF_ID(func, bpf_lsm_task_alloc)
    248BTF_ID(func, bpf_lsm_current_getsecid_subj)
    249BTF_ID(func, bpf_lsm_task_getsecid_obj)
    250BTF_ID(func, bpf_lsm_task_prctl)
    251BTF_ID(func, bpf_lsm_task_setscheduler)
    252BTF_ID(func, bpf_lsm_task_to_inode)
    253BTF_SET_END(sleepable_lsm_hooks)
    254
    255bool bpf_lsm_is_sleepable_hook(u32 btf_id)
    256{
    257	return btf_id_set_contains(&sleepable_lsm_hooks, btf_id);
    258}
    259
    260const struct bpf_prog_ops lsm_prog_ops = {
    261};
    262
    263const struct bpf_verifier_ops lsm_verifier_ops = {
    264	.get_func_proto = bpf_lsm_func_proto,
    265	.is_valid_access = btf_ctx_access,
    266};