Merge tag 'block-5.13-2021-05-14' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / Documentation / bpf / bpf_lsm.rst
1 .. SPDX-License-Identifier: GPL-2.0+
2 .. Copyright (C) 2020 Google LLC.
3
4 ================
5 LSM BPF Programs
6 ================
7
8 These BPF programs allow runtime instrumentation of the LSM hooks by privileged
9 users to implement system-wide MAC (Mandatory Access Control) and Audit
10 policies using eBPF.
11
12 Structure
13 ---------
14
15 The example shows an eBPF program that can be attached to the ``file_mprotect``
16 LSM hook:
17
18 .. c:function:: int file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, unsigned long prot);
19
20 Other LSM hooks which can be instrumented can be found in
21 ``include/linux/lsm_hooks.h``.
22
23 eBPF programs that use :doc:`/bpf/btf` do not need to include kernel headers
24 for accessing information from the attached eBPF program's context. They can
25 simply declare the structures in the eBPF program and only specify the fields
26 that 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
43 This can be further simplified (if one has access to the BTF information at
44 build 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
54 The ``vmlinux.h`` can then simply be included in the BPF programs without
55 requiring the definition of the types.
56
57 The eBPF programs can be declared using the``BPF_PROG``
58 macros defined in `tools/lib/bpf/bpf_tracing.h`_. In this
59 example:
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
89 The ``__attribute__((preserve_access_index))`` is a clang feature that allows
90 the 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
92 also validates all the accesses made to the various types in the eBPF program.
93
94 Loading
95 -------
96
97 eBPF 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
107 This 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
113 and the program can be loaded by including ``my_prog.skel.h`` and using
114 the generated helper, ``my_prog__open_and_load``.
115
116 Attachment to LSM Hooks
117 -----------------------
118
119 The LSM allows attachment of eBPF programs as LSM hooks using :manpage:`bpf(2)`
120 syscall's ``BPF_RAW_TRACEPOINT_OPEN`` operation or more simply by
121 using the libbpf helper ``bpf_program__attach_lsm``.
122
123 The program can be detached from the LSM hook by *destroying* the ``link``
124 link returned by ``bpf_program__attach_lsm`` using ``bpf_link__destroy``.
125
126 One 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
129 Examples
130 --------
131
132 An example eBPF program can be found in
133 `tools/testing/selftests/bpf/progs/lsm.c`_ and the corresponding
134 userspace 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