Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  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
102static const struct bpf_func_proto *
103bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
104{
105	switch (func_id) {
106	case BPF_FUNC_inode_storage_get:
107		return &bpf_inode_storage_get_proto;
108	case BPF_FUNC_inode_storage_delete:
109		return &bpf_inode_storage_delete_proto;
110#ifdef CONFIG_NET
111	case BPF_FUNC_sk_storage_get:
112		return &bpf_sk_storage_get_proto;
113	case BPF_FUNC_sk_storage_delete:
114		return &bpf_sk_storage_delete_proto;
115#endif /* CONFIG_NET */
116	case BPF_FUNC_spin_lock:
117		return &bpf_spin_lock_proto;
118	case BPF_FUNC_spin_unlock:
119		return &bpf_spin_unlock_proto;
120	case BPF_FUNC_bprm_opts_set:
121		return &bpf_bprm_opts_set_proto;
122	case BPF_FUNC_ima_inode_hash:
123		return prog->aux->sleepable ? &bpf_ima_inode_hash_proto : NULL;
124	default:
125		return tracing_prog_func_proto(func_id, prog);
126	}
127}
128
129/* The set of hooks which are called without pagefaults disabled and are allowed
130 * to "sleep" and thus can be used for sleepable BPF programs.
131 */
132BTF_SET_START(sleepable_lsm_hooks)
133BTF_ID(func, bpf_lsm_bpf)
134BTF_ID(func, bpf_lsm_bpf_map)
135BTF_ID(func, bpf_lsm_bpf_map_alloc_security)
136BTF_ID(func, bpf_lsm_bpf_map_free_security)
137BTF_ID(func, bpf_lsm_bpf_prog)
138BTF_ID(func, bpf_lsm_bprm_check_security)
139BTF_ID(func, bpf_lsm_bprm_committed_creds)
140BTF_ID(func, bpf_lsm_bprm_committing_creds)
141BTF_ID(func, bpf_lsm_bprm_creds_for_exec)
142BTF_ID(func, bpf_lsm_bprm_creds_from_file)
143BTF_ID(func, bpf_lsm_capget)
144BTF_ID(func, bpf_lsm_capset)
145BTF_ID(func, bpf_lsm_cred_prepare)
146BTF_ID(func, bpf_lsm_file_ioctl)
147BTF_ID(func, bpf_lsm_file_lock)
148BTF_ID(func, bpf_lsm_file_open)
149BTF_ID(func, bpf_lsm_file_receive)
150
151#ifdef CONFIG_SECURITY_NETWORK
152BTF_ID(func, bpf_lsm_inet_conn_established)
153#endif /* CONFIG_SECURITY_NETWORK */
154
155BTF_ID(func, bpf_lsm_inode_create)
156BTF_ID(func, bpf_lsm_inode_free_security)
157BTF_ID(func, bpf_lsm_inode_getattr)
158BTF_ID(func, bpf_lsm_inode_getxattr)
159BTF_ID(func, bpf_lsm_inode_mknod)
160BTF_ID(func, bpf_lsm_inode_need_killpriv)
161BTF_ID(func, bpf_lsm_inode_post_setxattr)
162BTF_ID(func, bpf_lsm_inode_readlink)
163BTF_ID(func, bpf_lsm_inode_rename)
164BTF_ID(func, bpf_lsm_inode_rmdir)
165BTF_ID(func, bpf_lsm_inode_setattr)
166BTF_ID(func, bpf_lsm_inode_setxattr)
167BTF_ID(func, bpf_lsm_inode_symlink)
168BTF_ID(func, bpf_lsm_inode_unlink)
169BTF_ID(func, bpf_lsm_kernel_module_request)
170BTF_ID(func, bpf_lsm_kernfs_init_security)
171
172#ifdef CONFIG_KEYS
173BTF_ID(func, bpf_lsm_key_free)
174#endif /* CONFIG_KEYS */
175
176BTF_ID(func, bpf_lsm_mmap_file)
177BTF_ID(func, bpf_lsm_netlink_send)
178BTF_ID(func, bpf_lsm_path_notify)
179BTF_ID(func, bpf_lsm_release_secctx)
180BTF_ID(func, bpf_lsm_sb_alloc_security)
181BTF_ID(func, bpf_lsm_sb_eat_lsm_opts)
182BTF_ID(func, bpf_lsm_sb_kern_mount)
183BTF_ID(func, bpf_lsm_sb_mount)
184BTF_ID(func, bpf_lsm_sb_remount)
185BTF_ID(func, bpf_lsm_sb_set_mnt_opts)
186BTF_ID(func, bpf_lsm_sb_show_options)
187BTF_ID(func, bpf_lsm_sb_statfs)
188BTF_ID(func, bpf_lsm_sb_umount)
189BTF_ID(func, bpf_lsm_settime)
190
191#ifdef CONFIG_SECURITY_NETWORK
192BTF_ID(func, bpf_lsm_socket_accept)
193BTF_ID(func, bpf_lsm_socket_bind)
194BTF_ID(func, bpf_lsm_socket_connect)
195BTF_ID(func, bpf_lsm_socket_create)
196BTF_ID(func, bpf_lsm_socket_getpeername)
197BTF_ID(func, bpf_lsm_socket_getpeersec_dgram)
198BTF_ID(func, bpf_lsm_socket_getsockname)
199BTF_ID(func, bpf_lsm_socket_getsockopt)
200BTF_ID(func, bpf_lsm_socket_listen)
201BTF_ID(func, bpf_lsm_socket_post_create)
202BTF_ID(func, bpf_lsm_socket_recvmsg)
203BTF_ID(func, bpf_lsm_socket_sendmsg)
204BTF_ID(func, bpf_lsm_socket_shutdown)
205BTF_ID(func, bpf_lsm_socket_socketpair)
206#endif /* CONFIG_SECURITY_NETWORK */
207
208BTF_ID(func, bpf_lsm_syslog)
209BTF_ID(func, bpf_lsm_task_alloc)
210BTF_ID(func, bpf_lsm_task_getsecid_subj)
211BTF_ID(func, bpf_lsm_task_getsecid_obj)
212BTF_ID(func, bpf_lsm_task_prctl)
213BTF_ID(func, bpf_lsm_task_setscheduler)
214BTF_ID(func, bpf_lsm_task_to_inode)
215BTF_SET_END(sleepable_lsm_hooks)
216
217bool bpf_lsm_is_sleepable_hook(u32 btf_id)
218{
219	return btf_id_set_contains(&sleepable_lsm_hooks, btf_id);
220}
221
222const struct bpf_prog_ops lsm_prog_ops = {
223};
224
225const struct bpf_verifier_ops lsm_verifier_ops = {
226	.get_func_proto = bpf_lsm_func_proto,
227	.is_valid_access = btf_ctx_access,
228};