多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

fault bad_address

fault bad_address bad_address()是 Linux 内核中一个用于安全探测内核地址是否可读的辅助函数。它的核心作用是在不触发内核崩溃Oops的前提下检查一个给定的内核地址是否有效可读。核心机制get_kernel_nofaultget_kernel_nofault()是一个特殊的宏/函数它利用内核的异常表exception table机制来实现“安全访问”正常读取它尝试从指定地址读取数据。异常捕获如果这次读取触发了缺页异常地址无效CPU 会跳转到异常表中预先注册的修复地址而不是执行正常的 Oops 流程。返回结果读取成功返回0失败返回非零值。因此bad_address(p)的返回值语义非常明确返回0地址p是可读的数据已成功读取到dummy变量中。返回非零地址p不可读如未映射、权限不足但内核安然无恙。在dump_pagetable中的用途这个函数通常出现在页表转储相关的代码中。在遍历页表层级PGD → PUD → PMD → PTE时内核需要读取每一级页表项的值。然而这些页表项本身可能指向无效的物理地址或者由于页表损坏对应的内核虚拟地址可能已经不可读。如果直接解引用这些指针一旦遇到坏地址内核就会立即 Oops。而使用bad_address()作为“探雷器”可以在尝试读取之前先确认地址的安全性避免在诊断问题的过程中引入新的崩溃。与probe_kernel_read的关系bad_address()和probe_kernel_read()功能相似但bad_address()更轻量。它只关心“能不能读”而不关心“读到了什么”。在页表遍历这种对性能敏感的调试路径中使用bad_address()可以快速过滤掉不安全的地址然后再用probe_kernel_read()去实际读取数据是一种常见的“两阶段”安全访问模式。
返回列表