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