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

eBPF获取的挂载命名空间ID与stat命令输出不一致问题排查

问题

按照bcc挂载命名空间过滤指南操作,虚拟机上运行正常,但另一台主机出现挂载命名空间ID不匹配问题,具体现象:

  • 使用sudo unshare -m bash创建新挂载命名空间,执行stat -L -c %i /proc/self/ns/mnt得到ID为4026533296;
  • 运行指定bcc脚本后,执行tail -f /dev/null,查看/sys/kernel/debug/tracing/trace_pipe发现eBPF输出的挂载命名空间ID为1824653312;
  • 通过ps aux找到该进程PID为1337178,执行sudo stat -L -c %i /proc/1337178/ns/mnt得到的ID仍为4026533296。

使用的bcc脚本:

from bcc import BPF

program = """
int syscall__hello(void *ctx) {
    u64 uid = 0;
    u64 pid = 0;
    u64 *p;
    uid = bpf_get_current_uid_gid() & 0xFFFFFFFF;
    pid = bpf_get_current_pid_tgid() & 0xFFFFFFFF;

    struct task_struct *current_task;
    current_task = (struct task_struct *)bpf_get_current_task();
    u64 ns_id = current_task->nsproxy->mnt_ns->ns.inum;

    if(!(uid == 0 || uid == 1000)) return 0; // to reduce noise
    if (container_should_be_filtered()) {
        bpf_trace_printk("Outside the namespace; %u", ns_id);
        return 0;
    } else {
        bpf_trace_printk("Inside the namespace; %u", ns_id);
    }
    return 0;
}
"""
from argparse import Namespace
from bcc.containers import filter_by_containers

program = filter_by_containers(Namespace(cgroupmap=None, mntnsmap="/sys/fs/bpf/namespaces")) + program
b = BPF(text=program)
syscall = b.get_syscall_fnname("execve")

b.attach_kprobe(event=syscall, fn_name="syscall__hello")

from time import sleep
sleep(6000) # to keep program attached

原因分析

  1. 格式符类型不匹配:脚本中用%u(32位无符号整数格式符)打印u64类型的ns_id,挂载命名空间inode是64位值,高位会被截断。4026533296减去2^32正好等于1824653312,这是输出错误ID的直接原因。
  2. 内核结构体偏移差异:不同内核版本中struct task_struct、struct nsproxy、struct mnt_namespace的字段偏移可能不同,硬编码访问current_task->nsproxy->mnt_ns->ns.inum可能指向错误内存地址,导致读取值异常。

解决方法

1. 修复格式符问题

将bpf_trace_printk中的%u替换为%llu,匹配u64类型输出:

bpf_trace_printk("Outside the namespace; %llu", ns_id);
bpf_trace_printk("Inside the namespace; %llu", ns_id);

2. 安全获取命名空间ID

避免硬编码内核结构体路径,改用可靠方式:

  • 利用内核BTF信息自动解析结构体偏移,可通过bpftool btf dump file /sys/kernel/btf/vmlinux format c导出当前内核的结构体定义,确认字段路径正确性;
  • 优先使用bcc提供的辅助函数或内核安全接口读取命名空间inode,减少硬编码依赖。

3. 验证BPF映射配置

检查/sys/fs/bpf/namespaces路径下的BPF映射,确认目标挂载命名空间ID已正确写入,避免过滤逻辑判断错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:45:06