1.. SPDX-License-Identifier: GPL-2.0+ 2.. Copyright (C) 2020 Google LLC. 3 4================ 5LSM BPF Programs 6================ 7 8These BPF programs allow runtime instrumentation of the LSM hooks by privileged 9users to implement system-wide MAC (Mandatory Access Control) and Audit 10policies using eBPF. 11 12Structure 13--------- 14 15The example shows an eBPF program that can be attached to the ``file_mprotect`` 16LSM hook: 17 18.. c:function:: int file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, unsigned long prot); 19 20Other LSM hooks which can be instrumented can be found in 21``include/linux/lsm_hooks.h``. 22 23eBPF programs that use :doc:`/bpf/btf` do not need to include kernel headers 24for accessing information from the attached eBPF program's context. They can 25simply declare the structures in the eBPF program and only specify the fields 26that need to be accessed. 27 28.. code-block:: c 29 30 struct mm_struct { 31 unsigned long start_brk, brk, start_stack; 32 } __attribute__((preserve_access_index)); 33 34 struct vm_area_struct { 35 unsigned long start_brk, brk, start_stack; 36 unsigned long vm_start, vm_end; 37 struct mm_struct *vm_mm; 38 } __attribute__((preserve_access_index)); 39 40 41.. note:: The order of the fields is irrelevant. 42 43This can be further simplified (if one has access to the BTF information at 44build time) by generating the ``vmlinux.h`` with: 45 46.. code-block:: console 47 48 # bpftool btf dump file <path-to-btf-vmlinux> format c > vmlinux.h 49 50.. note:: ``path-to-btf-vmlinux`` can be ``/sys/kernel/btf/vmlinux`` if the 51 build environment matches the environment the BPF programs are 52 deployed in. 53 54The ``vmlinux.h`` can then simply be included in the BPF programs without 55requiring the definition of the types. 56 57The eBPF programs can be declared using the``BPF_PROG`` 58macros defined in `tools/lib/bpf/bpf_tracing.h`_. In this 59example: 60 61 * ``"lsm/file_mprotect"`` indicates the LSM hook that the program must 62 be attached to 63 * ``mprotect_audit`` is the name of the eBPF program 64 65.. code-block:: c 66 67 SEC("lsm/file_mprotect") 68 int BPF_PROG(mprotect_audit, struct vm_area_struct *vma, 69 unsigned long reqprot, unsigned long prot, int ret) 70 { 71 /* ret is the return value from the previous BPF program 72 * or 0 if it's the first hook. 73 */ 74 if (ret != 0) 75 return ret; 76 77 int is_heap; 78 79 is_heap = (vma->vm_start >= vma->vm_mm->start_brk && 80 vma->vm_end <= vma->vm_mm->brk); 81 82 /* Return an -EPERM or write information to the perf events buffer 83 * for auditing 84 */ 85 if (is_heap) 86 return -EPERM; 87 } 88 89The ``__attribute__((preserve_access_index))`` is a clang feature that allows 90the BPF verifier to update the offsets for the access at runtime using the 91:doc:`/bpf/btf` information. Since the BPF verifier is aware of the types, it 92also validates all the accesses made to the various types in the eBPF program. 93 94Loading 95------- 96 97eBPF programs can be loaded with the :manpage:`bpf(2)` syscall's 98``BPF_PROG_LOAD`` operation: 99 100.. code-block:: c 101 102 struct bpf_object *obj; 103 104 obj = bpf_object__open("./my_prog.o"); 105 bpf_object__load(obj); 106 107This can be simplified by using a skeleton header generated by ``bpftool``: 108 109.. code-block:: console 110 111 # bpftool gen skeleton my_prog.o > my_prog.skel.h 112 113and the program can be loaded by including ``my_prog.skel.h`` and using 114the generated helper, ``my_prog__open_and_load``. 115 116Attachment to LSM Hooks 117----------------------- 118 119The LSM allows attachment of eBPF programs as LSM hooks using :manpage:`bpf(2)` 120syscall's ``BPF_RAW_TRACEPOINT_OPEN`` operation or more simply by 121using the libbpf helper ``bpf_program__attach_lsm``. 122 123The program can be detached from the LSM hook by *destroying* the ``link`` 124link returned by ``bpf_program__attach_lsm`` using ``bpf_link__destroy``. 125 126One can also use the helpers generated in ``my_prog.skel.h`` i.e. 127``my_prog__attach`` for attachment and ``my_prog__destroy`` for cleaning up. 128 129Examples 130-------- 131 132An example eBPF program can be found in 133`tools/testing/selftests/bpf/progs/lsm.c`_ and the corresponding 134userspace code in `tools/testing/selftests/bpf/prog_tests/test_lsm.c`_ 135 136.. Links 137.. _tools/lib/bpf/bpf_tracing.h: 138 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/lib/bpf/bpf_tracing.h 139.. _tools/testing/selftests/bpf/progs/lsm.c: 140 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/testing/selftests/bpf/progs/lsm.c 141.. _tools/testing/selftests/bpf/prog_tests/test_lsm.c: 142 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/testing/selftests/bpf/prog_tests/test_lsm.c 143