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