Linux驱动问题:chroot环境下无法访问指定绝对路径文件
解决chroot环境下内核模块无法访问真实绝对路径文件的问题
这问题我之前做容器相关内核模块时踩过同款坑!核心原因是内核模块在进程上下文执行时,路径解析会继承当前进程的chroot根目录,而非直接访问系统真实的根文件系统。
问题根源拆解
- 正常场景下:应用进程的根目录就是系统真实根(
/),当模块在这个进程上下文调用filp_open()等函数时,内核会基于进程的struct fs_struct里的根目录解析绝对路径,自然能定位到目标文件。 - chroot场景下:应用调用
chroot()后,进程的struct cred中的root指针会指向chroot后的新根目录。此时模块如果还是用原来的绝对路径(比如/etc/config.txt)调用filp_系列函数,内核会把这个路径解析成chroot目录下的/etc/config.txt,而非系统真实根下的对应文件,所以会出现找不到的情况。
可行解决方案
如果你的模块需要访问系统真实根文件系统中的目标文件,可以绕过进程上下文的根目录限制,直接基于系统真实根来打开文件,示例代码如下:
#include <linux/fs.h> #include <linux/sched.h> // 用于init_task struct path real_root_path; struct file *target_file; int ret = 0; // 获取系统真实根目录的path结构(init_task是初始化进程,它的fs指向真实根) get_fs_root(&init_task.fs, &real_root_path); // 基于真实根打开目标文件,注意这里要用相对真实根的路径(比如原绝对路径是/etc/config.txt,这里传"etc/config.txt") target_file = file_open_root(real_root_path.dentry, real_root_path.mnt, "etc/config.txt", O_RDONLY, 0); if (IS_ERR(target_file)) { ret = PTR_ERR(target_file); pr_err("Failed to open file: %d\n", ret); goto cleanup; } // 这里可以对target_file进行读写操作,比如用kernel_read()等函数 cleanup: if (!IS_ERR(target_file)) { filp_close(target_file, NULL); } put_path(&real_root_path); // 释放真实根路径的引用 return ret;
额外注意事项
- 权限问题:即使是内核模块,打开文件时依然会受文件系统DAC权限限制,如果需要访问受限文件,可以临时提升权限(比如使用
capable(CAP_DAC_READ_SEARCH)检查,或者谨慎使用set_fs(KERNEL_DS))。 - 避免硬编码路径:如果可能,尽量让应用传递目标文件的inode或者相对真实根的路径,减少硬编码带来的维护问题。
内容的提问来源于stack exchange,提问作者codemonkey
相关产品推荐
相关产品推荐

