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

Linux内核中能否从系统调用传入的fd获取文件名?

从系统调用传入的fd获取对应文件名(Linux 5.10.0-rc5 arm64)

在Linux内核中,确实可以通过用户态系统调用传入的fd获取对应的文件名,但这个过程存在关键限制,且需要遵循内核安全规范。以下是具体实现思路和注意事项:

核心实现步骤

  1. 通过fd获取struct file实例
    从当前进程的文件描述符表中,利用内核函数fget()通过fd定位到对应的文件结构体:

    struct file *file = fget(fd);
    if (!file) {
        // 处理fd无效的情况,比如返回-EBADF错误
        return -EBADF;
    }
    

    注意:使用完毕后必须调用fput(file)释放引用,避免内存泄漏。

  2. 提取路径相关结构体
    struct file中的f_path成员包含struct path对象,其中dentry指向目录项结构体,mnt指向挂载点结构体:

    struct path *path = &file->f_path;
    struct dentry *dentry = path->dentry;
    struct vfsmount *mnt = path->mnt;
    
  3. 拼接生成可读路径
    使用内核提供的d_path()函数,将struct path转换为用户可读的路径字符串。需要先通过__getname()分配临时内核缓冲区:

    char *buf = __getname();
    if (!buf) {
        fput(file);
        return -ENOMEM;
    }
    const char *filename = d_path(path, buf, PATH_MAX);
    // 此时filename指向拼接完成的路径字符串
    

    注意:使用完缓冲区后要调用__putname(buf)释放;d_path()可能返回相对路径,若需绝对路径需额外处理。

关键限制说明

  • 非真实文件的fd无法获取有效文件名:如果fd指向管道、socket、匿名inode(如tmpfs中的匿名文件)等特殊对象,d_path()会返回[pipe]、[socket]这类占位符,无法得到真实文件名。
  • 权限与上下文约束:fget()已隐含权限检查,但跨进程操作fd时需额外验证;必须确保操作处于合法进程上下文。
  • 路径的时效性:文件可能在获取路径后被重命名或删除,得到的路径仅代表当前时刻状态,不保证后续有效。

在do_el0_svc中的注意点

在do_el0_svc(struct pt_regs *regs)中读取x0寄存器的fd后,可直接执行上述操作,但需注意:

  • 禁止直接访问用户态内存,所有字符串操作必须使用内核安全函数。
  • 避免在该函数中执行耗时操作,防止拖慢系统调用的执行效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:45:45