Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

KASAN: Linux Kernel Memory Error Detection Tool

Tech Aug 29 9

KASAN stands for Kernel Address Sanitizer, a dynamic memory error detection tool primarily used to check for memory out-of-bounds access and use-after-free issues.

1. How to Enable KASAN

Add the following configuration to the kernel defconfig:

CONFIG_SLUB_DEBUG=y
CONFIG_SLUB_DEBUG_ON=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y

Since 1/8 of memory is used for shadow memory, the available memory decreases by 1/8. For example, with 8 GB of memory, after enabling KASAN, MemTotal is approximately 6.72 GB.

$ cat /proc/meminfo | grep MemTotal
MemTotal:  6723358 kB

2. Overview of KASAN Principles

KASAN uses extra memory to mark the state of usable memory. This extra memory is called shadow memory. KASEN reserves 1/8 of the total memory for shadow memory. It fills shadow memory with special magic numbers and checks the corresponding shadow memory on every load/store to determine if the operation is valid. Every 8 bytes of memory (8-byte aligned) are marked by 1 byte of shadow memory. If all 8 bytes are accessible, the shadow memory value is 0. If N consecutive bytes (1 ≤ N ≤ 7) are accessible, the shadow value is N. If all 8 bytes are invalid, the shadow value is negative.

For example:

adrp x0, 0xffffffc08821e810
mov w1, #0x5
bl __asan_store1
strb w1, [x0]

This assembly writes the value 5 to address 0xffffffc08821e810. When KASAN is enabled, the compiler automatically inserts the bl __asan_store1 instruction (shown in red). The __asan_store1 function checks whether the shadow memory for that address allows writing 1 byte. The actual memory access is the blue strb instruction.

3. How to Determine if a Memory Access is Valid Based on Shadow Memory

The kernel implements shadow memory checks mainly through __asan_load##size() and __asan_store##size() functions. How does KASAN determine validity based on the accessed address and its shadow memory 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: if *shadow_memory == 0, the access is valid; otherwise invalid.
  2. When accessing N bytes (N = 1,2,4): if (*shadow && *shadow > ((unsigned long)addr & 7) + N), the access is valid; otherwise invalid.

4. Shadow Memory for Buddy System Allocations

(1) Allocating Memory from Buddy System

  • Step 1: Suppose allocating 4 pages from buddy system. The system first removes a memory block from the order=2 list.
  • Step 2: Find the corresponding shadow memory using the relation: Shadow_addr = (addr >> 3) + KASAN_SHADOW_OFFSET. Right-shifting by 3 bits because 8 bytes of memory correspond to 1 byte of shadow memory.
  • Step 3: Fill the shadow memory. For allocated 4 pages (all accessible), fill with 0.

(2) Freeing Memory to Buddy System

  • Step 1: Free 4 pages from the order=2 list.
  • Step 2: Find the shadow memory using the same relation.
  • Step 3: Fill the corresponding shadow memory region (2 KB = 16 KB / 8) with 0xFF (KASAN_FREE_PAGE).

5. Shadow Memory for SLUB Allocations

(1) Allocating Memory from SLUB Cache

  • Step 1: Suppose allocating 20 bytes from kmalloc-32 cache. The remaining 12 bytes are marked as inaccessible by KASAN.
  • Step 2: Find the shadow memory using the memory address mapping.
  • Step 3: Fill the shadow memory with 00 00 04 FC. The meanings:
    • First two 00: bytes 0–15 are accessible.
    • 04: bytes 16–23 only the first 4 bytes are accessible.
    • FC: bytes 24–31 are KASAN_KMALLOC_REDZONE, inaccessible.
  • Step 4: Save the allocation call stack.
  • Step 5: If the redzone is accessed, KASAN reports an out-of-bounds bug.

(2) Freeing Memory from SLUB Cache

  • Step 1: Free 20 bytes from kmalloc-32 cache.
  • Step 2: Find the shadow memory address.
  • Step 3: Fill the 4 bytes of shadow memory with FB (KASAN_KMALLOC_FREE).
  • Step 4: Save the free call stack.
  • Step 5: If memory corresponding to FB is accessed, KASAN reports a use-after-free bug.

6. Shadow Memory for Other Allocation Types

Global variables and stack-allocated memory follow similar principles but with implementation differences.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.