通常在 Linux/ARM 上,映射在 0xffff0000
的特殊页面用于实现“读取 TLS 指针”操作、原子比较和交换以及内存屏障。该系统称为“kuser helpers”(CONFIG_KUSER_HELPERS
),对于解决早期 Arm 模型中缺乏对原子比较和交换的支持是必要的。然而,最近的内核版本提供了禁用此功能的选项,其原则是它存在安全风险(促进基于返回固定可执行地址的攻击,因为这些函数不受 ASLR 的约束);如果所有应用程序都是为了直接使用较新 ARM 型号上可用的同步指令而构建的,则可以使用此选项。
我的问题是,我希望能够使用相同的二进制文件支持旧的 ARM 模型(缺乏同步指令)和新的强化内核(缺乏 kuser 帮助程序),所以我正在寻找一种可靠的方法,从用户空间,检测 kuser 帮助程序页面的可用性(如果可用则使用它,如果不可用则假设较新的指令必须可用)。可靠排除了像 /proc
这样可能并不总是可用的东西。有没有什么方法可以探测 kuser 帮助程序页面的存在,而不是尝试使用它并捕获 SIGSEGV
?
最佳答案
vector 页面是在内核初始化期间在 arch/arm/kernel/traps.c:early_trap_init() 中设置的,并且仍然存在,只是没有助手,所以你不应该首先获得 SEGV;出于同样的原因,mmap 技巧不起作用(我没有检查这些假设中的任何一个)。
但是: vector 页面被early_alloc_aligned()初始化为零,所以你很幸运,因为0xffff0ffc处的kuser_helpers数量不会被填充,因此为零。
tl;dr:从0xffff0ffc读取kuser助手的数量。如果零 => 不支持它们
关于c - Linux/ARM "kuser_helper"函数的运行时检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22677456/