Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 4: Virtual Process Memory


mm->get_unmapped_area = arch_get_unmapped_area_topdown;
mm->unmap_area = arch_unmap_area_topdown;
}
}

The old layout is chosen if the user has explicitly instructed to do so via/proc/sys/kernel/legacy_
va_layout, if a binary that was compiled for a differentUnixflavor that requires the old layout is exe-
cuted, or — most importantly — the stack may grow infinitely. This makes it difficult to find a bound for
the stack below which the mmap region can start.


In the classical case, the start of the mmap area is atTASK_UNMAPPED_BASE, which resolves to0x4000000,
and the standard functionarch_get_unmapped_area(despite its name, the function is not necessarily
architecture-specific, but there’s also a standard implementation available in the kernel) is used to grow
new mappings from bottom to top.


When the new layout is used, memory mappings grow from top to bottom. The standard function
arch_get_unmapped_area_topdown(which I will not consider in detail) is responsible for this. More
interesting is how the base address for memory mappings is chosen:


arch/x86/mm/mmap_32.c
#define MIN_GAP (128*1024*1024)
#define MAX_GAP (TASK_SIZE/6*5)

static inline unsigned long mmap_base(struct mm_struct *mm)
{
unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
unsigned long random_factor = 0;

if (current->flags & PF_RANDOMIZE)
random_factor = get_random_int() % (1024*1024);

if (gap < MIN_GAP)
gap = MIN_GAP;
else if (gap > MAX_GAP)
gap = MAX_GAP;

return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
}

The lowest possible stack location that can be computed from the maximal stack size can be used as the
start of the mmap area. However, the kernel ensures that the stack spans at least 128 MiB. Additionally,
it is ensured that at least a small portion of the address space is not taken up by the stack if a gigantic
stack limit is specified.


If address space randomization is requested, the position is modified by a random offset of maximally
1 MiB. Additionally, the kernel ensures that the region is aligned along the page frame size because this
is required by the architecture.


At a first glance, one could assume that life is easier for 64-bit architectures because they should not have
to choose between different address layouts — the virtual address space is so large that collisions of heap
and mmap region are nearly impossible.

Free download pdf