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