内核中利用kasan检查访问内存是否合法时需要将要访问的内存地址映射到shadow区中的对应位置,然后再判断在shadow区里存放的数值。
下面是转换函数:
static inline void *kasan_mem_to_shadow(const void *addr) { return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET; }
为什么是上面的公式呢?
按照我们直观的理解,应该是:(addr - 内核虚地址起始地址) >> 3 + shadow区的起始地址
其实kasan_mem_to_shadow也是这么来的,只不过把其中的常量部分提前计算出来了,对上面的公式进行转换:
(addr >> 3) + shadow区的起始地址 - (内核虚地址起始地址 >> 3)
比如:
计算:
(addr >> 3) + ffffec0000000000 - (ffff800000000000 >> 3) = (addr >> 3) + 0xdffffc0000000000
对于x86,这个值是写死的:arch/x86/Kconfig
对于ARM64,是: