prog_lsm.rst 4.5 KB

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