Production-ready eBPF-based security monitoring tool for detecting io_uring abuse on Linux systems
The io_uring Security Monitor is an advanced eBPF-based detection system designed to identify and alert on potential abuse of the Linux io_uring subsystem for defense evasion. This technique, publicly disclosed in April 2025 by ARMO, allows malware to bypass traditional syscall-based security monitoring tools.
The monitor uses a layered detection approach:
- Primary Detection:
sys_enter_io_uring_setuptracepoint monitors all io_uring initialization - Secondary Detection (Optional): LSM hooks (
file_open,socket_create) detect I/O operations by processes using io_uring - Fallback Detection: Kprobe on
__x64_sys_io_uring_setupfor older kernels without tracepoint support
Process calls io_uring_setup
|
v
eBPF Tracepoint Triggers
|
v
Check Allowlist
|
Not Allowed?
|
v
Generate Alert Event
|
v
Ring Buffer → Userspace
|
v
JSON/Text Output → Elastic/Syslog
- Linux Kernel: 5.7+ (for LSM BPF support)
- Kernel 5.1+ required for io_uring support
- Recommended: 5.19+ for full auditd io_uring support
- Kernel Configuration:
CONFIG_BPF=y CONFIG_BPF_SYSCALL=y CONFIG_BPF_LSM=y # Required for LSM hooks CONFIG_DEBUG_INFO_BTF=y # Required for CO-RE CONFIG_DEBUG_INFO_BTF_MODULES=y
- clang/llvm 10+
- bpftool
- libbpf-dev (>= 0.7.0)
- libjson-c-dev
- libelf-dev
- zlib1g-dev
- linux-headers
sudo apt-get update
sudo apt-get install -y \
clang \
llvm \
libbpf-dev \
libjson-c-dev \
libelf-dev \
zlib1g-dev \
linux-tools-common \
linux-tools-$(uname -r) \
linux-headers-$(uname -r)# Clone or extract the project
cd io_uring_monitor
# Build
make
# The binary will be at: build/io_uring_monitorMonitor only io_uring_setup syscalls:
sudo ./build/io_uring_monitorsudo ./build/io_uring_monitor \
-j \
-o /var/log/io_uring_monitor.jsonsudo make install
sudo systemctl enable --now io_uring_monitor
sudo systemctl status io_uring_monitorsudo ./build/io_uring_monitor \
--file-ops \
--socket-ops \
--json \
--output /var/log/io_uring_monitor.jsonsudo ./build/io_uring_monitor \
--daemon \
--syslog# Create allowlist file with PIDs (one per line)
echo "1234" > /etc/io_uring_allowlist.txt
echo "5678" >> /etc/io_uring_allowlist.txt
sudo ./build/io_uring_monitor \
--allowlist /etc/io_uring_allowlist.txt \
--jsonUsage: io_uring_monitor [OPTIONS]
Options:
-f, --file-ops Monitor file operations via io_uring (LSM hooks)
-s, --socket-ops Monitor socket operations via io_uring (LSM hooks)
-a, --allowlist FILE Load PID allowlist from FILE
-o, --output FILE Write events to FILE instead of stdout
-j, --json Output events in JSON format
-S, --syslog Send events to syslog
-d, --daemon Run as daemon
-v, --verbose Verbose output
-h, --help Show help
[2025-11-13 12:45:23] ALERT: io_uring activity detected | event=io_uring_setup pid=12345 tid=12345 uid=0 comm=malware parent_pid=1234 parent_comm=bash cgroup_id=1234567890 | entries=128 flags=0x0
{
"timestamp": "2025-11-13T12:45:23",
"timestamp_ns": 1731502523000000000,
"process": {
"pid": 12345,
"tid": 12345,
"uid": 0,
"gid": 0,
"comm": "malware",
"parent_pid": 1234,
"parent_comm": "bash",
"cgroup_id": 1234567890
},
"event": {
"type": "io_uring_setup",
"entries": 128,
"flags": 0
}
}Install as a system service:
sudo make install
sudo systemctl enable io_uring_monitor
sudo systemctl start io_uring_monitor
sudo systemctl status io_uring_monitorThe service is configured to:
- Run as root (required for eBPF)
- Start automatically at boot
- Restart on failure
- Log to syslog and
/var/log/io_uring_monitor.json
[Unit]
Description=io_uring Security Monitor
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/io_uring_monitor -d -S -j -o /var/log/io_uring_monitor.json
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.targetError: Failed to load BPF skeleton: -2
Solution: Check kernel configuration and LSM BPF support:
# Verify BTF is available
ls -la /sys/kernel/btf/vmlinux
# Check BPF LSM support
cat /sys/kernel/security/lsm | grep bpf
# View kernel logs
sudo dmesg | grep -i bpfSolution: Disable file/socket monitoring or use allowlists:
# Default low-overhead mode
sudo ./io_uring_monitor
# Add busy processes to allowlist
echo "$(pidof nginx)" >> /etc/io_uring_allowlist.txtThis is a reference implementation for educational and security research purposes. Contributions for:
- Additional detection heuristics
- Performance optimizations
- Integration with other security tools
are welcome.
GPL v2.0 - See LICENSE file