Skip to content

KASLR and KAISER

1. KASLR — Kernel Address Space Layout Randomization

KASLR randomizes the virtual address at which the kernel is loaded.

Simplified pseudocode

// Normal kernel base address
#define KERNEL_BASE 0xffffffff81000000

// Choose a random offset
uint64_t random_offset = get_random_offset();

// Randomized kernel base
uint64_t kernel_base = KERNEL_BASE + random_offset;

// Load kernel at the randomized address
load_kernel(kernel_base);

Example

Without KASLR:

Kernel base = 0xffffffff81000000

With KASLR:

Kernel base = 0xffffffffa7200000

The exact address changes between boots.

Why?

An attacker may need kernel addresses for attacks such as ROP.

Without KASLR:

Attacker knows:
    kernel_function = 0xffffffff81012340

        ↓

Can potentially construct an attack
using known kernel addresses.

With KASLR:

Attacker knows only:

    kernel_function = ?????????

        ↓

Must discover the randomized address first.

2. The problem KAISER solves

Traditionally, the kernel was mapped into the page table of
a user process even though user-mode code was not allowed
to access it.

Simplified:

Process Page Table
│
├── User memory
│      USER = 1
│
└── Kernel memory
       USER = 0
       PRESENT = 1

USER = 0 means that user-mode code cannot access the page.

But the kernel mapping still exists in the page tables.

Conceptually:

User program
     │
     │ access kernel virtual address
     ↓
Page table
     │
     │ Kernel mapping exists
     ↓
Permission check
     │
     │ USER = 0
     ↓
Access denied / page fault

The problem is that the existence of the mapping can affect
microarchitectural structures such as address-translation
caches.

An attacker can measure timing differences and infer whether
an address is mapped.

This can defeat the purpose of KASLR.

3. KAISER — Kernel Address Isolation

KAISER changes the page-table organization.

Instead of keeping kernel mappings in the page table while
running user code, KAISER uses separate page tables.

User / Shadow page table

User Page Table
│
├── User memory
│
├── Program
│
├── Libraries
│
└── Kernel memory
       NOT MAPPED

Kernel page table

Kernel Page Table
│
├── User memory
│
└── Kernel memory
       MAPPED

The important difference is:

OLD:

Kernel mapping exists
        ↓
Access forbidden by permission
        ↓
Potential side channel


KAISER:

Kernel mapping does NOT exist
        ↓
No kernel translation available
        ↓
Side channel is removed

4. Switching between the page tables

On x86, CR3 identifies the current page-table hierarchy.

Simplified:

// Running user program

load_cr3(user_page_table);

// Execute user code
run_user_program();

When entering the kernel:

// System call / interrupt occurs

load_cr3(kernel_page_table);

// Execute kernel code
run_kernel_code();

When returning to user mode:

// Return from kernel

load_cr3(user_page_table);

// Continue user program
continue_user_program();

Conceptually:

             SYSTEM CALL
User mode ───────────────────→ Kernel mode
   │                              │
   │                              │
   │ CR3 = user_page_table        │ CR3 = kernel_page_table
   │                              │
   ↓                              ↓
User mappings                 Kernel mappings
Kernel absent                 Kernel present

5. Why this defeats the address-leaking attack

Before KAISER

User page table

Virtual address
      │
      ↓
Page table
      │
      ├── User mapping
      │
      └── Kernel mapping
              │
              ↓
        Translation exists
              │
              ↓
       Microarchitectural
       side channel
              │
              ↓
      Attacker learns that
      the address is mapped
              │
              ↓
       KASLR weakened

With KAISER

User page table

Virtual address
      │
      ↓
Page table
      │
      ├── User mapping
      │
      └── Kernel mapping
              X
           NOT PRESENT
Feature KASLR KAISER
Full name Kernel Address Space Layout Randomization Kernel Address Isolation
Main idea Randomize kernel addresses Remove kernel mappings from user page tables
Main goal Make kernel addresses difficult to predict Prevent user space from learning kernel address information
Changes addresses? Yes No
Changes page tables? Not primarily Yes
Uses separate page tables? No Yes
Defends against address-discovery side channels? By itself, not sufficiently Yes

KPTI

It is essentially the production Linux version of the page-table isolation idea used by KAISER, introduced as a major mitigation for Meltdown.