How KASAN Detects Kernel Memory Errors: Shadow Memory, Redzones, and Log Analysis

This article explains the inner workings of KernelAddressSanitizer (KASAN) in the Linux kernel, covering how to enable it, the shadow‑memory mechanism, redzone handling for heap, global and stack allocations, and how to interpret the detailed KASAN bug reports generated at runtime.

Liangxu Linux
Liangxu Linux
Liangxu Linux
How KASAN Detects Kernel Memory Errors: Shadow Memory, Redzones, and Log Analysis

1. Introduction

KASAN (KernelAddressSanitizer) is a dynamic memory‑error detector for the Linux kernel. It can catch out‑of‑bounds accesses, use‑after‑free, and other memory corruptions by instrumenting every memory access and checking a corresponding shadow memory.

2. Enabling KASAN

To use KASAN you must enable the kernel configuration options:

CONFIG_SLUB_DEBUG=y
CONFIG_KASAN=y

SLUB_DEBUG used to be required because early KASAN depended on it; recent kernels no longer need the dependency, but keeping it on provides richer diagnostics.

3. Detection Mechanism – Shadow Memory

KASAN reserves one‑eighth of the address space as shadow memory . For each 8‑byte aligned region of real memory there is one byte in shadow memory that encodes the accessibility of the bytes:

Value 0 – all 8 bytes are valid.

Value 1..7 – the first N bytes are valid, the rest are poisoned.

Negative value – the whole 8‑byte region is invalid.

During compilation the compiler inserts calls to __asan_loadN or __asan_storeN before each memory access, where N is the access size.

Shadow memory layout
Shadow memory layout

4. How Checks Are Performed

For an 8‑byte access the generated code computes the shadow address as (addr >> 3) + KASAN_SHADOW_OFFSET and checks whether *shadow == 0. If the value is non‑zero, a bug is reported.

For smaller accesses (1, 2, or 4 bytes) the check is adjusted:

if (*shadow && *shadow < ((addr & 7) + N))
    report_bug();

Here N is the access size. The expression ensures that the access does not cross the poisoned boundary.

4.1 Allocation – Buddy System and SLUB

When the buddy allocator reserves pages, KASAN fills the corresponding shadow memory with 0 (all bytes accessible). When pages are freed, the shadow bytes are set to 0xFF, turning the region into a use‑after‑free detection zone.

SLUB objects receive a redzone after the usable part. For example, an object allocated with kmalloc(20) from the kmalloc‑32 cache occupies 32 bytes; the first 20 bytes are marked as accessible (shadow value 20), and the remaining 12 bytes are poisoned with 0xFC (redzone).

4.2 Global Variables

The compiler generates a constructor function named _GLOBAL__sub_I_<file>_<var> for each global variable. This function calls __asan_register_globals() with a struct kasan_global describing the variable’s address, size, redzone size, name, and source location.

struct kasan_global {
    const void *beg;          // start address
    size_t size;              // original size
    size_t size_with_redzone; // rounded to 32‑byte alignment
    const void *name;         // variable name string
    const void *module_name;  // source file path
    unsigned long has_dynamic_init;
    const struct kasan_source_location *location;
};

During early kernel boot the do_ctors() routine walks the __ctors_start__ctors_end range and invokes all such constructors, thereby initializing the shadow memory for globals.

4.3 Stack Variables

For stack allocations the compiler also adds redzones. A typical function compiled with KASAN contains a hidden buffer before the real variable (e.g., rz1[32]) and after it (e.g., rz2[56]). The compiler writes the appropriate shadow values before the function runs and clears them on exit.

5. KASAN Bug Report Format

A typical KASAN log contains:

Bug type (e.g., "out of bounds access").

Faulting address and size of the offending operation.

Process and CPU information.

Call trace showing the kernel functions involved.

Object information (cache name, object address, redzone contents).

Memory state around the buggy address, displaying shadow bytes.

Example excerpt (truncated for brevity):

BUG: AddressSanitizer: out of bounds access in kmalloc_oob_right+0x65/0x75
Write of size 1 by task modprobe/1689
Object ffff8800693bc558: 6b6b6b6b... (SLUB object)
Shadow bytes around ffff8800693bc5d3: 00 00 00 00 00 00 00 00 03 fc fc ...
^

The shadow byte 03 indicates that only the first three bytes of the 8‑byte chunk are valid, confirming an out‑of‑bounds write at offset 123.

6. Minimal Reproducible Module

The article provides a tiny kernel module that deliberately writes past the allocated size to trigger KASAN:

static void __init kmalloc_oob_right(void)
{
    char *ptr;
    size_t size = 123;
    ptr = kmalloc(size, GFP_KERNEL);
    if (!ptr) {
        pr_err("Allocation failed
");
        return;
    }
    ptr[size] = 'x';   // out‑of‑bounds write
    kfree(ptr);
}
module_init(kmalloc_oob_right);
MODULE_LICENSE("GPL");

Running this module on a kernel built with KASAN produces the detailed log described in section 5, allowing developers to verify the detection pipeline.

7. Conclusions

KASAN provides a fast, compile‑time‑instrumented way to catch memory errors in the kernel. By mapping real memory to shadow memory, inserting runtime checks, and poisoning freed regions, it can pinpoint the exact location, size, and call stack of a bug. The generated reports are rich enough to reconstruct the offending code path, but interpreting them requires understanding of shadow‑memory values, redzone layout, and the kernel’s allocation subsystems.

KASAN memory layout diagram
KASAN memory layout diagram
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

kernelLinux kernelMemory DebuggingKASANShadow MemoryUse-After-FreeOut-of-Bounds
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.