Linux kernel memory detection tool KASAN

BOTTOM ['kæzən]

KASAN is the abbreviation of Kernel Address Sanitizer. It is a tool for dynamically detecting memory errors. Its main function is to check memory out-of-bounds access and use of released memory. KASAN is integrated in the Linux kernel, released with the Linux kernel code, and maintained and developed by the kernel community. This article briefly introduces the principle and usage of KASAN.

1. How to open the KASAN function

Kernel defconfig adds the following configuration:

CONFIG_SLUB_DEBUG=y

CONFIG_SLUB_DEBUG_ON=y

CONFIG_KASAN =y

CONFIG_KASAN_INLINE=y

Since 1/8 of the memory is used for shadow memory, the available memory will be reduced by 1/8 , such as 8GB of memory, after KASAN is turned on, MemTotal is about 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. Overview of KASAN principle

KASAN uses extra memory to mark the status of available memory. This part of extra memory is called shadow memory (shadow area), and KASAN uses 1/8 of the memory as shadow memory. Use a special magic num to fill the shadow memory, and check the corresponding shadow memory every time the memory is loaded/stored to determine whether the operation is valid. Continuous 8 bytes memory (8 bytes align) is marked with 1 byte shadow memory.

If 8 bytes memory can be accessed, the value of shadow memory is 0; if consecutive N (1 =< N <= 7) bytes can be accessed, then the value of shadow memory is N; if 8 bytes memory access is invalid, then The value of shadow memory is negative.

For example:

adrp x0, 0xffffffc08821e810

mov w1,#0x5

bl_asan_store1

strb w1,[x0]

 This assembly instruction is to write 5 to the address 0xffffffc08821e810. When Kasan is turned on, the compiler will automatically insert the red bl __asan_store1 instruction. The __asan_store1 function is to detect whether the value of the shadow memory corresponding to an address is allowed to write 1 byte. The blue assembly instruction is real memory access.

3. How to judge whether the memory access operation is legal according to the value of shadow memory?

The realization of the shadow memory detection principle is mainly the __asan_load##size() and __asan_store##size() functions. How does KASAN judge whether the access is legal based on the accessed address and the corresponding shadow memory status value ?

__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) When accessing 8 bytes, *shadow_memory=0, the access is valid, otherwise it is invalid;

2) When accessing N bytes (N=1,2,4), if (*shadow && *shadow > ((unsigned long)addr & 7) +N) )

Access is valid; otherwise, it is invalid; ( misunderstood, need to compare the source code )

4. How to fill the shadow memory value allocated by the partner system

 (1) Allocate memory from buddy system

 Step1: If 4 pages are allocated from the buddy system, the system first removes a piece of memory from the linked list with order=2;

Step2: Then find the corresponding shadow memory according to the corresponding relationship between shadow memory address and memory address; the corresponding relationship is:

Shadow_addr = (addr >> 3) + KASAN_SHADOW_OFFSET, the reason for shifting right by 3 bits is that 8 byte memory corresponds to 1 byte shadow memory;

Step3: Fill the content of the shadow memory, the allocated 4 pages can all be accessed, and the filling is 0;

(2) Release memory from buddy system

 Step1: Release 4 pages from the linked list with buddy system order = 2;

Step2: According to the corresponding relationship between shadow memory addr and memory addr, find shadow memory;

Step3: Fill the memory area corresponding to shadow memory 2KB (16KB/8) with 0xFF (KASAN_FREE_PAGE);

5. How to fill the shadow memory value allocated by slub

(1) Allocate memory from the slub cache

 

Step1: kmalloc(20) will match the kmem_cache of kmalloc-32, and the actual allocated object size is 32 bytes. The remaining 12 bytes KASAN will be marked as inaccessible;

Step2: Find shadow memory according to the corresponding relationship between shadow memory addr and memory addr;

Step3: The content of filling shadow memory is 00 00 04 FC, the specific meaning is:

1) The first 2 00 means that the 0~15 byte can be accessed
2) 04 means that only the 16~23 byte can be accessed by the first 4 bytes
3) FC means that the 24~31 byte is KASAN_KMALLOC_REDZONE and cannot be accessed

Step4: save the call-stack of memory allocation;

Step5: If the REDZONE area is accessed, KASAN will report out-of-bounds bug;

(2) Release memory from slub cache

Step1: free 20 bytes memory from the slub cache (kmalloc-32);

Step2: Find the shadow memory addr according to the memory addr;

Step3: Fill 4 bytes of shadow memory as FB(KASAN_KMALLOC_FREE);

Step4: save the call-stack of slub free;

Step5: If the memory corresponding to FB is accessed, KASAN will report a use-after-free bug;

6. How to fill shadow memory allocated in other forms?

The memory filling principle of global variable/stack allocation is similar to the previous ones, but there are some differences in implementation, so I won’t go into details here.

7. Example of KASAN report bug

 

 

2. Summary

KASAN manages the legitimacy of memory access by establishing shadow memory, which can effectively detect problems such as memory out of bounds, but cannot find the content rewriting of legal memory caused by logical problems.

Generally, it is very effective for DDR damage.

Guess you like

Origin blog.csdn.net/y13182588139/article/details/125814705