解析 Section Mismatch

Section Mismatch 可能引发非法内存访问,进而引发内核crush崩溃

0 配置 Section Mismatch 检测

CONFIG_DEBUG_SECTION_MISMATCH=y

1 如何引发 Section Mismatch

1.1 非法访问 __init section中的资源,因为带有__init 标记的section会在linux启动初始化完成后被free掉,这样可以较少内存消耗, 非法引用已经被free掉的init section的资源会导致Section Mistach
1.2 不同section之间的引用会导致编译时出现Warnning,同1.1, 运行时如果其中一个section资源被free掉,另外一个section重新去引用它也会出现section mismatch, 还可能崩溃

2 如何解决 Section Mismatch

2.1 解决1.1的问题, 如果运行时函数需要调用init section 中的函数或者变量, 则被调用的函数或者变量要去掉__init *的标记, 或者给调用者加上init 的声明, include/linux/init.h
2.2 解决1.2的问题,如果不同的Section之间存在交叉引用,这个交叉引用是安全的,则用__ref标记让Section Mismatch Detector(modpost)忽略相关检查, 比如在cpu hotplug中,__cpuinit不会放在Init section中,在运行时访问是安全的。如果一个函数跟cpu hotplug无关,不用添加__cpuinit标记。因为这种访问是安全的,所以可以让内核忽略对它的检测,用__ref标记 该函数即可。

3 arm内核支持

在最新的ARM内核中,引入了一个更进一步的智能检测,该检测是针对free掉的内存被运行时函数访问的情况,前面的分析提到类似的情况会导致无法预测的风险,而该智能检测则会明确地报告出具体的问题。
该检测的原理是把所有Init Section的内存区域在内核初始化时把这些内存区域初始化为0xe7fddef0 (an undefined instruction (ARM) or a branch to an  undefined instruction (Thumb)),如果运行时函数非法访问到了这些区域,会触发一个undef instruction的异常并打印相应的回调,从而辅助开发人员更快地解决相关问题。
参考 arch/arm/mm/init.c:
free_initmem(void)
    ->poison_init_mem()

你可能感兴趣的:(解析 Section Mismatch)