Practical eBPF Security: Auditing and Intercepting Privilege‑Escalation Operations

The article explains how attackers exploit SUID binaries for privilege escalation and demonstrates how to use eBPF LSM hooks (file_open, bprm_check_security) and Kprobe tracing to audit such operations, then shows how to block them by returning error codes while exempting root users.

Linux Code Review Hub
Linux Code Review Hub
Linux Code Review Hub
Practical eBPF Security: Auditing and Intercepting Privilege‑Escalation Operations

Attackers often gain higher privileges by executing SUID binaries. To detect and block these privilege‑escalation attempts, the article first shows how to identify SUID files by inspecting the i_mode field of the inode structure and provides a helper function is_suid_file() that checks both the regular file flag and the SUID bit.

Auditing with eBPF LSM

Using the file_open LSM hook, the program reads the inode of the opened file, calls is_suid_file(), and, if true, records the UID, PID, command name, file mode, and file path via bpf_perf_event_output. The key snippet is:

SEC("lsm/file_open")
int BPF_PROG(lsm_file_open, struct file *file) {
    struct event_t event = {};
    if (!is_suid_file(file))
        return 0;
    u32 uid = bpf_get_current_uid_gid();
    event.uid = uid;
    event.pid = bpf_get_current_pid_tgid() >> 32;
    bpf_get_current_comm(&event.comm, sizeof(event.comm));
    event.fmode = BPF_CORE_READ(file, f_mode);
    get_file_path(file, event.filename, sizeof(event.filename));
    bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));
    return 0;
}

Because file_open only sees the file being opened, the article also uses the bprm_check_security LSM hook, which triggers during execve. This hook provides access to the linux_binprm structure, allowing the same SUID check on the file about to be executed.

SEC("lsm/bprm_check_security")
int BPF_PROG(lsm_bprm_check_security, struct linux_binprm *bprm) {
    struct file *file = BPF_CORE_READ(bprm, file);
    if (!is_suid_file(file))
        return 0;
    // collect and emit event (uid, pid, comm, filename) similar to above
    return 0;
}

Auditing with eBPF Kprobe

When the kernel version is older than 5.7 or LSM is not enabled, the article shows an alternative using a Kprobe on the kernel function security_bprm_check. The probe extracts the same file pointer from the linux_binprm argument and reuses is_suid_file() to emit audit events.

SEC("kprobe/security_bprm_check")
int BPF_KPROBE(kprobe_security_bprm_check, struct linux_binprm *bprm) {
    struct file *file = BPF_CORE_READ(bprm, file);
    if (!is_suid_file(file))
        return 0;
    // emit event (uid, pid, comm, filename)
    return 0;
}

Intercepting Privilege‑Escalation

To block the escalation, the LSM program can return a non‑zero error from bprm_check_security. The article adds a check that allows root (UID 0) or root‑group users to pass, then returns -1 for other SUID executions, effectively preventing the execve.

SEC("lsm/bprm_check_security")
int BPF_PROG(lsm_bprm_check_security, struct linux_binprm *bprm) {
    // ... SUID check as before ...
    if (uid == 0 || gid == 0)
        return 0; // allow root
    return -1;    // block non‑root SUID exec
}

The article concludes that both LSM and Kprobe approaches can audit and intercept privilege‑escalation attempts, and points readers to the book "eBPF Cloud‑Native Security: Principles and Practice" for deeper exploration.

eBPFInterceptionprivilege escalationLSMLinux SecurityAuditingKprobe
Linux Code Review Hub
Written by

Linux Code Review Hub

A professional Linux technology community and learning platform covering the kernel, memory management, process management, file system and I/O, performance tuning, device drivers, virtualization, and cloud computing.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.