Linux内核内存检测工具KASAN

2023-11-19

KASAN ['kæzən]

KASAN 是 Kernel Address Sanitizer 的缩写,它是一个动态检测内存错误的工具,主要功能是检查内存越界访问和使用已释放的内存等问题。KASAN 集成在 Linux 内核中,随 Linux 内核代码一起发布,并由内核社区维护和发展。本文简要介绍 KASAN 的原理及使用方法。

1. 如何打开KASAN功能

Kernel defconfig增加如下配置:

CONFIG_SLUB_DEBUG=y

CONFIG_SLUB_DEBUG_ON=y

CONFIG_KASAN =y

CONFIG_KASAN_INLINE=y

由于1/8的内存用于shadow memory,可用内存会减少1/8,例如8GB的内存,打开KASAN后,MemTotal约为6.72GB。

#ifdef CONFIG_KASAN
#define KASAN_SHADOW_SIZE    (UL(1) << (VA_BITS - 3))
#define KASAN_THREAD_SHIFT    1
#else
#define KASAN_SHADOW_SIZE    (0)
#define KASAN_THREAD_SHIFT    0
#endif

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的值为负数。

例如:

adrp x0, 0xffffffc08821e810

mov w1,#0x5

bl_asan_store1

strb w1,[x0]

 这段汇编指令是往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的状态值来判断访问是否合法呢?

__asan_load##size/__asan_store##size

        check_memory_region_inline

                memory_is_poisoned

                       memory_is_poisoned_1

                                return unlikely(last_accessible_byte >= shadow_value)

                        memory_is_poisoned_2_4_8

                        memory_is_poisoned_16

 

 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通过建立影子内存来管理内存访问的合法性,可以有效检测内存越界等问题,但无法发现因逻辑问题导致的合法内存的内容改写问题。

一般是针对,DDR损坏,很有效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux内核内存检测工具KASAN 的相关文章

  • 如何从 C 文件更改终端中的目录

    如何从 C 程序更改将在终端上生效的目录 实际上不要告诉 system 函数或 chdir 函数 这些仅适用于 C 中的进程或子 shell 假设我正在从 bash shell 执行一个 C 程序 其进程 ID 为 10223 那么 我可以
  • 从 gitlab docker runner 启动声纳扫描仪

    我有一个 CI 工作流程 集成了 linting 作业和代码质量作业 我的 Linting 工作是一个 docker runner 从应用程序代码启动我的 eslint 脚本 然后我的代码质量工作应该启动声纳扫描仪泊坞窗实例 检查我的代码并
  • Linux下的C#,Process.Start()异常“没有这样的文件或目录”

    我在使用 Process 类调用程序来启动程序时遇到问题 可执行文件的层次结构位于 bin 目录下 而当前工作目录需要位于 lib 目录下 project bin a out this is what I need to call lib
  • 即使 makefile 和源代码存在,为什么“Build Project”在 Eclipse Helios CDT 中显示为灰色?

    我无法构建我的项目 我在 Eclipse Helios 中创建了一个新的 CDT 项目 并告诉它使用现有的源代码和 makefile 这两者都正确显示在 Package 和 Project 视图中 然而 项目 菜单中的 构建全部 和 构建项
  • 在键盘热插拔上加载模块

    我正在尝试学习如何为 Linux 系统编写模块和驱动程序 类似于this https unix stackexchange com questions 120839 usb kernel module does not load on de
  • 跟踪 pthread 调度

    我想做的是创建某种图表 详细说明 Linux 中 两个 线程的执行情况 我不需要查看线程的作用 只需查看它们何时被安排以及持续多长时间 基本上是一条时间线 在过去的几个小时里 我一直在互联网上搜索跟踪 pthread 调度的方法 不幸的是
  • 使用 C++ 输出字符串覆盖 Linux 终端上的最后一个字符串

    假设我有一个命令行程序 有没有办法让我说的时候 std cout lt lt stuff 如果我不做std cout lt lt n 在另一个之间std cout lt lt stuff 东西的另一个输出将覆盖同一行上的最后一个东西 清理行
  • 无法为 Python 3.4 创建工作虚拟环境

    I 安装Python 3 4 2 https docs python org 3 using unix html building python和我的 Linux Mint 17 1 中的 Virtualenv 12 0 5 然后我尝试创建
  • 我在哪里可以学习如何使 C++ 程序与操作系统 (Linux) 交互

    我是一个 C 初学者 我想创建与操作系统交互的小程序 使用 Kubuntu Linux 到目前为止 我还没有找到任何教程或手册来让 C 与操作系统交互 在 PHP 中 我可以使用命令 exec 或反引号运算符来启动通常在控制台中执行的命令
  • 使用 MongoDB docker 镜像停止虚拟机而不丢失数据

    我已经在 AWS EC2 上的虚拟机中安装了官方的 MongoDB docker 映像 并且数据库上已经有数据 如果我停止虚拟机 以节省过夜费用 我会丢失数据库中包含的所有数据吗 在这些情况下我怎样才能让它持久 有多种选择可以实现此目的 但
  • 测试linux下磁盘空间不足

    我有一个程序 当写入某个文件的磁盘空间不足时 该程序可能会死掉 我不确定是否是这种情况 我想运行它并查看 但我的测试服务器不会很快耗尽空间 有什么办法可以嘲笑这种行为吗 看起来没有任何方法可以在 Ubuntu 中设置文件夹 文件大小限制 并
  • 原生 Linux 应用程序可像 ResHacker 一样编辑 Win32 PE

    我想运行自动修改 dll服务 用户提交特定的 dll 我在服务器上修改它 然后用户可以下载 dll的修改版本 是否有任何本机 Linux 应用程序提供常见的 Win32 PE 修改功能 例如图标 字符串 加速器 对话等 至少提供命令行或脚本
  • /proc/PID 文件格式

    我想从中检索一些流程信息 proc目录 我的问题如下 中的文件是否有标准格式 proc PID 例如 有这个proc PID status文件与Name t ProcName在第一行 我可以在其他地方用空格代替这个文件吗 t或者类似的东西
  • 退出 bash 脚本但保持进程运行

    我正在运行服务器 需要使用参数执行以下命令 这些脚本目前工作得很好 但问题是当我运行脚本时我无法返回到控制台 它在控制台中保持运行 如果我强行停止它 那么该过程也会停止 我想继续运行该进程并返回到控制台 bin sh php home st
  • Docker DNS 设置

    我尝试使用自定义网络和 dos 设置创建 docker 容器 docker网络创建 driver bridge opt com docker network bridge enable ip masquerade true opt com
  • 静态链接共享对象?或者损坏的文件?

    我有一个从专有来源获得的库 我正在尝试链接它 但出现以下错误 libxxx so 文件无法识别 文件格式无法识别 Collect2 ld 返回 1 退出状态 确实 ldd libxxx so statically linked 这究竟意味着
  • 如何从“git log”中查看 Git 中的特定版本?

    My git log显示为 enter code here git trial git log commit 4c5bc66ae50780cf8dcaf032da98422aea6e2cf7 Author king lt email pro
  • 通过 SSH 将变量传递给远程脚本

    我正在通过 SSH 从本地服务器在远程服务器上运行脚本 首先使用 SCP 复制该脚本 然后在传递一些参数时调用该脚本 如下所示 scp path to script server example org another path ssh s
  • 远程linux服务器到远程linux服务器大型稀疏文件复制 - 如何?

    我有两台 CentOS 5 4 服务器 每台服务器上都安装了 VMware Server 假设我始终对 vmware 虚拟机使用稀疏文件 将虚拟机文件从一台服务器复制到另一台服务器的最可靠 最快速的方法是什么 虚拟机的文件复制起来很痛苦 因
  • perf stat中的cycles注释是什么意思

    8 014196 task clock 0 004 CPUs utilized 204 context switches 0 025 M sec 32 cpu migrations 0 004 M sec 0 page faults 0 0

随机推荐

  • 8.3雾

    先上图 其实很简单 就是光照和雾的系数插值 雾出现在与摄像机的一定距离 在这个距离内 没雾 在这个距离外 越远雾越大 即雾的系数从0到1 光照系数从1到0 在shader中 代码如下 cbuffer cbFixed float gFogSt
  • 安川服务器输入输出信号,最全PLC输入输出各种回路接线!

    原标题 最全PLC输入输出各种回路接线 一 输入回路接线 输入电路是PLC接收信号的端口 对模拟量来说一般为0 40MA直流电流或0 10V直流电压信号 输入接线是指外部输入器件 任何无源的触点和集电极开路的NPN三极管 接通输入回路闭合
  • Nginx双机主备(Keepalived实现)

    前言 首先介绍一下Keepalived 它是一个高性能的服务器高可用或热备解决方案 起初是专为LVS负载均衡软件设计的 Keepalived主要来防止服务器单点故障的发生问题 可以通过其与Nginx的配合实现web服务端的高可用 Keepa
  • 截取鼠标指针的图片

    Windows下的鼠标经常会显示出不同的样子以提示当前的操作 所以对于很多程序来说截取鼠标指针当前的图片并进行分析是很有用处的 下面分析两种截取鼠标指针的图片的方法并给出一个示范程序 截取鼠标指针的图片首先要取得鼠标的句柄 然后用API函数
  • ESP32学习笔记05-串口事件方式读取数据

    串口中断方式处理数据 事件机构体 typedef struct uart event type t type lt UART event type size t size lt UART data size for UART DATA ev
  • leetcode 142.环形链表2

    leetcode 142 环形链表2 给定一个链表的头节点 head 返回链表开始入环的第一个节点 如果链表无环 则返回 null 如果链表中有某个节点 可以通过连续跟踪 next 指针再次到达 则链表中存在环 为了表示给定链表中的环 评测
  • VASP - Bader Charge Analysis

    Bader电荷分析 用于分析原子周围的电荷密度 从而得到原子价电子数 下载 Bader Charge Analysis 工具包 下载地址为 http theory cm utexas edu henkelman code bader 下载
  • C++中的friend详细解析

    https blog csdn net u012861978 article details 52095607
  • 奇偶数排序

    题目描述 给定一个整数数组 请调整数组的顺序 使得所有奇数位于数组前半部分 所有偶数位于数组后半部分 要求时间复杂度为O n 分析与解法 最容易想到的办法是从头到尾扫描这个数组 每遇到一个偶数 就把他单独取出来 然后把该偶数后面的所有数往前
  • vulnhub之vegeta

    目录 一 主机发现 二 端口扫描 四 信息收集 五 cyberchef解密 1 两道base64解密 2 save保存 3 qrcode module 4 二维码提取工具zbaring 六 大字典跑目录 七 bulma 八 音频分析软件au
  • spark-2.2.2-bin-hadoop2.7 安装

    1 上传spark 2 2 2 bin hadoop2 7 tgz 2 解压文件 tar zxvf spark 2 2 2 bin hadoop2 7 tgz C usr local 3 进入conf 下把spark env sh temp
  • 『NLP经典项目集』05:新年到,飞桨带你对对联

    基于seq2seq的对联生成 对联 是汉族传统文化之一 是写在纸 布上或刻在竹子 木头 柱子上的对偶语句 对联对仗工整 平仄协调 是一字一音的汉语独特的艺术形式 是中国传统文化瑰宝 这里 我们将根据上联 自动写下联 这是一个典型的序列到序列
  • Mysql 检查表是否存在并创建表,检查列是否存在并新增、修改、删除列

    判断表是否存在 不存在就可新增 CREATE TABLE IF NOT EXISTS example ENGINE InnoDB AUTO INCREMENT 1 DEFAULT CHARSET utf8 判断表字段是否存在 不存在就可新增
  • springboot好在哪

    springboot好在哪 欢迎观看 第一篇 欢迎观看 你好 这是本人第一次使用 新手发文 多多包涵 第一篇 以往的ssm框架整合通常有两种形式 一种是xml形式 一种是注解形式 不管是xml还是注解 基本都会有一大堆xml标签配置 其中有
  • C++学习之list的实现

    在了解学习list实现之前我们首先了解一下关于迭代器的分类 按功能分类 正向迭代器 反向迭代器 const正向迭代器 const反向迭代器 按性质分类 单向迭代器 只能 例如单链表 双向迭代器 可 也可 例如双链表 map和set 随机迭代
  • Unity3D 监控面板显示数据(Inspector)

    using System Collections using System Collections Generic using UnityEngine using UnityEngine Serialization AddComponent
  • 机器学习十大算法之四:SVM(支持向量机)

    SVM 支持向量机 支持向量机 Support Vector Machine 是一种十分常见的分类器 曾经火爆十余年 分类能力强于NN 整体实力比肩LR与RF 核心思路是通过构造分割面将数据进行分离 寻找到一个超平面使样本分成两类 并且间隔
  • IC卡和ID卡

    定义 最常用的感应卡分为ID卡和IC卡两种 IC卡全称集成电路卡 Integrated Circuit Card 又称智能卡 Smart Card 可读写 容量大 有加密功能 数据记录可靠 使用更方便 如一卡通系统 消费系统等 ID卡全称身
  • java.sql.SQLException: Statement.executeQuery() cannot issue statements that do not produce result

    java sql SQLException Statement executeQuery cannot issue statements that do not produce result sets 解决 看看自己的java代码里的 sq
  • Linux内核内存检测工具KASAN

    KASAN k z n KASAN 是 Kernel Address Sanitizer 的缩写 它是一个动态检测内存错误的工具 主要功能是检查内存越界访问和使用已释放的内存等问题 KASAN 集成在 Linux 内核中 随 Linux 内