144 lines · plain
1.. SPDX-License-Identifier: GPL-2.0+2.. Copyright (C) 2020 Google LLC.3 4================5LSM BPF Programs6================7 8These BPF programs allow runtime instrumentation of the LSM hooks by privileged9users to implement system-wide MAC (Mandatory Access Control) and Audit10policies using eBPF.11 12Structure13---------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 in21``security/security.c``.22 23eBPF programs that use Documentation/bpf/btf.rst do not need to include kernel24headers for accessing information from the attached eBPF program's context.25They can simply declare the structures in the eBPF program and only specify26the fields that need to be accessed.27 28.. code-block:: c29 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 at44build time) by generating the ``vmlinux.h`` with:45 46.. code-block:: console47 48 # bpftool btf dump file <path-to-btf-vmlinux> format c > vmlinux.h49 50.. note:: ``path-to-btf-vmlinux`` can be ``/sys/kernel/btf/vmlinux`` if the51 build environment matches the environment the BPF programs are52 deployed in.53 54The ``vmlinux.h`` can then simply be included in the BPF programs without55requiring 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 this59example:60 61 * ``"lsm/file_mprotect"`` indicates the LSM hook that the program must62 be attached to63 * ``mprotect_audit`` is the name of the eBPF program64 65.. code-block:: c66 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 program72 * 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 buffer83 * for auditing84 */85 if (is_heap)86 return -EPERM;87 }88 89The ``__attribute__((preserve_access_index))`` is a clang feature that allows90the BPF verifier to update the offsets for the access at runtime using the91Documentation/bpf/btf.rst information. Since the BPF verifier is aware of the92types, it also validates all the accesses made to the various types in the93eBPF program.94 95Loading96-------97 98eBPF programs can be loaded with the :manpage:`bpf(2)` syscall's99``BPF_PROG_LOAD`` operation:100 101.. code-block:: c102 103 struct bpf_object *obj;104 105 obj = bpf_object__open("./my_prog.o");106 bpf_object__load(obj);107 108This can be simplified by using a skeleton header generated by ``bpftool``:109 110.. code-block:: console111 112 # bpftool gen skeleton my_prog.o > my_prog.skel.h113 114and the program can be loaded by including ``my_prog.skel.h`` and using115the generated helper, ``my_prog__open_and_load``.116 117Attachment to LSM Hooks118-----------------------119 120The LSM allows attachment of eBPF programs as LSM hooks using :manpage:`bpf(2)`121syscall's ``BPF_RAW_TRACEPOINT_OPEN`` operation or more simply by122using the libbpf helper ``bpf_program__attach_lsm``.123 124The program can be detached from the LSM hook by *destroying* the ``link``125link returned by ``bpf_program__attach_lsm`` using ``bpf_link__destroy``.126 127One can also use the helpers generated in ``my_prog.skel.h`` i.e.128``my_prog__attach`` for attachment and ``my_prog__destroy`` for cleaning up.129 130Examples131--------132 133An example eBPF program can be found in134`tools/testing/selftests/bpf/progs/lsm.c`_ and the corresponding135userspace code in `tools/testing/selftests/bpf/prog_tests/test_lsm.c`_136 137.. Links138.. _tools/lib/bpf/bpf_tracing.h:139 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/lib/bpf/bpf_tracing.h140.. _tools/testing/selftests/bpf/progs/lsm.c:141 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/testing/selftests/bpf/progs/lsm.c142.. _tools/testing/selftests/bpf/prog_tests/test_lsm.c:143 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/testing/selftests/bpf/prog_tests/test_lsm.c144