Commit | Line | Data |
---|---|---|
df4e817b PT |
1 | .. SPDX-License-Identifier: GPL-2.0 |
2 | ||
df4e817b PT |
3 | ================ |
4 | Page Table Check | |
5 | ================ | |
6 | ||
7 | Introduction | |
8 | ============ | |
9 | ||
854d0982 | 10 | Page table check allows to harden the kernel by ensuring that some types of |
df4e817b PT |
11 | the memory corruptions are prevented. |
12 | ||
13 | Page table check performs extra verifications at the time when new pages become | |
14 | accessible from the userspace by getting their page table entries (PTEs PMDs | |
15 | etc.) added into the table. | |
16 | ||
17 | In case of detected corruption, the kernel is crashed. There is a small | |
18 | performance and memory overhead associated with the page table check. Therefore, | |
19 | it is disabled by default, but can be optionally enabled on systems where the | |
20 | extra hardening outweighs the performance costs. Also, because page table check | |
21 | is synchronous, it can help with debugging double map memory corruption issues, | |
22 | by crashing kernel at the time wrong mapping occurs instead of later which is | |
23 | often the case with memory corruptions bugs. | |
24 | ||
25 | Double mapping detection logic | |
26 | ============================== | |
27 | ||
28 | +-------------------+-------------------+-------------------+------------------+ | |
29 | | Current Mapping | New mapping | Permissions | Rule | | |
30 | +===================+===================+===================+==================+ | |
31 | | Anonymous | Anonymous | Read | Allow | | |
32 | +-------------------+-------------------+-------------------+------------------+ | |
33 | | Anonymous | Anonymous | Read / Write | Prohibit | | |
34 | +-------------------+-------------------+-------------------+------------------+ | |
35 | | Anonymous | Named | Any | Prohibit | | |
36 | +-------------------+-------------------+-------------------+------------------+ | |
37 | | Named | Anonymous | Any | Prohibit | | |
38 | +-------------------+-------------------+-------------------+------------------+ | |
39 | | Named | Named | Any | Allow | | |
40 | +-------------------+-------------------+-------------------+------------------+ | |
41 | ||
42 | Enabling Page Table Check | |
43 | ========================= | |
44 | ||
45 | Build kernel with: | |
46 | ||
47 | - PAGE_TABLE_CHECK=y | |
48 | Note, it can only be enabled on platforms where ARCH_SUPPORTS_PAGE_TABLE_CHECK | |
49 | is available. | |
50 | ||
51 | - Boot with 'page_table_check=on' kernel parameter. | |
52 | ||
53 | Optionally, build kernel with PAGE_TABLE_CHECK_ENFORCED in order to have page | |
54 | table support without extra kernel parameter. | |
81a31a86 RL |
55 | |
56 | Implementation notes | |
57 | ==================== | |
58 | ||
59 | We specifically decided not to use VMA information in order to avoid relying on | |
60 | MM states (except for limited "struct page" info). The page table check is a | |
61 | separate from Linux-MM state machine that verifies that the user accessible | |
62 | pages are not falsely shared. | |
63 | ||
64 | PAGE_TABLE_CHECK depends on EXCLUSIVE_SYSTEM_RAM. The reason is that without | |
65 | EXCLUSIVE_SYSTEM_RAM, users are allowed to map arbitrary physical memory | |
66 | regions into the userspace via /dev/mem. At the same time, pages may change | |
67 | their properties (e.g., from anonymous pages to named pages) while they are | |
68 | still being mapped in the userspace, leading to "corruption" detected by the | |
69 | page table check. | |
70 | ||
71 | Even with EXCLUSIVE_SYSTEM_RAM, I/O pages may be still allowed to be mapped via | |
72 | /dev/mem. However, these pages are always considered as named pages, so they | |
73 | won't break the logic used in the page table check. |