what is KASLR

일단 kalsr에 대해 간단히 설명을 해보자면,

C
========================================================================================================================
    Start addr    |   Offset   |     End addr     |  Size   | VM area description
========================================================================================================================
                  |            |                  |         |
 0000000000000000 |    0       | 00007fffffffffff |  128 TB | user-space virtual memory, different per mm
__________________|____________|__________________|_________|___________________________________________________________
                  |            |                  |         |
 0000800000000000 | +128    TB | ffff7fffffffffff | ~16M TB | ... huge, almost 64 bits wide hole of non-canonical
                  |            |                  |         |     virtual memory addresses up to the -128 TB
                  |            |                  |         |     starting offset of kernel mappings.
__________________|____________|__________________|_________|___________________________________________________________
                                                            |
                                                            | Kernel-space virtual memory, shared between all processes:
____________________________________________________________|___________________________________________________________
                  |            |                  |         |
 ffff800000000000 | -128    TB | ffff87ffffffffff |    8 TB | ... guard hole, also reserved for hypervisor
 ffff880000000000 | -120    TB | ffff887fffffffff |  0.5 TB | LDT remap for PTI
 ffff888000000000 | -119.5  TB | ffffc87fffffffff |   64 TB | direct mapping of all physical memory (page_offset_base)
 ffffc88000000000 |  -55.5  TB | ffffc8ffffffffff |  0.5 TB | ... unused hole
 ffffc90000000000 |  -55    TB | ffffe8ffffffffff |   32 TB | vmalloc/ioremap space (vmalloc_base)
 ffffe90000000000 |  -23    TB | ffffe9ffffffffff |    1 TB | ... unused hole
 ffffea0000000000 |  -22    TB | ffffeaffffffffff |    1 TB | virtual memory map (vmemmap_base)
 ffffeb0000000000 |  -21    TB | ffffebffffffffff |    1 TB | ... unused hole
 ffffec0000000000 |  -20    TB | fffffbffffffffff |   16 TB | KASAN shadow memory
__________________|____________|__________________|_________|____________________________________________________________
                                                            |
                                                            | Identical layout to the 56-bit one from here on:
____________________________________________________________|____________________________________________________________
                  |            |                  |         |
 fffffc0000000000 |   -4    TB | fffffdffffffffff |    2 TB | ... unused hole
                  |            |                  |         | vaddr_end for KASLR
 fffffe0000000000 |   -2    TB | fffffe7fffffffff |  0.5 TB | cpu_entry_area mapping
 fffffe8000000000 |   -1.5  TB | fffffeffffffffff |  0.5 TB | ... unused hole
 ffffff0000000000 |   -1    TB | ffffff7fffffffff |  0.5 TB | %esp fixup stacks
 ffffff8000000000 | -512    GB | ffffffeeffffffff |  444 GB | ... unused hole
 ffffffef00000000 |  -68    GB | fffffffeffffffff |   64 GB | EFI region mapping space
 ffffffff00000000 |   -4    GB | ffffffff7fffffff |    2 GB | ... unused hole
 ffffffff80000000 |   -2    GB | ffffffff9fffffff |  512 MB | kernel text mapping, mapped to physical address 0
 ffffffff80000000 |-2048    MB |                  |         |
 ffffffffa0000000 |-1536    MB | fffffffffeffffff | 1520 MB | module mapping space
 ffffffffff000000 |  -16    MB |                  |         |
    FIXADDR_START | ~-11    MB | ffffffffff5fffff | ~0.5 MB | kernel-internal fixmap range, variable size and offset
 ffffffffff600000 |  -10    MB | ffffffffff600fff |    4 kB | legacy vsyscall ABI
 ffffffffffe00000 |   -2    MB | ffffffffffffffff |    2 MB | ... unused hole
__________________|____________|__________________|_________|___________________________________________________________

일단, 최신 커널 기준으로 커널에는 크게 두가지 축이 있음

하나는 일반적인 커널이미지 base 하나는 메모리 영역에 대한 base

커널이미지 base → 커널의 .text 영역과 data 영역, 모듈의 text영역과 data 영역

메모리 영역에 대한 base → Directmap , vmalloc , ioremap(mmio)., vmemmap

기본적으로 KALSR은 켜져 있는 경우가 많기에 이 두가지 축을 base에 특정 오프셋이 더해지면서 움직이다.

커널이미지 base 에는 처음 부분에 한번의 오프셋으로 전체영역을 보호한다. ( CONFIG_RANDOMIZE_MEMORY )

자 그럼, 메모리 영역을 어떻게 보호가 되냐? 메모리 영역은 또 내부적으로 크게 3가지 부분으로 나눌 수 있다. 첫번째는 slab같은 heap 할당에서 많이 사용하는 주소인 direct map이고 있고 두번째는 또 다른 할당제인, vmalloc 영역이 있다. 이 영역은 ioremap ( mmio ) 와 같이 쓰이기도 한다.

그리고 마지막으로 vmemmap 영역이 있다.

각각의 영역은page_offset_base ,vmalloc_base , vmemmap_base

으로부터 특정 오프셋이 더해짐으로써 각각의 영역을 보호하기 때문에

사실상 각각의 영역 안에서에 leak이 따로따로 필요하다. ( 특히, CONFIG_RANDOMIZE_MEMORY 옵션이 있으면 각각의 영역을 따로 지키는 것이 확정이다)