日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux内核内存检测工具KASAN

發布時間:2023/12/3 linux 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux内核内存检测工具KASAN 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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損壞,很有效。

總結

以上是生活随笔為你收集整理的Linux内核内存检测工具KASAN的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。