Program type BPF_PROG_TYPE_LSM
BPF_PROG_TYPE_LSM
are eBPF programs that can attach to LSM (Linux Security Module) hooks. These are the same hooks as used by programs such as SELinux and AppArmor.
Usage
The primary use case is to implement security software. For example, the socket_create
hook is called when a process calls the socket
syscall, if the eBPF program returns 0
the socket is allowed to be created, but the eBPF program can also return an error value to block the socket creation.
The list of all LSM hooks can be found in lsm_hook_defs.h
, additional documentation for these hooks lives in lsm_hooks.h
// Copyright (C) 2020 Google LLC.
SEC("lsm/file_mprotect")
int BPF_PROG(mprotect_audit, struct vm_area_struct *vma,
unsigned long reqprot, unsigned long prot, int ret)
{
/* ret is the return value from the previous BPF program
* or 0 if it's the first hook.
*/
if (ret != 0)
return ret;
int is_heap;
is_heap = (vma->vm_start >= vma->vm_mm->start_brk &&
vma->vm_end <= vma->vm_mm->brk);
/* Return an -EPERM or write information to the perf events buffer
* for auditing
*/
if (is_heap)
return -EPERM;
}
Context
LSM programs are invoked with an array of __u64
values equal in length to the amount of arguments of the LSM hook, each index representing the arguments in order. The BPF_PROG
macro defined in tools/lib/bpf/bpf_tracing.h
is often used to make it easier to write LSM programs. The macro allows the user to write the arguments as declared on the hooks, the macro will cast the arguments. The actual arguments and their times are determined by the hook to which this program is attached.
Attachment
LSM programs are exclusively attached via bpf links. To do so the program must be loaded with the BPF_LSM_MAC
expected attach type and use it as the parameter to attach_type
. The target_btf_id
parameter must be populated with the BTF ID of the LSM hook point which can be extracted from the SELinux BTF on the system.
Docs could be improved
This part of the docs is incomplete, contributions are very welcome
Helper functions
Not all helper functions are available in all program types. These are the helper calls available for LSM programs:
Supported helper functions
bpf_inode_storage_get
bpf_inode_storage_delete
bpf_sk_storage_get
bpf_sk_storage_delete
bpf_spin_lock
bpf_spin_unlock
bpf_bprm_opts_set
bpf_ima_inode_hash
bpf_ima_file_hash
bpf_setsockopt
v6.0bpf_getsockopt
v6.0bpf_get_attach_cookie
v5.19bpf_map_lookup_elem
bpf_map_update_elem
bpf_map_delete_elem
bpf_map_push_elem
bpf_map_pop_elem
bpf_map_peek_elem
bpf_map_lookup_percpu_elem
bpf_ktime_get_ns
bpf_ktime_get_boot_ns
bpf_tail_call
bpf_get_current_pid_tgid
bpf_get_current_task
bpf_get_current_task_btf
bpf_task_pt_regs
bpf_get_current_uid_gid
bpf_get_current_comm
bpf_trace_printk
bpf_get_smp_processor_id
bpf_get_numa_node_id
bpf_perf_event_read
bpf_current_task_under_cgroup
bpf_get_prandom_u32
bpf_probe_write_user
bpf_probe_read_user
bpf_probe_read_kernel
bpf_probe_read_user_str
bpf_probe_read_kernel_str
bpf_probe_read
bpf_probe_read_str
bpf_get_current_cgroup_id
bpf_get_current_ancestor_cgroup_id
bpf_send_signal
bpf_send_signal_thread
bpf_perf_event_read_value
bpf_get_ns_current_pid_tgid
bpf_ringbuf_output
bpf_ringbuf_reserve
bpf_ringbuf_submit
bpf_ringbuf_discard
bpf_ringbuf_query
bpf_jiffies64
bpf_get_task_stack
bpf_copy_from_user
bpf_copy_from_user_task
bpf_snprintf_btf
bpf_per_cpu_ptr
bpf_this_cpu_ptr
bpf_task_storage_get
bpf_task_storage_delete
bpf_for_each_map_elem
bpf_snprintf
bpf_get_func_ip
bpf_get_branch_snapshot
bpf_find_vma
bpf_trace_vprintk
bpf_map_lookup_elem
bpf_map_update_elem
bpf_map_delete_elem
bpf_map_push_elem
bpf_map_pop_elem
bpf_map_peek_elem
bpf_map_lookup_percpu_elem
bpf_get_prandom_u32
bpf_get_smp_processor_id
bpf_get_numa_node_id
bpf_tail_call
bpf_ktime_get_ns
bpf_ktime_get_boot_ns
bpf_ringbuf_output
bpf_ringbuf_reserve
bpf_ringbuf_submit
bpf_ringbuf_discard
bpf_ringbuf_query
bpf_for_each_map_elem
bpf_loop
bpf_strncmp
bpf_spin_lock
bpf_spin_unlock
bpf_jiffies64
bpf_per_cpu_ptr
bpf_this_cpu_ptr
bpf_timer_init
bpf_timer_set_callback
bpf_timer_start
bpf_timer_cancel
bpf_trace_printk
bpf_get_current_task
bpf_get_current_task_btf
bpf_probe_read_user
bpf_probe_read_kernel
bpf_probe_read_user_str
bpf_probe_read_kernel_str
bpf_snprintf_btf
bpf_snprintf
bpf_task_pt_regs
bpf_trace_vprintk
bpf_cgrp_storage_get
bpf_cgrp_storage_delete
bpf_dynptr_data
bpf_dynptr_from_mem
bpf_dynptr_read
bpf_dynptr_write
bpf_kptr_xchg
bpf_ktime_get_tai_ns
bpf_ringbuf_discard_dynptr
bpf_ringbuf_reserve_dynptr
bpf_ringbuf_submit_dynptr
bpf_user_ringbuf_drain
KFuncs
Supported kfuncs
bpf_arena_alloc_pages
bpf_arena_free_pages
bpf_cast_to_kern_ctx
bpf_cgroup_acquire
bpf_cgroup_ancestor
bpf_cgroup_from_id
bpf_cgroup_release
bpf_cpumask_acquire
bpf_cpumask_and
bpf_cpumask_any_and_distribute
bpf_cpumask_any_distribute
bpf_cpumask_clear
bpf_cpumask_clear_cpu
bpf_cpumask_copy
bpf_cpumask_create
bpf_cpumask_empty
bpf_cpumask_equal
bpf_cpumask_first
bpf_cpumask_first_and
bpf_cpumask_first_zero
bpf_cpumask_full
bpf_cpumask_intersects
bpf_cpumask_or
bpf_cpumask_release
bpf_cpumask_set_cpu
bpf_cpumask_setall
bpf_cpumask_subset
bpf_cpumask_test_and_clear_cpu
bpf_cpumask_test_and_set_cpu
bpf_cpumask_test_cpu
bpf_cpumask_weight
bpf_cpumask_xor
bpf_dynptr_adjust
bpf_dynptr_clone
bpf_dynptr_is_null
bpf_dynptr_is_rdonly
bpf_dynptr_size
bpf_dynptr_slice
bpf_dynptr_slice_rdwr
bpf_get_file_xattr
bpf_get_fsverity_digest
bpf_iter_bits_destroy
bpf_iter_bits_new
bpf_iter_bits_next
bpf_iter_css_destroy
bpf_iter_css_new
bpf_iter_css_next
bpf_iter_css_task_destroy
bpf_iter_css_task_new
bpf_iter_css_task_next
bpf_iter_num_destroy
bpf_iter_num_new
bpf_iter_num_next
bpf_iter_task_destroy
bpf_iter_task_new
bpf_iter_task_next
bpf_iter_task_vma_destroy
bpf_iter_task_vma_new
bpf_iter_task_vma_next
bpf_list_pop_back
bpf_list_pop_front
bpf_list_push_back_impl
bpf_list_push_front_impl
bpf_map_sum_elem_count
bpf_obj_drop_impl
bpf_obj_new_impl
bpf_percpu_obj_drop_impl
bpf_percpu_obj_new_impl
bpf_preempt_disable
bpf_preempt_enable
bpf_rbtree_add_impl
bpf_rbtree_first
bpf_rbtree_remove
bpf_rcu_read_lock
bpf_rcu_read_unlock
bpf_rdonly_cast
bpf_refcount_acquire_impl
bpf_task_acquire
bpf_task_from_pid
bpf_task_get_cgroup1
bpf_task_release
bpf_task_under_cgroup
bpf_throw
bpf_wq_init
bpf_wq_set_callback_impl
bpf_wq_start
cgroup_rstat_flush
cgroup_rstat_updated
crash_kexec
hid_bpf_allocate_context
hid_bpf_get_data
hid_bpf_hw_output_report
hid_bpf_hw_request
hid_bpf_input_report
hid_bpf_release_context
hid_bpf_try_input_report