Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 4: Virtual Process Memory


❑ When a new memory mapping is created, the kernel needs to find a suitable place for it unless
a specific address has been specified by the user. If the architecture wants to choose the proper
location itself, it must set the pre-processor symbolHAVE_ARCH_UNMAPPED_AREAand define the
functionarch_get_unmapped_areaaccordingly.
❑ New locations for memory mappings are usually found by starting the search from lower mem-
ory locations and progressing toward higher addresses. The kernel provides the default func-
tionarch_get_unmapped_area_topdownto perform this search, but if an architecture wants
to provide a specialized implementation, it needs to set the pre-processor symbolHAVE_ARCH_
GET_UNMAPPED_AREA.
❑ Usually, the stack grows from bottom to top. Architectures that handle this differently need to
set the configuration optionCONFIG_STACK_GROWSUP.^2 In the following, only stacks that grow
from top to bottom are considered.

Finally, we need to consider the task flagPF_RANDOMIZE. If it is set, the kernel does not choose fixed
locations for stack and the starting point for memory mappings, but varies them randomly each time a
new process is started. This complicates, for instance, exploiting security holes that are caused by buffer
overflows. If an attacker cannot rely on a fixed address where the stack can be found, it will be much
harder to construct malicious code that deliberatelymanipulates stack entries after access to the memory
region has been gained by a buffer overflow.

Figure 4-1 illustrates how the aforementioned components are distributed across the virtual address
space on most architectures.

Text

Heap

MMAP

Stack

TASK_SIZE
STACK_TOP-randomized_variable

mm->mmap_base (TASK_UNMAPPED_SIZE)

Gap

already used

Figure 4-1: Composition of the linear process address space.

(^2) Currently only PA-Risc processors require this option. The constants in the kernel thus have a slight tendency toward a sit-
uation where the stack grows from downward, albeit the PA-Risc code is not quite satisfied with that, as we can read in
include/asm-parisc/a.out.h:
/ XXX: STACK_TOP actually should be STACK_BOTTOM for parisc. prumpf *\
The funny thing is that ‘‘prumpf’’ is not a grumpy sign of discontent, but an abbreviation for a developer, Philipp Rumpf :-)

Free download pdf