xref: /openbmc/linux/kernel/bpf/bpf_lsm.c (revision 592a3498)
1fc611f47SKP Singh // SPDX-License-Identifier: GPL-2.0
2fc611f47SKP Singh 
3fc611f47SKP Singh /*
4fc611f47SKP Singh  * Copyright (C) 2020 Google LLC.
5fc611f47SKP Singh  */
6fc611f47SKP Singh 
7fc611f47SKP Singh #include <linux/filter.h>
8fc611f47SKP Singh #include <linux/bpf.h>
9fc611f47SKP Singh #include <linux/btf.h>
109d3fdea7SKP Singh #include <linux/lsm_hooks.h>
119d3fdea7SKP Singh #include <linux/bpf_lsm.h>
129e4e01dfSKP Singh #include <linux/kallsyms.h>
139e4e01dfSKP Singh #include <linux/bpf_verifier.h>
1430897832SKP Singh #include <net/bpf_sk_storage.h>
1530897832SKP Singh #include <linux/bpf_local_storage.h>
169d3fdea7SKP Singh 
179d3fdea7SKP Singh /* For every LSM hook that allows attachment of BPF programs, declare a nop
189d3fdea7SKP Singh  * function where a BPF program can be attached.
199d3fdea7SKP Singh  */
209d3fdea7SKP Singh #define LSM_HOOK(RET, DEFAULT, NAME, ...)	\
219d3fdea7SKP Singh noinline RET bpf_lsm_##NAME(__VA_ARGS__)	\
229d3fdea7SKP Singh {						\
239d3fdea7SKP Singh 	return DEFAULT;				\
249d3fdea7SKP Singh }
259d3fdea7SKP Singh 
269d3fdea7SKP Singh #include <linux/lsm_hook_defs.h>
279d3fdea7SKP Singh #undef LSM_HOOK
28fc611f47SKP Singh 
299e4e01dfSKP Singh #define BPF_LSM_SYM_PREFX  "bpf_lsm_"
309e4e01dfSKP Singh 
319e4e01dfSKP Singh int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog,
329e4e01dfSKP Singh 			const struct bpf_prog *prog)
339e4e01dfSKP Singh {
349e4e01dfSKP Singh 	if (!prog->gpl_compatible) {
359e4e01dfSKP Singh 		bpf_log(vlog,
369e4e01dfSKP Singh 			"LSM programs must have a GPL compatible license\n");
379e4e01dfSKP Singh 		return -EINVAL;
389e4e01dfSKP Singh 	}
399e4e01dfSKP Singh 
409e4e01dfSKP Singh 	if (strncmp(BPF_LSM_SYM_PREFX, prog->aux->attach_func_name,
419e4e01dfSKP Singh 		    sizeof(BPF_LSM_SYM_PREFX) - 1)) {
429e4e01dfSKP Singh 		bpf_log(vlog, "attach_btf_id %u points to wrong type name %s\n",
439e4e01dfSKP Singh 			prog->aux->attach_btf_id, prog->aux->attach_func_name);
449e4e01dfSKP Singh 		return -EINVAL;
459e4e01dfSKP Singh 	}
469e4e01dfSKP Singh 
479e4e01dfSKP Singh 	return 0;
489e4e01dfSKP Singh }
499e4e01dfSKP Singh 
5030897832SKP Singh static const struct bpf_func_proto *
5130897832SKP Singh bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
5230897832SKP Singh {
5330897832SKP Singh 	switch (func_id) {
5430897832SKP Singh 	case BPF_FUNC_inode_storage_get:
5530897832SKP Singh 		return &bpf_inode_storage_get_proto;
5630897832SKP Singh 	case BPF_FUNC_inode_storage_delete:
5730897832SKP Singh 		return &bpf_inode_storage_delete_proto;
5830897832SKP Singh 	case BPF_FUNC_sk_storage_get:
59592a3498SMartin KaFai Lau 		return &bpf_sk_storage_get_proto;
6030897832SKP Singh 	case BPF_FUNC_sk_storage_delete:
61592a3498SMartin KaFai Lau 		return &bpf_sk_storage_delete_proto;
6230897832SKP Singh 	default:
6330897832SKP Singh 		return tracing_prog_func_proto(func_id, prog);
6430897832SKP Singh 	}
6530897832SKP Singh }
6630897832SKP Singh 
67fc611f47SKP Singh const struct bpf_prog_ops lsm_prog_ops = {
68fc611f47SKP Singh };
69fc611f47SKP Singh 
70fc611f47SKP Singh const struct bpf_verifier_ops lsm_verifier_ops = {
7130897832SKP Singh 	.get_func_proto = bpf_lsm_func_proto,
72fc611f47SKP Singh 	.is_valid_access = btf_ctx_access,
73fc611f47SKP Singh };
74