调用VFIO文件操作时,set_fs(KERNEL_DS)后用内核地址调用copy_from_user是否安全?
问题
我正在基于kernel-4.9.168开发Linux内核模块,因需求需要调用VFIO模块的文件操作(如write)。VFIO模块的相关实现大致如下:
static ssize_t do_io_rw(struct vfio_pci_device *vdev, bool test_mem, void __iomem *io, char __user *buf, loff_t off, size_t count, size_t x_start, size_t x_end, bool iswrite) { ssize_t done = 0; int ret; while (count) { size_t fillable, filled; if (off < x_start) fillable = min(count, (size_t)(x_start - off)); else if (off >= x_end) fillable = count; else fillable = 0; if (fillable >= 4 && !(off % 4)) { u32 val; if (iswrite) { if (copy_from_user(&val, buf, 4)) return -EFAULT; ret = vfio_pci_iowrite32(vdev, test_mem, val, io + off); if (ret) return ret; } } // 省略剩余代码 } }
我了解copy_from_user会通过比较addr_limit与buf参数来检查地址是否属于用户空间,因此在自己的模块中,我使用__kernel_write来绕过用户空间检查,代码如下:
static int my_module_code(struct file *file, struct vhost_virtqueue *vvq) { loff_t pos = yyy; unsigned int *idx = &vvq->idx; return __kernel_write(file, (char *)idx, 2, &pos); }
__kernel_write会在调用file->ops->write前设置set_fs(KERNEL_DS),目前代码运行正常,但我因copy_from_user名称带有"user"而感到不安。请问我的代码是否安全?是否有更合适的处理方式?
回答
代码安全性分析
你的代码在当前场景下是安全的:
__kernel_write的设计初衷就是在内核态向文件对象写入内核空间数据,它会临时将addr_limit设置为KERNEL_DS,让后续的copy_from_user(或同类用户空间检查函数)认可传入的内核地址合法性,执行完成后再恢复原有addr_limit。- 你传入的
idx是内核空间指针(&vvq->idx属于内核态内存),本身不存在用户空间地址合法性问题,__kernel_write的逻辑完全匹配这种使用场景。
更合适的处理方式
如果想要让代码逻辑更清晰,或者避免依赖__kernel_write,可以考虑以下两种方案:
- 直接调用VFIO核心读写函数:如果VFIO提供了
vfio_pci_write这类直接操作设备的内核接口,可以直接传入内核态数据指针。需要注意的是,这类函数可能未被导出(非EXPORT_SYMBOL),需要确认内核配置或修改VFIO代码导出所需函数。 - 封装内核态写入适配函数:如果必须通过文件操作接口,可以自己封装一个逻辑明确的写入函数,本质和
__kernel_write一致,但命名更贴合场景:
static ssize_t kernel_vfio_write(struct file *file, const void *buf, size_t count, loff_t *pos) { mm_segment_t old_fs = get_fs(); ssize_t ret; set_fs(KERNEL_DS); // 强制转换为__user类型绕过编译检查,实际已通过set_fs允许内核地址 ret = file->f_op->write(file, (const char __user *)buf, count, pos); set_fs(old_fs); return ret; }
额外注意事项
- 确保传入的
file对象确实是VFIO设备的文件句柄,避免因文件类型错误触发异常。 - 注意
vvq->idx的访问同步:如果该变量可能被其他线程或中断修改,需要添加自旋锁等同步机制,避免数据竞争。
内容的提问来源于stack exchange,提问作者user24452356
相关产品推荐
相关产品推荐

