Implications of enabling kptr_restrict=2

Updated -

Overview

The kernel.kptr_restrict sysctl acts as a toggle to indicate whether or not a restriction is placed upon exposing kernel memory addresses via /proc and other interfaces.

The behavior of the printk format specifier %pK, which is used to print kernel pointers, is modified by this sysctl.

When kptr_restrict is configured to 2, any kernel pointers that are printed using %pK are printed as 0s, regardless of what privilege the user has. This is normally used in the context of security/hardening.

Considerations

When setting kptr_restrict to 2, it's important to understand that this may affect the expected behavior or functionality of some tools, applications, or workflows.

For example;

The perf utility, commonly used in troubleshooting performance issues in the context of interactions on a CPU, uses files located in /proc as well as other files that make use of %pK.

With kernel.kptr_restrict = 2, this functionality is no longer available.

Examples

Below, we demonstrate kptr_restrict being configured to 1, and kernel addresses are still visible:

$ sysctl kernel.kptr_restrict
kernel.kptr_restrict = 1

$ tail /proc/vmallocinfo 
0xffffffffc0df4000-0xffffffffc0e22000  188416 move_module+0x1e/0x170 pages=45 vmalloc N0=45
0xffffffffc0e22000-0xffffffffc0e47000  151552 move_module+0x1e/0x170 pages=36 vmalloc N0=36
0xffffffffc0e47000-0xffffffffc0e53000   49152 move_module+0x1e/0x170 pages=11 vmalloc N0=11
0xffffffffc0e53000-0xffffffffc0e75000  139264 move_module+0x1e/0x170 pages=33 vmalloc N0=33
0xffffffffc0e75000-0xffffffffc0e80000   45056 move_module+0x1e/0x170 pages=10 vmalloc N0=10
0xffffffffc0e8b000-0xffffffffc0ea8000  118784 move_module+0x1e/0x170 pages=28 vmalloc N0=28
0xffffffffc0eba000-0xffffffffc0eef000  217088 move_module+0x1e/0x170 pages=52 vmalloc N0=52
0xffffffffc0eef000-0xffffffffc0f09000  106496 move_module+0x1e/0x170 pages=25 vmalloc N0=25
0xffffffffc0f09000-0xffffffffc0f31000  163840 move_module+0x1e/0x170 pages=39 vmalloc N0=39
0xffffb09481035000-0xffffb09484adc000 61501440 unpurged vm_area

Next, we enable kptr_restrict = 2 to show that these same addresses are zeroed out:

$ sysctl kernel.kptr_restrict
kernel.kptr_restrict = 2

$ tail /proc/vmallocinfo 
0x0000000000000000-0x0000000000000000  188416 move_module+0x1e/0x170 pages=45 vmalloc N0=45
0x0000000000000000-0x0000000000000000  151552 move_module+0x1e/0x170 pages=36 vmalloc N0=36
0x0000000000000000-0x0000000000000000   49152 move_module+0x1e/0x170 pages=11 vmalloc N0=11
0x0000000000000000-0x0000000000000000  139264 move_module+0x1e/0x170 pages=33 vmalloc N0=33
0x0000000000000000-0x0000000000000000   45056 move_module+0x1e/0x170 pages=10 vmalloc N0=10
0x0000000000000000-0x0000000000000000  118784 move_module+0x1e/0x170 pages=28 vmalloc N0=28
0x0000000000000000-0x0000000000000000  217088 move_module+0x1e/0x170 pages=52 vmalloc N0=52
0x0000000000000000-0x0000000000000000  106496 move_module+0x1e/0x170 pages=25 vmalloc N0=25
0x0000000000000000-0x0000000000000000  163840 move_module+0x1e/0x170 pages=39 vmalloc N0=39
0x0000000000000000-0x0000000000000000 20500480 unpurged vm_area
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To demonstrate how this sysctl only modifies the %pK format specifier, below is a custom kernel module that prints using both the %pK and %lx format specificers. kernel.kptr_restrict = 2 only acts upon the %pK format specifier.

With kernel.kptr_restrict = 1 the address is visible:

$ sysctl kernel.kptr_restrict
kernel.kptr_restrict = 1

$ insmod hello_world_kptr.ko; dmesg | tail -3
[  993.175225] Hello World
[  993.175245] Memory address of hello_str with %pK: ffffffffc1039072     < - - - - - - - - address is visible
[  993.175494] Memory address of hello_str with %lx: ffffffffc1039072

With kernel.kptr_restrict = 2 the address is obfuscated for the %pK format:

$ sysctl kernel.kptr_restrict
kernel.kptr_restrict = 2

$ insmod hello_world_kptr.ko; dmesg | tail -3
[ 1089.495206] Hello World
[ 1089.495227] Memory address of hello_str with %pK: 0000000000000000  < - - - - - - - -  address is obfuscated
[ 1089.495235] Memory address of hello_str with %lx: ffffffffc1039072

Further reading

Disclaimer: Links contained herein to external website(s) are provided for convenience only. Red Hat has not reviewed the links and is not responsible for the content or its availability. The inclusion of any link to an external website does not imply endorsement by Red Hat of the website or their entities, products or services. You agree that Red Hat is not responsible or liable for any loss or expenses that may result due to your use of (or reliance on) the external site or content.

https://www.kernel.org/doc/Documentation/sysctl/kernel.txt

https://www.kernel.org/doc/Documentation/printk-formats.txt

Comments