Virtual Memory & Memory Mapping

memory protection and protection faults

Memory protection is the rule that not every part of memory may be used in every way: some pages you may read but not write, some you may execute but not write, some you may not touch at all. It is the hardware-enforced equivalent of locked doors and signs reading 'read-only' or 'staff only', and it is what keeps a stray pointer or a malicious input from quietly rewriting your program's code or stomping the kernel.

It is enforced per page, through permission bits in each page-table entry: a readable bit, a writable bit, and an executable (or no-execute) bit. On every access the MMU checks the operation against these bits. Read a readable page: fine. Try to write a page whose writable bit is clear, or fetch an instruction from a no-execute page, and the MMU refuses and raises a protection fault — a page fault caused not by the page being absent but by the operation being forbidden. The OS receives it and, since it is illegal, normally delivers a fatal signal (SIGSEGV on Unix) that ends the program. This is exactly why a typical code page is mapped read-and-execute-but-not-write, and a data page read-and-write-but-not-execute: the famous W xor X policy that stops attackers from injecting code into data and running it.

Two honest distinctions matter. First, a protection fault is different from an absent-page fault: same exception mechanism, but one means 'you may not' and the other means 'not loaded yet'. Second, this hardware protection is page-granular and is NOT the same as catching a pointer that wanders within a region you do own — writing past the end of an array into another valid page of your own memory breaks nothing the MMU can see, which is why those bugs (buffer overflows) are so dangerous and so silent.

String literals live in a read-only page. char *s = "hi"; s[0] = 'H'; tries to write that page; the writable bit is clear, so the MMU raises a protection fault and the program dies with a segmentation fault — even though the pointer itself was perfectly valid.

A valid pointer to a read-only page still cannot be written.

Memory protection is per-page, not per-object: it cannot catch an overrun that stays inside a page you legitimately own. So protection stops cross-process and read-only violations, but a buffer overflow into your own writable memory passes the MMU silently — that is a job for sanitizers, not the hardware.

Also called
page permissionsaccess protection存取權限