Linux内核内存检测工具KASAN
KASAN 是 Kernel Address Sanitizer 的缩写,它是一个动态检测内存错误的工具,主要功能是检查内存越界访问和使用已释放的内存等问题。KASAN 集成在 Linux 内核中,随 Linux 内核代码一起发布,并由内核社区维护和发展。本文简要介绍 KASAN 的原理及使用方法。
一、KASAN的原理和使用方法
1. 如何打开KASAN功能
Kernel defconfig增加如下配置:
由于1/8的内存用于shadow memory,可用内存会减少1/8,例如8GB的内存,打开KASAN后,MemTotal约为6.72GB。
C:\Users>adb shell "cat /proc/meminfo | grep MemTotal"
MemTotal: 6723572 kB
2. KASAN原理概述
KASAN利用额外的内存标记可用内存的状态,这部分额外的内存被称作shadow memory(影子区),KASAN将1/8的内存用作shadow memory。使用特殊的magic num填充shadow memory,在每一次load/store内存的时候检测对应的shadow memory确定操作是否valid。连续8 bytes内存(8 bytes align)使用1 byte shadow memory标记。
如果8 bytes内存都可以访问,则shadow memory的值为0;如果连续N(1 =< N <= 7) bytes可以访问,则shadow memory的值为N;如果8 bytes内存访问都是invalid,则shadow memory的值为负数。
例如:
这段汇编指令是往0xffffffc08821e810地址写5,当打开Kasan时,编译器会自动插入红色的bl __asan_store1指令,__asan_store1函数就是检测一个地址对应的shadow memory的值是否允许写1 byte,蓝色汇编指令是真正的内存访问。
3. 如何根据shadow memory的值判断内存访问操作是否合法?
shadow memory检测原理的实现主要就是__asan_load##size()和__asan_store##size()函数。KASAN如何根据访问的address以及对应的shadow memory的状态值来判断访问是否合法呢?
1)当访问8 bytes时,*shadow_memory == 0,访问是valid,否则是invalid;
2)当访问N bytes (N = 1,2,4)时,
if (*shadow && *shadow > ((unsigned long)addr & 7) + N),访问valid;否则,是invalid;
4. 伙伴系统分配的内存shadow memory值如何填充
(1) 从buddy system分配内存
Step1:假如从buddy system分配4 pages,系统首先从order=2的链表中摘下一块内存;
Step2:然后根据shadow memory address和memory address的对应关系找到对应的shadow memory;对应关系为:
Shadow_addr = (addr >> 3) + KASAN_SHADOW_OFFSET,右移3bit的原因是8 byte memory对应1 byte shadow memory;
Step3:填充shadow memory的内容,分配的4 pages均可访问,填充为0;
(2) 从buddy system释放内存
Step1:从buddy system order = 2的链表中释放4 pages;
Step2:根据shadow memory addr和memory addr的对应关系,找到shadow memory;
Step3:将shadow memory对应的内存区域2KB(16KB/8)填充为0xFF(KASAN_FREE_PAGE);
5. slub分配的内存shadow memory值如何填充
(1) 从slub cache分配内存
Step1:kmalloc(20)会匹配到kmalloc-32的kmem_cache,实际分配的object大小是32 bytes。剩下的12 bytes KASAN会标记为不可访问状态;
Step2:根据shadow memory addr和memory addr的对应关系找到shadow meory;
Step3:填充shadow memory的内容为00 00 04 FC,具体含义为:
1)前面2个00表示第0~15 byte均可访问
2)04表示第16~23 byte只有前面4 bytes可以访问
3)FC表示第24~31 byte为 KASAN_KMALLOC_REDZONE,不可访问
Step4:保存内存分配的call-stack;
Step5:如果访问了REDZONE区域,KASAN会report out-of-bounds bug;
(2) 从slub cache释放内存
Step1:从slub cache(kmalloc-32) free 20 bytes内存;
Step2:根据memory addr找到shadow memory addr;
Step3:将shadow memory的4 bytes填充为FB(KASAN_KMALLOC_FREE);
Step4:保存slub free的call-stack;
Step5:如果访问了 FB对应的内存,KASAN会报use-after-free bug;
6. 其他形式分配的内存shadow memory如何填充?
全局变量/栈分配的内存填充原理和前面类似,实现有些差异,这里不一一赘述。
7. KASAN report bug举例
二、总结
KASAN通过建立影子内存来管理内存访问的合法性,可以有效检测内存越界等问题,但无法发现因逻辑问题导致的合法内存的内容改写问题。
Linux内核内存检测工具KASAN的更多相关文章
- linux下内存检测工具的使用和对比
linux背后隐藏着各种丰富的工具,学会这些工具,让这些工具更好地服务于我们的项目开发,不仅可以提高工作的效率,而且可以增强个人技术力. 参考:http://blog.chinaunix.net/ui ...
- 【调试】Linux下超强内存检测工具Valgrind
[调试]Linux下超强内存检测工具Valgrind 内容简介 Valgrind是什么? Valgrind的使用 Valgrind详细教程 1. Valgrind是什么? Valgrind是一套Lin ...
- Linux中系统检测工具top命令
Linux中系统检测工具top命令 本文转自:https://www.cnblogs.com/zhoug2020/p/6336453.html 首先介绍top中一些字段的含义: VIRT:virtua ...
- valgrind内存检测工具
valgrind 那点事 ---------------------------------------内存检测工具 valgrind要使用此工具,可以使用--tool=memcheck 在Valgr ...
- Linux内核死锁检测机制【转】
转自:http://www.oenhan.com/kernel-deadlock-check 死锁就是多个进程(线程)因为等待别的进程已占有的自己所需要的资源而陷入阻塞的一种状态,死锁状态一旦形成,进 ...
- Linux内核-内存回收逻辑和算法(LRU)
Linux内核内存回收逻辑和算法(LRU) LRU 链表 在 Linux 中,操作系统对 LRU 的实现主要是基于一对双向链表:active 链表和 inactive 链表,这两个链表是 Linux ...
- Linux IO时事检测工具iostat
Linux IO时事检测工具iostat iostat命令用于检测linux系统io设备的负载情况,运行iostat将显示自上次运行该命令以后的统计信息.用户可以通过指定统计的次数和时间来获得所需的统 ...
- Linux内核内存管理算法Buddy和Slab: /proc/meminfo、/proc/buddyinfo、/proc/slabinfo
slabtop cat /proc/slabinfo # name <active_objs> <num_objs> <objsize> <objpersla ...
- 安全运维之:Linux后门入侵检测工具的使用
安全运维之:Linux后门入侵检测工具的使用 https://blog.csdn.net/exitgogo/article/details/39547113
随机推荐
- P7046-「MCOI-03」诗韵【SAM,倍增,树状数组】
正题 题目链接:https://www.luogu.com.cn/problem/P7046 题目大意 给出一个长度为 \(n\) 的字符串,然后 \(m\) 次把它的一个子串加入集合.如果一个字符串 ...
- P5825-排列计数【EGF,NTT】
正题 题目链接:https://www.luogu.com.cn/problem/P5825 题目大意 对于每个\(k\),求有多少个长度为\(n\)的排列有\(k\)个位置上升. \(1\leq n ...
- AT4995-[AGC034E] Complete Compress【树形dp】
正题 题目链接:https://www.luogu.com.cn/problem/AT4995 题目大意 \(n\)个点的一棵树,上面有一些棋子,每次可以选择两个棋子移动到他们之间的路径上相邻的点上, ...
- Android系统编程入门系列之应用级文件在应用程序间的共享
在上篇文章了解到应用级文件只能被其所创建的应用程序所访问,那么其他应用程序是不是就无论如何都无法访问了呢?肯定不是的,只要文件经过其创建的应用程序授权,还是可以被其他应用程序所访问的.这也就是应用级文 ...
- Kotlin基础入门之必知必会,查漏补缺来一手~~~
数据类型 Kotlin跟 java 相同,基本数据类型有八种 boolean,char,int,short,long,float,double,byte 类型 位宽 最小值 最大值 Short 16 ...
- C++核心编程 4 类和对象-封装
C++面向对象的三大特性:封装.继承.多态 C++认为万事万物皆为对象,对象上有其属性和行为 封装 意义:1.将属性和行为作为一个整体,表现生活中的事物 语法: class 类名{ 访问权限:属性 ...
- 微信公众号开发之H5页面跳转到指定的小程序
前言: 最近公司有一个这样的需要,需要从我们在现有的公众号H5页面中加一个跳转到第三方小程序的按钮.之前只知道小程序之间是可以相互跳转的,今天查阅了下微信开发文档原来现在H5网页也支持小程序之间的跳转 ...
- C++类结构体与json相互转换
1. 背景与需求 之前写C#的时候,解析json字符串一般使用的是开源的类库Newtonsoft.Json,方法十分简洁,比如: class Project { public string Input ...
- ApacheCon 首次亚洲大会火热来袭,SphereEx 邀您共赴年度盛会!
ApacheCon 是 Apache 软件基金会(ASF)的官方全球系列大会.作为久负盛名的开源盛宴,ApacheCon 在开源界备受关注,也是开源运动早期的知名活动之一. ApacheCon 每年举 ...
- 关于 Binomial Coefficient is Fun
题目传送门 Solution 应该这个做法不是很常见吧. 我们设 \(f_{i,j}\) 表示前面 \(i\) 个数,选出的数和为 \(j\) 的贡献之和.因为我们有以下式子: \[\sum_{i=a ...