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

BPF LSM问题:bpf_task_storage_get期望可信指针

问题:LSM BPF程序中bpf_task_storage_get无法识别bpf_get_current_task()返回的指针

现象

在LSM的task_alloc钩子中,使用bpf_get_current_task()获取当前任务指针并传入bpf_task_storage_get时,BPF程序加载失败。BPF验证器提示第二个参数为标量,不符合指针/可信指针的要求。

可正常运行的代码

struct provenance_structure {
    __u8    to_trace;
    struct bpf_spin_lock lock;
};

struct {
    __uint(type, BPF_MAP_TYPE_TASK_STORAGE);
    __uint(map_flags, BPF_F_NO_PREALLOC);
    __type(key, int);
    __type(value, struct provenance_structure);
} provenance_structure_map_task SEC(".maps");


SEC("lsm/task_alloc")
int BPF_PROG(task_allocation, struct task_struct *p, u64 clone_flags) {
    struct provenance_structure *prov;
    prov = bpf_task_storage_get(&provenance_structure_map_task, p, NULL, 0);
    if(prov){
        bpf_spin_lock(&prov->lock);
        prov->to_trace = 1;
        bpf_spin_unlock(&prov->lock);
    } 
    return 0;
}

出错的代码

SEC("lsm/task_alloc")
int BPF_PROG(task_allocation, struct task_struct *p, u64 clone_flags) {
    // 强制转换为struct task_struct*也会触发相同错误
    struct task_struct *s_task = (void *)bpf_get_current_task();
    struct provenance_structure *prov;
    prov = bpf_task_storage_get(&provenance_structure_map_task, s_task, NULL, 0);
    if(prov){
        bpf_spin_lock(&prov->lock);
        // 将to_trace标记设为True
        prov->to_trace = 1;
        bpf_spin_unlock(&prov->lock);
    } 
    return 0;
}

验证器错误日志

libbpf: prog 'task_allocation': -- BEGIN PROG LOAD LOG --
0: R1=ctx() R10=fp0
; struct task_struct *s_task = (void *)bpf_get_current_task(); @ provenance_tracing_programs.bpf.c:139
0: (85) call bpf_get_current_task#35          ; R0_w=scalar()
; prov = bpf_task_storage_get(&provenance_structure_map_task, s_task, NULL, 0); @ provenance_tracing_programs.bpf.c:141
1: (18) r1 = 0xffff9a96d1220200       ; R1_w=map_ptr(map=provenance_stru,ks=4,vs=272)
3: (bf) r2 = r0                       ; R0_w=scalar(id=1) R2_w=scalar(id=1)
4: (b7) r3 = 0                        ; R3_w=0
5: (b7) r4 = 0                        ; R4_w=0
6: (85) call bpf_task_storage_get#156
R2 type=scalar expected=ptr_, trusted_ptr_, rcu_ptr_
processed 6 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
-- END PROG LOAD LOG --
libbpf: prog 'task_allocation': failed to load: -13
libbpf: failed to load object 'provenance_tracing_programs_bpf'
failed to load BPF object: -13

原因

bpf_get_current_task()返回的是无类型的标量指针,BPF验证器无法确认其指向struct task_struct,也不会将其标记为可信指针(trusted_ptr)。而LSM钩子参数中的p是内核直接传递的,验证器已确认其类型和可信度,因此可以正常使用。

解决方案

使用bpf_get_current_task_btf()替代bpf_get_current_task(),该函数返回带有BTF类型信息的struct task_struct*指针,验证器会识别其为可信指针,允许传递给bpf_task_storage_get。

修改后的代码:

SEC("lsm/task_alloc")
int BPF_PROG(task_allocation, struct task_struct *p, u64 clone_flags) {
    struct task_struct *s_task = bpf_get_current_task_btf();
    struct provenance_structure *prov;
    prov = bpf_task_storage_get(&provenance_structure_map_task, s_task, NULL, 0);
    if(prov){
        bpf_spin_lock(&prov->lock);
        prov->to_trace = 1;
        bpf_spin_unlock(&prov->lock);
    } 
    return 0;
}

注意事项

  • bpf_get_current_task_btf()需要内核版本5.15及以上支持。
  • 确保编译环境启用了BTF(较新内核发行版默认已开启)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 02:35:54