参考资料:
1,内核源码目录中的Documentation\dev-tools\kasan.rst
2,KASAN - Kernel Address Sanitizer | Naveen Naidu (naveenaidu.dev)
一、kasan实现原理
KASAN(Kernel Address SANitizer)是一个动态内存非法访问检测工具. 可以检测 use-after-free 和out-of-bounds两类错误。
KASAN将内存按8字节分一组,每组用一个额外的字节(shadow mem)来记录可访问的字节数。
shadow mem的值:
1)0,8 bytes内存都是可以访问的。
2)N (1 <= N <= 7) ,8 bytes内存的前N个字节可以访问。
3)为负数,8 bytes内存都不可访问,原因见mm/kasan/kasan.h。
mm/kasan/kasan.h
#define KASAN_FREE_PAGE 0xFF /* page was freed */
#define KASAN_PAGE_REDZONE 0xFE /* redzone for kmalloc_large allocations */
#define KASAN_KMALLOC_REDZONE 0xFC /* redzone inside slub object */
#define KASAN_KMALLOC_FREE 0xFB /* object was freed (kmem_cache_free/kfree) */
#define KASAN_VMALLOC_INVALID 0xF8 /* unallocated space in vmapped page */
二、内存越界示例
代码片段:
1197 static long do_sys_openat2(int dfd, const char __user *filename,
1198 struct open_how *how)
1199 {
1200 struct open_flags op;
1201 int fd = build_open_flags(how, &op);
1202 struct filename *tmp;
1203 int *kasan;
1204 int i;
1205
1206 if (fd)
1207 return fd;
1208
1209 tmp = getname(filename);
1210 if (IS_ERR(tmp))
1211 return PTR_ERR(tmp);
1212
1213 if (!strcmp(tmp->name, "a")) {
1214 kasan = kmalloc(100, GFP_KERNEL);
1215 if (kasan) {
1216 for (i=0; i < 200; i++)
1217 *kasan++ = 'a';
1218