]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man7/pkeys.7
execve.2, ioctl_console.2, ioctl_iflags.2, ioctl_ns.2, ioctl_userfaultfd.2, kcmp...
[thirdparty/man-pages.git] / man7 / pkeys.7
1 .\" Copyright (C) 2016 Intel Corporation
2 .\"
3 .\" %%%LICENSE_START(VERBATIM)
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
7 .\"
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
12 .\"
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date. The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein. The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
19 .\" professionally.
20 .\"
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
23 .\" %%%LICENSE_END
24 .\"
25 .TH PKEYS 7 2016-12-12 "Linux" "Linux Programmer's Manual"
26 .SH NAME
27 pkeys \- overview of Memory Protection Keys
28 .SH DESCRIPTION
29 Memory Protection Keys (pkeys) are an extension to existing
30 page-based memory permissions.
31 Normal page permissions using
32 page tables require expensive system calls and TLB invalidations
33 when changing permissions.
34 Memory Protection Keys provide a mechanism for changing
35 protections without requiring modification of the page tables on
36 every permission change.
37 .PP
38 To use pkeys, software must first "tag" a page in the page tables
39 with a pkey.
40 After this tag is in place, an application only has
41 to change the contents of a register in order to remove write
42 access, or all access to a tagged page.
43 .PP
44 Protection keys work in conjunction with the existing
45 .BR PROT_READ /
46 .BR PROT_WRITE /
47 .BR PROT_EXEC
48 permissions passed to system calls such as
49 .BR mprotect (2)
50 and
51 .BR mmap (2),
52 but always act to further restrict these traditional permission
53 mechanisms.
54 .PP
55 If a process performs an access that violates pkey
56 restrictions, it receives a
57 .BR SIGSEGV
58 signal.
59 See
60 .BR sigaction (2)
61 for details of the information available with that signal.
62 .PP
63 To use the pkeys feature, the processor must support it, and the kernel
64 must contain support for the feature on a given processor.
65 As of early 2016 only future Intel x86 processors are supported,
66 and this hardware supports 16 protection keys in each process.
67 However, pkey 0 is used as the default key, so a maximum of 15
68 are available for actual application use.
69 The default key is assigned to any memory region for which a
70 pkey has not been explicitly assigned via
71 .BR pkey_mprotect (2).
72 .PP
73 Protection keys have the potential to add a layer of security and
74 reliability to applications.
75 But they have not been primarily designed as
76 a security feature.
77 For instance, WRPKRU is a completely unprivileged
78 instruction, so pkeys are useless in any case that an attacker controls
79 the PKRU register or can execute arbitrary instructions.
80 .PP
81 Applications should be very careful to ensure that they do not "leak"
82 protection keys.
83 For instance, before calling
84 .BR pkey_free (2),
85 the application should be sure that no memory has that pkey assigned.
86 If the application left the freed pkey assigned, a future user of
87 that pkey might inadvertently change the permissions of an unrelated
88 data structure, which could impact security or stability.
89 The kernel currently allows in-use pkeys to have
90 .BR pkey_free (2)
91 called on them because it would have processor or memory performance
92 implications to perform the additional checks needed to disallow it.
93 Implementation of the necessary checks is left up to applications.
94 Applications may implement these checks by searching the
95 .IR /proc/[pid]/smaps
96 file for memory regions with the pkey assigned.
97 Further details can be found in
98 .BR proc (5).
99 .PP
100 Any application wanting to use protection keys needs to be able
101 to function without them.
102 They might be unavailable because the hardware that the
103 application runs on does not support them, the kernel code does
104 not contain support, the kernel support has been disabled, or
105 because the keys have all been allocated, perhaps by a library
106 the application is using.
107 It is recommended that applications wanting to use protection
108 keys should simply call
109 .BR pkey_alloc (2)
110 and test whether the call succeeds,
111 instead of attempting to detect support for the
112 feature in any other way.
113 .PP
114 Although unnecessary, hardware support for protection keys may be
115 enumerated with the
116 .I cpuid
117 instruction.
118 Details of how to do this can be found in the Intel Software
119 Developers Manual.
120 The kernel performs this enumeration and exposes the information in
121 .IR /proc/cpuinfo
122 under the "flags" field.
123 The string "pku" in this field indicates hardware support for protection
124 keys and the string "ospke" indicates that the kernel contains and has
125 enabled protection keys support.
126 .PP
127 Applications using threads and protection keys should be especially
128 careful.
129 Threads inherit the protection key rights of the parent at the time
130 of the
131 .BR clone (2),
132 system call.
133 Applications should either ensure that their own permissions are
134 appropriate for child threads at the time when
135 .BR clone (2)
136 is called, or ensure that each child thread can perform its
137 own initialization of protection key rights.
138 .\"
139 .SS Signal Handler Behavior
140 Each time a signal handler is invoked (including nested signals), the
141 thread is temporarily given a new, default set of protection key rights
142 that override the rights from the interrupted context.
143 This means that applications must re-establish their desired protection
144 key rights upon entering a signal handler if the desired rights differ
145 from the defaults.
146 The rights of any interrupted context are restored when the signal
147 handler returns.
148 .PP
149 This signal behavior is unusual and is due to the fact that the x86 PKRU
150 register (which stores protection key access rights) is managed with the
151 same hardware mechanism (XSAVE) that manages floating-point registers.
152 The signal behavior is the same as that of floating-point registers.
153 .\"
154 .SS Protection Keys system calls
155 The Linux kernel implements the following pkey-related system calls:
156 .BR pkey_mprotect (2),
157 .BR pkey_alloc (2),
158 and
159 .BR pkey_free (2).
160 .PP
161 The Linux pkey system calls are available only if the kernel was
162 configured and built with the
163 .BR CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
164 option.
165 .SH EXAMPLE
166 .PP
167 The program below allocates a page of memory with read and write permissions.
168 It then writes some data to the memory and successfully reads it
169 back.
170 After that, it attempts to allocate a protection key and
171 disallows access to the page by using the WRPKRU instruction.
172 It then tries to access the page,
173 which we now expect to cause a fatal signal to the application.
174 .PP
175 .in +4n
176 .EX
177 .RB "$" " ./a.out"
178 buffer contains: 73
179 about to read buffer again...
180 Segmentation fault (core dumped)
181 .EE
182 .in
183 .SS Program source
184 \&
185 .EX
186 #define _GNU_SOURCE
187 #include <unistd.h>
188 #include <sys/syscall.h>
189 #include <stdio.h>
190 #include <sys/mman.h>
191
192 static inline void
193 wrpkru(unsigned int pkru)
194 {
195 unsigned int eax = pkru;
196 unsigned int ecx = 0;
197 unsigned int edx = 0;
198
199 asm volatile(".byte 0x0f,0x01,0xef\\n\\t"
200 : : "a" (eax), "c" (ecx), "d" (edx));
201 }
202
203 int
204 pkey_set(int pkey, unsigned long rights, unsigned long flags)
205 {
206 unsigned int pkru = (rights << (2 * pkey));
207 return wrpkru(pkru);
208 }
209
210 int
211 pkey_mprotect(void *ptr, size_t size, unsigned long orig_prot,
212 unsigned long pkey)
213 {
214 return syscall(SYS_pkey_mprotect, ptr, size, orig_prot, pkey);
215 }
216
217 int
218 pkey_alloc(void)
219 {
220 return syscall(SYS_pkey_alloc, 0, 0);
221 }
222
223 int
224 pkey_free(unsigned long pkey)
225 {
226 return syscall(SYS_pkey_free, pkey);
227 }
228
229 #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \\
230 } while (0)
231
232 int
233 main(void)
234 {
235 int status;
236 int pkey;
237 int *buffer;
238
239 /*
240 *Allocate one page of memory
241 */
242 buffer = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE,
243 MAP_ANONYMOUS | MAP_PRIVATE, \-1, 0);
244 if (buffer == MAP_FAILED)
245 errExit("mmap");
246
247 /*
248 * Put some random data into the page (still OK to touch)
249 */
250 *buffer = __LINE__;
251 printf("buffer contains: %d\\n", *buffer);
252
253 /*
254 * Allocate a protection key:
255 */
256 pkey = pkey_alloc();
257 if (pkey == \-1)
258 errExit("pkey_alloc");
259
260 /*
261 * Disable access to any memory with "pkey" set,
262 * even though there is none right now
263 */
264 status = pkey_set(pkey, PKEY_DISABLE_ACCESS, 0);
265 if (status)
266 errExit("pkey_set");
267
268 /*
269 * Set the protection key on "buffer".
270 * Note that it is still read/write as far as mprotect() is
271 * concerned and the previous pkey_set() overrides it.
272 */
273 status = pkey_mprotect(buffer, getpagesize(),
274 PROT_READ | PROT_WRITE, pkey);
275 if (status == -1)
276 errExit("pkey_mprotect");
277
278 printf("about to read buffer again...\\n");
279
280 /*
281 * This will crash, because we have disallowed access
282 */
283 printf("buffer contains: %d\\n", *buffer);
284
285 status = pkey_free(pkey);
286 if (status == -1)
287 errExit("pkey_free");
288
289 exit(EXIT_SUCCESS);
290 }
291 .SH SEE ALSO
292 .BR pkey_alloc (2),
293 .BR pkey_free (2),
294 .BR pkey_mprotect (2),
295 .BR sigaction (2)