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的更多相关文章

  1. linux下内存检测工具的使用和对比

    linux背后隐藏着各种丰富的工具,学会这些工具,让这些工具更好地服务于我们的项目开发,不仅可以提高工作的效率,而且可以增强个人技术力. 参考:http://blog.chinaunix.net/ui ...

  2. 【调试】Linux下超强内存检测工具Valgrind

    [调试]Linux下超强内存检测工具Valgrind 内容简介 Valgrind是什么? Valgrind的使用 Valgrind详细教程 1. Valgrind是什么? Valgrind是一套Lin ...

  3. Linux中系统检测工具top命令

    Linux中系统检测工具top命令 本文转自:https://www.cnblogs.com/zhoug2020/p/6336453.html 首先介绍top中一些字段的含义: VIRT:virtua ...

  4. valgrind内存检测工具

    valgrind 那点事 ---------------------------------------内存检测工具 valgrind要使用此工具,可以使用--tool=memcheck 在Valgr ...

  5. Linux内核死锁检测机制【转】

    转自:http://www.oenhan.com/kernel-deadlock-check 死锁就是多个进程(线程)因为等待别的进程已占有的自己所需要的资源而陷入阻塞的一种状态,死锁状态一旦形成,进 ...

  6. Linux内核-内存回收逻辑和算法(LRU)

    Linux内核内存回收逻辑和算法(LRU) LRU 链表 在 Linux 中,操作系统对 LRU 的实现主要是基于一对双向链表:active 链表和 inactive 链表,这两个链表是 Linux ...

  7. Linux IO时事检测工具iostat

    Linux IO时事检测工具iostat iostat命令用于检测linux系统io设备的负载情况,运行iostat将显示自上次运行该命令以后的统计信息.用户可以通过指定统计的次数和时间来获得所需的统 ...

  8. Linux内核内存管理算法Buddy和Slab: /proc/meminfo、/proc/buddyinfo、/proc/slabinfo

    slabtop cat /proc/slabinfo # name <active_objs> <num_objs> <objsize> <objpersla ...

  9. 安全运维之:Linux后门入侵检测工具的使用

    安全运维之:Linux后门入侵检测工具的使用 https://blog.csdn.net/exitgogo/article/details/39547113

随机推荐

  1. 关于mysql基础

    早就想把自己的数据库基础巩固一下,然而一直没有时间,今天终于抽出时间对mysql数据库基础进行了学习与扩展. mysql与其他数据库的区别 Sqlite: 开源免费,体积小,单文件,没有进程.磁盘读性 ...

  2. 12c slience dbca ORA-27125

    问题:12c slience dbca ORA-27125 解决办法:网上大部分方法是把dba组放在内核的,没有效果,可以尝试google找到一位大神的方案,成功解决https://oracle-ad ...

  3. SQL 居然还能在 Apache ShardingSphere 上实现这些功能?

    在去年 10 月 5.0.0-alpha 版本发布之后,Apache ShardingSphere 经历了长达 8 个多月的持续开发与优化,终于在 6 月 25 日正式迎来了 5.0.0-beta 版 ...

  4. MSSQL还原数据库,更改用户登陆权限

    有的时候还原完数据库后,使用账号登陆不进去,报告没有这个用户的时候,可以使用以下sql解决: sp_change_users_login 'update_one','username','userna ...

  5. C/C++入门级小游戏——开发备忘录

    很多工科的学生在大一都有一门课程,叫C语言程序设计.大概就是装个IDE然后和一个黑乎乎的窗口打交道,期末到了考完试就结束了.然而很多人可能都有一个疑惑:C语言究竟能干什么?除开嵌入式单片机这些高大上的 ...

  6. 关于 WinDoAdmin

    WinDoAdmin(有温度,更有深度) an amazing winform admin 框架描述 最新基于Winform实现的Web样式中后台解决方案,大型企业级开发框架. 如果你要使用Winfo ...

  7. 初学Python “登录”案例 更新!!

    更新内容:添加了登录次数,如果超过限制的次数,则提示账户被锁定,去某邮箱申请解锁账户! 此次仅把登录系统更新之后源代码放到这里,不在共享源文件在网盘了! 1 ''' 2 登录界面 3 ''' 4 5 ...

  8. HCIP-RSTP

    端口角色 根端口(RP): 非根桥收到最优的BPDU配置信息的端口为根端口,(到根桥开销最小的端口),根桥没有根端口. 指定端口(DP): 两非根交换机之间连接的两个端口必有一个为指定端口,比较两个非 ...

  9. 如何访问位于内网的Ubuntu主机

    如何访问位于内网的Ubuntu主机 内网主机为Ubuntu桌面版 内网主机Ubuntu字符串界面版 SSH远程主机管理工具推荐 SSH远程文件访问工具推荐 如何访问位于内网的Ubuntu主机 内网主机 ...

  10. JVM:内存模型

    JVM:内存模型 说明:这是看了 bilibili 上 黑马程序员 的课程 JVM完整教程 后做的笔记 1. java 内存模型 很多人将[java 内存结构]与[java 内存模型]傻傻分不清,[j ...