aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Hansen <dave.hansen@linux.intel.com>2016-07-29 12:30:20 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-09-09 07:02:28 -0400
commitc74fe3940848c6afea83bfbda64a9baf9da547c8 (patch)
treef2b4047c9e1da051ec79f775adf4e56cd5bc30c6
parenta60f7b69d92c0142c80a30d669a76b617b7f6879 (diff)
pkeys: Add details of system call use to Documentation/
This spells out all of the pkey-related system calls that we have and provides some example code fragments to demonstrate how we expect them to be used. Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Cc: linux-arch@vger.kernel.org Cc: Dave Hansen <dave@sr71.net> Cc: mgorman@techsingularity.net Cc: arnd@arndb.de Cc: linux-api@vger.kernel.org Cc: linux-mm@kvack.org Cc: luto@kernel.org Cc: akpm@linux-foundation.org Cc: torvalds@linux-foundation.org Link: http://lkml.kernel.org/r/20160729163020.59350E33@viggo.jf.intel.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--Documentation/x86/protection-keys.txt62
1 files changed, 62 insertions, 0 deletions
diff --git a/Documentation/x86/protection-keys.txt b/Documentation/x86/protection-keys.txt
index c281ded1ba16..6da7689601d1 100644
--- a/Documentation/x86/protection-keys.txt
+++ b/Documentation/x86/protection-keys.txt
@@ -18,6 +18,68 @@ even though there is theoretically space in the PAE PTEs. These
18permissions are enforced on data access only and have no effect on 18permissions are enforced on data access only and have no effect on
19instruction fetches. 19instruction fetches.
20 20
21=========================== Syscalls ===========================
22
23There are 2 system calls which directly interact with pkeys:
24
25 int pkey_alloc(unsigned long flags, unsigned long init_access_rights)
26 int pkey_free(int pkey);
27 int pkey_mprotect(unsigned long start, size_t len,
28 unsigned long prot, int pkey);
29
30Before a pkey can be used, it must first be allocated with
31pkey_alloc(). An application calls the WRPKRU instruction
32directly in order to change access permissions to memory covered
33with a key. In this example WRPKRU is wrapped by a C function
34called pkey_set().
35
36 int real_prot = PROT_READ|PROT_WRITE;
37 pkey = pkey_alloc(0, PKEY_DENY_WRITE);
38 ptr = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
39 ret = pkey_mprotect(ptr, PAGE_SIZE, real_prot, pkey);
40 ... application runs here
41
42Now, if the application needs to update the data at 'ptr', it can
43gain access, do the update, then remove its write access:
44
45 pkey_set(pkey, 0); // clear PKEY_DENY_WRITE
46 *ptr = foo; // assign something
47 pkey_set(pkey, PKEY_DENY_WRITE); // set PKEY_DENY_WRITE again
48
49Now when it frees the memory, it will also free the pkey since it
50is no longer in use:
51
52 munmap(ptr, PAGE_SIZE);
53 pkey_free(pkey);
54
55=========================== Behavior ===========================
56
57The kernel attempts to make protection keys consistent with the
58behavior of a plain mprotect(). For instance if you do this:
59
60 mprotect(ptr, size, PROT_NONE);
61 something(ptr);
62
63you can expect the same effects with protection keys when doing this:
64
65 pkey = pkey_alloc(0, PKEY_DISABLE_WRITE | PKEY_DISABLE_READ);
66 pkey_mprotect(ptr, size, PROT_READ|PROT_WRITE, pkey);
67 something(ptr);
68
69That should be true whether something() is a direct access to 'ptr'
70like:
71
72 *ptr = foo;
73
74or when the kernel does the access on the application's behalf like
75with a read():
76
77 read(fd, ptr, 1);
78
79The kernel will send a SIGSEGV in both cases, but si_code will be set
80to SEGV_PKERR when violating protection keys versus SEGV_ACCERR when
81the plain mprotect() permissions are violated.
82
21=========================== Config Option =========================== 83=========================== Config Option ===========================
22 84
23This config option adds approximately 1.5kb of text. and 50 bytes of 85This config option adds approximately 1.5kb of text. and 50 bytes of