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

编写lsm/file_open eBPF程序时BPF验证器拒绝bpf_d_path参数的问题

问题:挂载lsm/file_open的eBPF程序被BPF验证器拒绝

我编写了一个挂载到lsm/file_open的eBPF示例程序,但加载时被BPF验证器拒绝,内核版本为6.8.0-51-generic。

我的eBPF程序代码

#include "vmlinux.h"
#include "commons.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>
#include <bpf/bpf_tracing.h>

#define MAX_SIZE        255

SEC("lsm/file_open")
int BPF_PROG(test_prog, struct file *file, int ret)
{
    unsigned int f_flags;
    struct path file_path;
    char path_buffer[MAX_SIZE];
    BPF_CORE_READ_INTO(&file_path, file, f_path);
    long err = bpf_d_path(&file_path, path_buffer, sizeof(path_buffer));
    return 0;
}

char LICENSE[] SEC("license") = "GPL";

BPF验证器输出

libbpf: prog 'test_prog': BPF program load failed: Permission denied
libbpf: prog 'test_prog': -- BEGIN PROG LOAD LOG --
0: R1=ctx() R10=fp0
; int BPF_PROG(test_prog, struct file *file, int ret)
0: (b7) r2 = 152                      ; R2_w=152
; int BPF_PROG(test_prog, struct file *file, int ret)
1: (79) r3 = *(u64 *)(r1 +0)
func 'bpf_lsm_file_open' arg0 has btf_id 601 type STRUCT 'file'
2: R1=ctx() R3_w=trusted_ptr_file()
2: (0f) r3 += r2                      ; R2_w=152 R3_w=trusted_ptr_file(off=152)
3: (bf) r6 = r10                      ; R6_w=fp0 R10=fp0
; 
4: (07) r6 += -16                     ; R6_w=fp-16
; BPF_CORE_READ_INTO(&file_path, file, f_path);
5: (bf) r1 = r6                       ; R1_w=fp-16 R6_w=fp-16
6: (b7) r2 = 16                       ; R2_w=16
7: (85) call bpf_probe_read_kernel#113        ; R0_w=scalar() fp-8=mmmmmmmm fp-16=mmmmmmmm
8: (bf) r2 = r10                      ; R2_w=fp0 R10=fp0
; 
9: (07) r2 += -271                    ; R2_w=fp-271
; long err = bpf_d_path(&file_path, path_buffer, sizeof(path_buffer));
10: (bf) r1 = r6                      ; R1_w=fp-16 R6_w=fp-16
11: (b7) r3 = 255                     ; R3_w=255
12: (85) call bpf_d_path#147
R1 type=fp expected=ptr_, trusted_ptr_, rcu_ptr_
processed 13 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
-- END PROG LOAD LOG --
libbpf: prog 'test_prog': failed to load: -13
libbpf: failed to load object 'lsm_file_open.o'
Failed to load BPF object into the kernel

错误原因与修复方案

错误原因

验证器报错R1 type=fp expected=ptr_, trusted_ptr_, rcu_ptr_,核心问题是:bpf_d_path的第一个参数要求传入内核空间的可信指针(如trusted_ptr_类型),但原代码传递的是eBPF栈上变量file_path的地址(fp类型,即栈指针),不符合内核验证规则。

修复后的代码

#include "vmlinux.h"
#include "commons.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>
#include <bpf/bpf_tracing.h>

#define MAX_SIZE        255

SEC("lsm/file_open")
int BPF_PROG(test_prog, struct file *file, int ret)
{
    char path_buffer[MAX_SIZE];
    // 直接获取内核中file->f_path的可信指针,无需拷贝到栈
    const struct path *file_path = BPF_CORE_READ(file, f_path);
    long err = bpf_d_path(file_path, path_buffer, sizeof(path_buffer));
    return 0;
}

char LICENSE[] SEC("license") = "GPL";

修复说明

通过BPF_CORE_READ(file, f_path)直接获取内核中struct file成员f_path的指针,该指针属于内核认可的可信指针类型,能通过BPF验证器的检查,同时避免了不必要的栈拷贝操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 02:42:45