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

  • 批量删除文件名中包含 BASH 中特殊字符的子字符串

    我的目录中有一个文件列表 opencv calib3d so2410 so opencv contrib so2410 so opencv core so2410 so opencv features2d so2410 so opencv
  • 找不到包“gdk-pixbuf-2.0”

    我正在尝试在 Amazon Linux 发行版实例上构建 librsvg 我已经通过 yum 安装了大部分依赖项 其中一些在实例上启用的默认 yum 存储库中不可用 因此必须从头开始构建它们 我已经走了很远 但还停留在最后一点 跑步时sud
  • 仅使用containerd(不使用Docker)修剪容器镜像

    如果我刚刚containerd安装在 Linux 系统上 即 Docker 是not安装 如何删除未使用的容器映像以节省磁盘空间 Docker 就是这么方便docker system prune https docs docker com
  • 执行命令而不将其保留在历史记录中[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在进行软件开发时 经常需要在命令行命令中包含机密信息 典型示例是将项目部署到服务器的凭据设置为环境变量 当我不想将某些命令存储在命令历史记
  • docker 非 root 绑定安装权限,WITH --userns-remap

    all 尝试让绑定安装权限正常工作 我的目标是在容器中绑定安装卷 以便 a 容器不以 root 用户身份运行入口点 二 docker daemon 配置了 userns remap 这样容器 主机上没有 root c 我可以绑定挂载和读 写
  • 在centos中安装sqlite3 dev和其他包

    我正在尝试使用 cpanel 在 centos 机器上安装 sqlite dev 和其他库 以便能够编译应用程序 我对 debian 比 centos 更熟悉 我知道我需要的库是 libsqlite3 dev libkrb5 dev lib
  • 在 Linux 上以编程方式设置 DNS 名称服务器

    我希望能够通过我的 C C 程序为 Linux 上的 DNS 名称服务器添加 IP 地址 我在一个带有只读 etc resolv conf 的嵌入式平台上 这意味着我不能简单地将 nameserver xxx xxx xxx xxx 行添加
  • 无需超级用户即可在 Linux 中打开 RAW 套接字

    我必须编写一个在 Linux 上运行的 ping 函数 语言是 C 所以 C 也可以 在网上搜索并查看源代码ping命令 事实证明我应该创建一个原始套接字 icmp sock socket AF INET SOCK RAW IPPROTO
  • GMail 421 4.7.0 稍后重试,关闭连接

    我试图找出为什么它无法使用 GMail 从我的服务器发送邮件 为此 我使用 SwiftMailer 但我可以将问题包含在以下独立代码中
  • 尽管 if 语句,Visual Studio 仍尝试包含 Linux 标头

    我正在尝试创建一个强大的头文件 无需更改即可在 Windows 和 Linux 上进行编译 为此 我的包含内容中有一个 if 语句 如下所示 if defined WINDOWS include
  • 使用非规范地址检索内存数据会导致 SIGSEGV 而不是 SIGBUS

    我无法使用以下汇编代码产生 总线错误 这里我使用的内存地址不是合法的 规范地址 那么 我怎样才能触发该错误呢 我在带有 NASM 2 14 02 的 Ubuntu 20 04 LTS 下运行这段代码 但它会导致负载出现 SIGSEGV 分段
  • 使用循环在 C 中管道传输两个或多个 shell 命令

    我正在尝试执行ls wc l通过 C 语言程序 而不是使用命令行 这是我当前的工作代码 int main int pfds 2 pipe pfds pid t pid fork if pid 0 The child process clos
  • 为什么 fopen("any_path_name",'r') 不给出 NULL 作为返回值?

    在调试一些代码时 我得到如下内容 include
  • CMake 链接 glfw3 lib 错误

    我正在使用 CLion 并且正在使用 glfw3 库编写一个程序 http www glfw org docs latest http www glfw org docs latest 我安装并正确执行了库中的所有操作 我有 a 和 h 文
  • 在 Mono 上运行 .Net MVC5 应用程序

    我正在 Windows 上的 Visual Studio 2013 中开发 Net 4 5 1 MVC5 应用程序 现在我想知道 是否可以在Linux Ubuntu 12 04 上运行这个应用程序 可以使用OWIN吗 Owin 可以自托管运
  • 如何在 Linux 中使用 C 语言使用共享内存

    我的一个项目有点问题 我一直在试图找到一个有据可查的使用共享内存的例子fork 但没有成功 基本上情况是 当用户启动程序时 我需要在共享内存中存储两个值 当前路径这是一个char and a 文件名这也是char 根据命令参数 启动一个新进
  • C修改printf()输出到文件

    有没有办法修改printf为了将字符串输出到文件而不是控制台 我尝试在互联网上查找一些内容 发现了类似的电话dup dup2 and fflush这可能与此有关 EDIT 也许我不清楚 问题是这是C考试问题 问题如下 解释一个通常将字符串输
  • 错误:“rjags”的包或命名空间加载失败

    在终端的 conda 环境之一中 我能够成功安装包 rjags 但是 当我在该环境中运行 R 并运行库 rjags 时 出现以下错误 加载所需的包 coda 错误 rjags 的包或命名空间加载失败 rjags 的 loadNamespac
  • Apache 访问 Linux 中的 NTFS 链接文件夹

    在 Debian jessie 中使用 Apache2 PHP 当我想在 Apache 的文档文件夹 var www 中创建一个新的小节时 我只需创建一个指向我的 php 文件所在的外部文件夹的链接 然后只需更改该文件夹的所有者和权限文件夹
  • 如何在 Mac OSX Mavericks 中正确运行字符串工具?

    如何在 Mac OSX Mavericks 中正确运行字符串工具 我尝试按照我在网上找到的示例来运行它 strings a UserParser class 但我收到此错误 错误 Applications Xcode app Content

随机推荐

  • 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 内