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 param 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.0
- bpf_getsockopt v6.0
- 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_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
KFuncs
Supported kfuncs
- 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_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_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
- cgroup_rstat_flush
- cgroup_rstat_updated
- crash_kexec
- hid_bpf_get_data