资讯动态

maccess copy_from_kernel_nofault

发布时间:2026/10/15 12:53:12 来源:尧图企业网站定制
copy_from_kernel_nofault是一个安全的内核空间内存读取函数位于mm/maccess.c中。它的作用是在不触发内核崩溃OOPS的前提下尝试从任意内核地址拷贝数据。函数原型与语义long copy_from_kernel_nofault(void *dst, const void *src, size_t size);dst: 目标缓冲区内核空间的有效地址。src: 源地址可能是无效的内核地址。size: 要拷贝的字节数。返回值: 成功返回0如果源地址无效或访问出错返回-EFAULT如果源地址超出内核有效范围返回-ERANGE。实现机制该函数的实现依赖于架构是否支持HAVE_GET_KERNEL_NOFAULT分为两种路径原生 nofault 路径现代架构当架构定义了HAVE_GET_KERNEL_NOFAULT时如 x86-64核心逻辑如下地址范围校验: 先调用copy_from_kernel_nofault_allowed()检查源地址是否在合法的内核地址范围内。默认实现直接返回true但架构可以覆盖此函数例如 x86 会检查地址是否在TASK_SIZE_MAX以上。禁用页错误: 调用pagefault_disable()防止在拷贝过程中因缺页而睡眠或触发复杂路径。逐级对齐拷贝: 根据src和dst的对齐情况依次尝试用u64、u32、u16、u8的粒度循环拷贝。每次实际读取都使用__get_kernel_nofault()宏该宏被异常表exception table保护——如果读取触发页错误异常表会将控制流跳转到Efault标签函数随即返回-EFAULT。恢复页错误: 拷贝完成后调用pagefault_enable()。兼容回退路径旧架构如果架构未定义HAVE_GET_KERNEL_NOFAULT则使用旧的__copy_from_user_inatomic配合set_fs(KERNEL_DS)来模拟。与get_kernel_nofault的关系bad_address()函数内部调用的就是get_kernel_nofault()它是读取单个unsigned long的安全版本。copy_from_kernel_nofault是它的批量版本用于拷贝任意大小的数据块两者底层共享相同的异常表保护机制。典型用途内核调试/诊断: 在 OOPS 处理路径中安全读取可能已损坏的内存内容如栈回溯、寄存器转储时读取栈上数据。探测内核地址: 判断某个内核地址是否真正可读。BPF / kprobe: 安全地从内核内存中提取数据避免因探针命中无效地址导致系统崩溃。注意事项不可用于 MMIO 地址: 该函数会实际读取内存如果src指向 MMIO 区域读取可能产生硬件副作用如清除中断状态。“nofault” 的含义: 它保证不因访问失败而崩溃但不保证访问本身没有副作用。原子上下文友好: 由于禁用了页错误处理可以在持有自旋锁或禁用抢占的上下文中调用。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑