You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用eBPF阻止文件打开?请明确方案适配uprobe/root probe

Got it, let's walk through exactly how to use eBPF to block access to a specific file when someone tries to open it via the open syscall, plus clear up the compatibility with uprobe/kprobe (I think you might have meant kprobe instead of "root probe"—I'll cover that too!).

核心实现思路

To block file access, we need to intercept the open/openat system calls (most modern apps use openat instead of raw open), check the target filename, and modify the syscall's return value to an error code if it matches our target file. We'll use kprobes (kernel function probes) for this since they let us hook into kernel-level syscalls globally.

Quick Prototype with BCC

BCC is a great tool for rapid eBPF development—it handles a lot of kernel compatibility boilerplate for us. Here's a working script:

from bcc import BPF
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("target_file", help="Full path or filename to block access to")
args = parser.parse_args()

bpf_program = """
#include <uapi/linux/ptrace.h>
#include <linux/fs.h>

// Hash map to store our target filename from user space
BPF_HASH(targets, char *, u32);

int block_open_call(struct pt_regs *ctx, const char __user *filename, int flags) {
    char fname_buf[256];
    u32 *is_target;

    // Safely copy the filename from user space to kernel space
    if (bpf_probe_read_user_str(fname_buf, sizeof(fname_buf), filename) < 0) {
        return 0;
    }

    // Check if this filename is in our target list
    is_target = targets.lookup(&fname_buf);
    if (is_target) {
        // Overwrite the syscall's return value with -EACCES (permission denied)
        // Note: This is x86_64-specific—adjust registers for ARM/RISC-V
        ctx->ax = -EACCES;
        // Return early to stop the original syscall from executing
        return 0;
    }

    return 0;
}
"""

# Initialize BPF and load our program
b = BPF(text=bpf_program)

# Hook into both sys_open and sys_openat (covers most use cases)
b.attach_kprobe(event="sys_open", fn_name="block_open_call")
b.attach_kprobe(event="sys_openat", fn_name="block_open_call")

# Push our target filename into the BPF hash map
b["targets"][args.target_file.encode()] = 1

print(f"🔒 Blocking access to {args.target_file}... Press Ctrl+C to exit.")

# Keep the script running to maintain the probe
b.trace_print()

How This Works

  • We attach kprobes to the entry points of the sys_open and sys_openat kernel functions.
  • The BPF program copies the filename from user space (since kernel can't directly access user memory safely) and checks if it's in our target list.
  • If it matches, we overwrite the syscall's return register (ax on x86_64) with -EACCES, so the calling process gets a "permission denied" error instead of opening the file.
Compatibility with Uprobe/Kprobe (and "Root Probe")

Let's break down which probe types fit this use case:

1. Kprobe (Kernel Probe)

  • Full compatibility: This is exactly what we used in the example. Kprobes hook into kernel functions, so they intercept every process that calls the open/openat syscall—perfect for global file blocking.
  • Pros: Covers all processes, no need to target specific apps.
  • Caveats: Kernel function names can vary slightly between versions (e.g., __x64_sys_open on newer kernels), but BCC automatically handles this mapping for you.

2. Uprobe (User-Space Probe)

  • Partial compatibility: Uprobes hook into user-space functions (like the open function in libc). They only intercept calls from specific processes or libraries, not all system-wide access.
  • When to use: If you only want to block a single app from opening the file (e.g., block cat from reading /etc/secret), uprobe works. But it's not suitable for global blocking.

"Root Probe" Clarification

I think you might have meant kprobe (since "root probe" isn't a standard eBPF term). If you're referring to kernel-level probes that require root privileges, yes—both kprobes and uprobes need root (or specific capabilities like CAP_BPF/CAP_PERFMON on kernel 5.8+) to attach.

Key Notes
  • Permissions: Run the script as root—eBPF kernel operations require elevated privileges.
  • Architecture: The example uses ctx->ax (x86_64's syscall return register). For ARM/RISC-V, use ctx->regs[0] instead.
  • Filename Matching: The script does exact matches. For fuzzy matching (e.g., block all files in /secret/), use bpf_strstr (requires kernel 5.10+) to check for substrings.
  • Kernel Version: Works on Linux 4.15+ (minimum for eBPF support), but newer kernels have better eBPF features.

内容的提问来源于stack exchange,提问作者Liroshka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 14:12:53