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

内核空间访问字符设备:set_fs()替代方案及跨模块文件交互

内核空间文件交互的两个问题

我已经把问题做了泛化处理,之前社区里有不少关于内核空间中打开/交互文件的讨论,相关实现方法大多诞生于set_fs()被弃用之前。以下是两个具体问题及对应方案:

一、set_fs()弃用后的替代技术

出于好奇,目前有没有能替代set_fs()的技术,来完成之前那些方案里的内核文件操作?

目前内核提供了更安全、无需手动切换地址空间的替代方案:

  • 使用封装好的内核文件操作API,比如kernel_read()、kernel_write(),这些函数已经内置了安全的地址空间处理,不需要手动调用set_fs()
  • 直接调用vfs_read()、vfs_write()等VFS层函数,现在内核在调用这些函数时,会自动处理内核态的地址空间上下文,无需手动设置fs结构体
  • 对于更复杂的操作,可以使用file_read_actor()这类回调式函数,或者直接操作struct file对应的f_op接口,只要确保传入的缓冲区是内核地址空间的合法指针即可

二、无导出接口的内核模块间文件通信方案

存在这样的场景:某个内核模块只提供基于文件的接口,没有导出任何其他符号,但另一个内核模块需要和它交互,且无法修改原模块。比如kcov,它通过debugfs文件做IO,核心的struct kcov只存在于filp->private_data中。这种情况下,或许不需要完整执行open等流程,只需获取struct file_operations指针,再构造/获取合适的file/inode/dentry作为参数调用对应函数即可,有没有可行的方案?

可行的思路如下:

  1. 定位目标文件的内核对象:通过kern_path()函数传入目标文件的路径(比如kcov的debugfs路径),获取对应的struct path,从中可以拿到dentry和inode对象
  2. 获取/构造struct file实例:可以使用filp_open()打开目标文件(当前版本无需set_fs()),得到合法的struct file指针;也可以通过alloc_file()构造文件对象,但需要正确设置inode、f_op等参数,同时注意管理引用计数
  3. 直接调用文件操作函数:拿到file->f_op后,可以直接调用其中的read、write、ioctl等函数,传入对应的内核态参数。比如对于kcov,打开文件后filp->private_data就是struct kcov结构体,可直接用于后续交互
  4. 注意事项:操作过程中要严格管理文件对象的引用计数(用fput()释放),避免内存泄漏;确保操作在允许的上下文执行(比如部分文件操作不能在中断上下文进行);注意内核版本兼容性,部分函数的参数或行为可能随版本变化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:25:17