in x86 CPU, there is control register number 0. the 16'th bit of this register indicates "Write Protection" setting. if this bit is cleared, CPU is able to overwrite Read Only data. (configured in page table entry) in memory. if this bit is set, CPU can not overwrite RO data in memory.
what I am curious is "what is the original purpose of this bit??" "why does x86 CPU need this??"
According to the Intel Systems Programming Manual (section 2-13), the CR1 control register is "Reserved". That is, the kernel manipulating control register CR1 results in undefined behavior. As the articles indicates, there are also CR2, CR3, CR4 and CR8 control registers, though they are not reserved.
Quoting from Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A pg. 2-15 (Emphasis mine):
WP Write Protect (bit 16 of CR0) — When set, inhibits supervisor-level procedures from writing into readonly pages; when clear, allows supervisor-level procedures to write into read-only pages (regardless of the U/S bit setting; see Section 4.1.3 and Section 4.6). This flag facilitates implementation of the copy-on-write method of creating a new process (forking) used by operating systems such as UNIX.
Update: Looking at wikipedia on fork():
Whenever a process (parent or child) modifies a page, a separate copy of that particular page alone is made for that process (parent or child) which performed the modification.
This is at the core of copy-on-write, but presents a problem when the modification is done by the kernel (such as when the write occurs as a result of syscall - think read()
).
From 4.1.3:
CR0.WP allows pages to be protected from supervisor-mode writes. If CR0.WP = 0, supervisor-mode write accesses are allowed to linear addresses with read-only access rights; if CR0.WP = 1, they are not. (User-mode write accesses are never allowed to linear addresses with read-only access rights, regardless of the value of CR0.WP.)
By setting CR0.WP = 1
the kernel will be notified (with a page-fault) when it modifies read-only user pages and can perform the copy-on-write operation before proceeding with the page modification.
WP=1 is the default. It enables traps when kernel writes to a read only (write protected) user (U) page, so the kernel can check whether it is a COW page (so it knows that another copy of the page needs to be created that is not COW), otherwise it would have to check every single memory address it is accessing or it would break COW by making the change visible to other processes that map the memory.
WP can be set to 0 (but it wants to make sure interrupts are disabled / masked during this handling, so that control can't be taken away by code executing that is unaware of this condition). This allows a write protected cr3 page to be unwriteprotected (because when you unset the write bit in its recursive PML4 entry to itself, nothing can be done about it until you WP = 0, otherwise it will keep causing a trap)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With