]> granicus.if.org Git - strace/commitdiff
Add support for pkey_mprotect, pkey_alloc, pkey_free syscalls
authorEugene Syromyatnikov <evgsyr@gmail.com>
Sat, 12 Nov 2016 17:54:56 +0000 (20:54 +0300)
committerDmitry V. Levin <ldv@altlinux.org>
Sun, 13 Nov 2016 21:41:58 +0000 (21:41 +0000)
* linux/32/syscallent.h: Add syscall entries for pkey_* calls.
* linux/64/syscallent.h: Likewise.
* linux/arm/syscallent.h: Likewise.
* linux/i386/syscallent.h: Likewise.
* linux/mips/syscallent-n32.h: Likewise.
* linux/mips/syscallent-n64.h: Likewise.
* linux/mips/syscallent-o32.h: Likewise.
* linux/x32/syscallent.h: Likewise.
* linux/x86_64/syscallent.h: Likewise.
* mem.c (do_mprotect): New function, common handler for mprotect and
pkey_mprotect.
(SYS_FUNC(mprotect)): Convert to wrapper around do_mprotect.
(SYS_FUNC(pkey_mprotect)): New function.
* xlat/pkey_access.in: New file.
* pkeys.c: New file containing implementation of pkey_alloc and
pkey_free.
* Makefile.am: Add it.
* NEWS: Mention this enhancement.
* tests/.gitignore: Add pkey_alloc, pkey_free, and pkey_mprotect.
* tests/Makefile.am (check_PROGRAMS): Likewise.
(DECODER_TESTS): Add pkey_alloc.test, pkey_free.test, and
pkey_mprotect.test.
* tests/pkey_alloc.c: New file.
* tests/pkey_free.c: Likewise.
* tests/pkey_mprotect.c: Likewise.
* tests/pkey_alloc.test: New test.
* tests/pkey_free.test: Likewise.
* tests/pkey_mprotect.test: Likewise.

22 files changed:
Makefile.am
NEWS
linux/32/syscallent.h
linux/64/syscallent.h
linux/arm/syscallent.h
linux/i386/syscallent.h
linux/mips/syscallent-n32.h
linux/mips/syscallent-n64.h
linux/mips/syscallent-o32.h
linux/x32/syscallent.h
linux/x86_64/syscallent.h
mem.c
pkeys.c [new file with mode: 0644]
tests/.gitignore
tests/Makefile.am
tests/pkey_alloc.c [new file with mode: 0644]
tests/pkey_alloc.test [new file with mode: 0755]
tests/pkey_free.c [new file with mode: 0644]
tests/pkey_free.test [new file with mode: 0755]
tests/pkey_mprotect.c [new file with mode: 0644]
tests/pkey_mprotect.test [new file with mode: 0755]
xlat/pkey_access.in [new file with mode: 0644]

index 2e65f97d78eaef1cad5cbba21ddfeb31207f2053..e7faed4178268d3c4d36db8588065ae1c4838c3d 100644 (file)
@@ -176,6 +176,7 @@ strace_SOURCES =    \
        perf.c          \
        perf_event_struct.h \
        personality.c   \
+       pkeys.c         \
        poll.c          \
        prctl.c         \
        print_mq_attr.c \
diff --git a/NEWS b/NEWS
index 3964fbc09d37954626583b160f4fcad2cf330c13..8db88df93152012b20b0c05794ffcdc8257b536d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ Noteworthy changes in release ?.?? (????-??-??)
 * Improvements
   * Implemented decoding of DM_* ioctl commands.
   * Implemented decoding of attr parameter of perf_event_open syscall.
+  * Implemented decoding of pkey_alloc, pkey_free, and pkey_mprotect syscalls.
   * Implemented dumping of mq_timedsend and mq_timedreceive syscalls.
   * Updated lists of ioctl commands from Linux 4.9.
 
index 2295d1e89dafc061fd1767ab132964bfcebd7b40..c2005a6b3619c8a6c3e9282d0ef25b16be92cab6 100644 (file)
 [285] = { 6,   TD,             SEN(copy_file_range),           "copy_file_range"       },
 [286] = { 6,   TD,             SEN(preadv2),                   "preadv2"               },
 [287] = { 6,   TD,             SEN(pwritev2),                  "pwritev2"              },
+[288] = { 4,   TM|SI,          SEN(pkey_mprotect),             "pkey_mprotect"         },
+[289] = { 2,   0,              SEN(pkey_alloc),                "pkey_alloc"            },
+[290] = { 1,   0,              SEN(pkey_free),                 "pkey_free"             },
 
 #undef sys_ARCH_mmap
 #undef ARCH_WANT_SYNC_FILE_RANGE2
index 5bd6cb042d9db5449d27c8223cbc9612dfd23d59..d67ce02fbc9bbb058a18136741105c6e62105b05 100644 (file)
 [285] = { 6,   TD,             SEN(copy_file_range),           "copy_file_range"       },
 [286] = { 6,   TD,             SEN(preadv2),                   "preadv2"               },
 [287] = { 6,   TD,             SEN(pwritev2),                  "pwritev2"              },
+[288] = { 4,   TM|SI,          SEN(pkey_mprotect),             "pkey_mprotect"         },
+[289] = { 2,   0,              SEN(pkey_alloc),                "pkey_alloc"            },
+[290] = { 1,   0,              SEN(pkey_free),                 "pkey_free"             },
index 356468bd5e5c1b08d0464643ae5260f27e55871e..4b72831371d5f71584d188d295b5249cab881cfb 100644 (file)
 [391] = { 6,   TD,             SEN(copy_file_range),           "copy_file_range"       },
 [392] = { 6,   TD,             SEN(preadv2),                   "preadv2"               },
 [393] = { 6,   TD,             SEN(pwritev2),                  "pwritev2"              },
+[394] = { 4,   TM|SI,          SEN(pkey_mprotect),             "pkey_mprotect"         },
+[395] = { 2,   0,              SEN(pkey_alloc),                "pkey_alloc"            },
+[396] = { 1,   0,              SEN(pkey_free),                 "pkey_free"             },
 
 #ifdef __ARM_EABI__
 # define ARM_FIRST_SHUFFLED_SYSCALL 400
index 307f46adad02e1188d03e12d7e0fb80ee415caf2..46170c3b423b3f5163d6fc31f3962540f322b30c 100644 (file)
 [377] = { 6,   TD,             SEN(copy_file_range),           "copy_file_range"       },
 [378] = { 6,   TD,             SEN(preadv2),                   "preadv2"               },
 [379] = { 6,   TD,             SEN(pwritev2),                  "pwritev2"              },
+[380] = { 4,   TM|SI,          SEN(pkey_mprotect),             "pkey_mprotect"         },
+[381] = { 2,   0,              SEN(pkey_alloc),                "pkey_alloc"            },
+[382] = { 1,   0,              SEN(pkey_free),                 "pkey_free"             },
 
 #define SYS_socket_subcall     400
 #include "subcall.h"
index b061355dbf2679fe521f22fca20bc1dcd11fd9e7..9ba0b12fce5c85a0f24381374e6de8e8959d13e0 100644 (file)
 [6324] = { 6,  TD,             SEN(copy_file_range),           "copy_file_range"       },
 [6325] = { 6,  TD,             SEN(preadv2),                   "preadv2"               },
 [6326] = { 6,  TD,             SEN(pwritev2),                  "pwritev2"              },
+[6327] = { 4,  TM|SI,          SEN(pkey_mprotect),             "pkey_mprotect"         },
+[6328] = { 2,  0,              SEN(pkey_alloc),                "pkey_alloc"            },
+[6329] = { 1,  0,              SEN(pkey_free),                 "pkey_free"             },
 
 # define SYS_socket_subcall      6400
 # include "subcall.h"
index 42c1bfd43edf89f67968f808ca6da79c9fb37f4f..e2096cb491285f37058407462010681e432750e9 100644 (file)
 [5320] = { 6,  TD,             SEN(copy_file_range),           "copy_file_range"       },
 [5321] = { 6,  TD,             SEN(preadv2),                   "preadv2"               },
 [5322] = { 6,  TD,             SEN(pwritev2),                  "pwritev2"              },
+[5323] = { 4,  TM|SI,          SEN(pkey_mprotect),             "pkey_mprotect"         },
+[5324] = { 2,  0,              SEN(pkey_alloc),                "pkey_alloc"            },
+[5325] = { 1,  0,              SEN(pkey_free),                 "pkey_free"             },
 
 # define SYS_socket_subcall      5400
 # include "subcall.h"
index c92005fc6006c4e79d0c4f2a4cc97b0950b61adc..da8e4fb44b8874492408242e3e7ecc650f533cd1 100644 (file)
 [4360] = { 6,  TD,             SEN(copy_file_range),           "copy_file_range"       },
 [4361] = { 6,  TD,             SEN(preadv2),                   "preadv2"               },
 [4362] = { 6,  TD,             SEN(pwritev2),                  "pwritev2"              },
+[4363] = { 4,  TM|SI,          SEN(pkey_mprotect),             "pkey_mprotect"         },
+[4364] = { 2,  0,              SEN(pkey_alloc),                "pkey_alloc"            },
+[4365] = { 1,  0,              SEN(pkey_free),                 "pkey_free"             },
 
 # define SYS_socket_subcall      4400
 # include "subcall.h"
index bd44450e01921f91bb1e38c231f54fa2f2a287f7..ab2ad5e83134f87d89ff47b446f5e45d9758150c 100644 (file)
 [326] = { 6,   TD,             SEN(copy_file_range),           "copy_file_range"       },
 [327] = { 6,   TD,             SEN(printargs),                 "64:preadv2"            },
 [328] = { 6,   TD,             SEN(printargs),                 "64:pwritev2"           },
-[329 ... 511] = { },
+[329] = { 4,   TM|SI,          SEN(pkey_mprotect),             "pkey_mprotect"         },
+[330] = { 2,   0,              SEN(pkey_alloc),                "pkey_alloc"            },
+[331] = { 1,   0,              SEN(pkey_free),                 "pkey_free"             },
+[332 ... 511] = { },
 /*
  * x32-specific system call numbers start at 512 to avoid cache impact
  * for native 64-bit operation.
index 6e814ea01bc3d6d249fa3871c03340aa9270ed1e..7c476dbde9260354549ca0c7c11ac2aa740af349 100644 (file)
 [326] = { 6,   TD,             SEN(copy_file_range),           "copy_file_range"       },
 [327] = { 6,   TD,             SEN(preadv2),                   "preadv2"               },
 [328] = { 6,   TD,             SEN(pwritev2),                  "pwritev2"              },
+[329] = { 4,   TM|SI,          SEN(pkey_mprotect),             "pkey_mprotect"         },
+[330] = { 2,   0,              SEN(pkey_alloc),                "pkey_alloc"            },
+[331] = { 1,   0,              SEN(pkey_free),                 "pkey_free"             },
diff --git a/mem.c b/mem.c
index affc9355c256227303cd909701e175180fd075e7..9b54486cc2fcb68258e96ef5625a8abd8071727a 100644 (file)
--- a/mem.c
+++ b/mem.c
@@ -182,15 +182,29 @@ SYS_FUNC(munmap)
        return RVAL_DECODED;
 }
 
-SYS_FUNC(mprotect)
+static int
+do_mprotect(struct tcb *tcp, bool has_pkey)
 {
        printaddr(tcp->u_arg[0]);
        tprintf(", %lu, ", tcp->u_arg[1]);
        printflags_long(mmap_prot, tcp->u_arg[2], "PROT_???");
 
+       if (has_pkey)
+               tprintf(", %d", (int) tcp->u_arg[3]);
+
        return RVAL_DECODED;
 }
 
+SYS_FUNC(mprotect)
+{
+       return do_mprotect(tcp, false);
+}
+
+SYS_FUNC(pkey_mprotect)
+{
+       return do_mprotect(tcp, true);
+}
+
 #include "xlat/mremap_flags.h"
 
 SYS_FUNC(mremap)
diff --git a/pkeys.c b/pkeys.c
new file mode 100644 (file)
index 0000000..5b4e116
--- /dev/null
+++ b/pkeys.c
@@ -0,0 +1,18 @@
+#include "defs.h"
+
+#include "xlat/pkey_access.h"
+
+SYS_FUNC(pkey_alloc)
+{
+       tprintf("%#llx, ", getarg_ull(tcp, 0));
+       printflags64(pkey_access, getarg_ull(tcp, 1), "PKEY_???");
+
+       return RVAL_DECODED;
+}
+
+SYS_FUNC(pkey_free)
+{
+       tprintf("%d", (int) tcp->u_arg[0]);
+
+       return RVAL_DECODED;
+}
index ef1e94b9a869ac9cddb9746914c46336a70c682a..0366c9c45ac3b643d6479374884263231086f3d2 100644 (file)
@@ -201,6 +201,9 @@ perf_event_open
 perf_event_open_unabbrev
 personality
 pipe
+pkey_alloc
+pkey_free
+pkey_mprotect
 poll
 ppoll
 prctl-seccomp-filter-v
index f83cccc77c90065e32fbd3ef02584bbe8bb3616e..0f04779354b2defc2f17b78512ea818d2a3142f0 100644 (file)
@@ -259,6 +259,9 @@ check_PROGRAMS = \
        perf_event_open_unabbrev \
        personality \
        pipe \
+       pkey_alloc \
+       pkey_free \
+       pkey_mprotect \
        poll \
        ppoll \
        prctl-seccomp-filter-v \
@@ -628,6 +631,9 @@ DECODER_TESTS = \
        perf_event_open_unabbrev.test \
        personality.test \
        pipe.test \
+       pkey_alloc.test \
+       pkey_free.test \
+       pkey_mprotect.test \
        poll.test \
        ppoll.test \
        prctl-seccomp-filter-v.test \
diff --git a/tests/pkey_alloc.c b/tests/pkey_alloc.c
new file mode 100644 (file)
index 0000000..906d67f
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Check decoding of pkey_alloc syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#if defined __NR_pkey_alloc
+
+# include <stdio.h>
+# include <unistd.h>
+
+# include "kernel_types.h"
+
+int
+main(void)
+{
+       static const kernel_ulong_t flags[] = {
+               0,
+               (kernel_ulong_t) 0xbadc0ded00000000ULL,
+               (kernel_ulong_t) 0xffff0000eeee1111ULL,
+               (kernel_ulong_t) 0x123456789abcdef0ULL,
+       };
+       static const struct {
+               kernel_ulong_t val;
+               const char *str;
+       } rights[] = {
+               { (kernel_ulong_t) 0xbadc0ded00000002ULL,
+                       sizeof(kernel_ulong_t) > sizeof(int) ?
+                       "PKEY_DISABLE_WRITE|0xbadc0ded00000000" :
+                       "PKEY_DISABLE_WRITE" },
+               { 0xdec0ded, "PKEY_DISABLE_ACCESS|0xdec0dec" },
+               { 0x3, "PKEY_DISABLE_ACCESS|PKEY_DISABLE_WRITE" },
+               { ARG_STR(0) },
+               { 0xbadc0dec, "0xbadc0dec /* PKEY_??? */" },
+       };
+
+       long rc;
+       unsigned int i;
+       unsigned int j;
+
+       for (i = 0; i < ARRAY_SIZE(flags); i++) {
+               for (j = 0; j < ARRAY_SIZE(rights); j++) {
+                       rc = syscall(__NR_pkey_alloc, flags[i], rights[j].val);
+                       printf("pkey_alloc(%#llx, %s) = %s\n",
+                              (unsigned long long) flags[i], rights[j].str,
+                              sprintrc(rc));
+               }
+       }
+
+       puts("+++ exited with 0 +++");
+
+       return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_pkey_alloc");
+
+#endif
diff --git a/tests/pkey_alloc.test b/tests/pkey_alloc.test
new file mode 100755 (executable)
index 0000000..f168c21
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check decoding of pkey_alloc syscall.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -a17
diff --git a/tests/pkey_free.c b/tests/pkey_free.c
new file mode 100644 (file)
index 0000000..13f9e58
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Check decoding of pkey_free syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#if defined __NR_pkey_free
+
+# include <stdio.h>
+# include <unistd.h>
+
+# include "kernel_types.h"
+
+int
+main(void)
+{
+       static const kernel_ulong_t keys[] = {
+               0,
+               3141592653U,
+               (kernel_ulong_t) 0xbadc0ded00000000ULL,
+               (kernel_ulong_t) 0xffff00001111eeeeULL,
+               (kernel_ulong_t) 0x123456789abcdef0ULL,
+       };
+
+       long rc;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(keys); i++) {
+               rc = syscall(__NR_pkey_free, keys[i]);
+               printf("pkey_free(%d) = %s\n", (int) keys[i], sprintrc(rc));
+       }
+
+       puts("+++ exited with 0 +++");
+
+       return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_pkey_free");
+
+#endif
diff --git a/tests/pkey_free.test b/tests/pkey_free.test
new file mode 100755 (executable)
index 0000000..9c01c3e
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check decoding of pkey_free syscall.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -a13
diff --git a/tests/pkey_mprotect.c b/tests/pkey_mprotect.c
new file mode 100644 (file)
index 0000000..e62ae79
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Check decoding of pkey_mprotect syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#if defined __NR_pkey_mprotect
+
+# include <stdio.h>
+# include <unistd.h>
+
+#include <sys/mman.h>
+
+# include "kernel_types.h"
+
+const char *
+sprintptr(kernel_ulong_t ptr)
+{
+       static char buf[sizeof(ptr) * 2 + sizeof("0x")];
+
+       if (ptr)
+               snprintf(buf, sizeof(buf), "%#llx", (unsigned long long) ptr);
+       else
+               return "NULL";
+
+       return buf;
+}
+
+int
+main(void)
+{
+       static const kernel_ulong_t ptrs[] = {
+               0,
+               (kernel_ulong_t) 0xfacebeef00000000ULL,
+               (kernel_ulong_t) 0xbadc0dedda7a1057ULL,
+       };
+       static const kernel_ulong_t sizes[] = {
+               0,
+               (kernel_ulong_t) 0xfacebeef00000000ULL,
+               (kernel_ulong_t) 0xfedcba9876543210ULL,
+               (kernel_ulong_t) 0x123456789abcdef0ULL,
+               (kernel_ulong_t) 0xbadc0dedda7a1057ULL,
+       };
+       static const struct {
+               kernel_ulong_t val;
+               const char *str;
+       } prots[] = {
+               { ARG_STR(PROT_READ) },
+               /* For now, only 0x0300001f are used */
+               { (kernel_ulong_t) 0xdeadfeed00ca7500ULL,
+                       sizeof(kernel_ulong_t) > sizeof(int) ?
+                       "0xdeadfeed00ca7500 /* PROT_??? */" :
+                       "0xca7500 /* PROT_??? */" },
+               { ARG_STR(PROT_READ|PROT_WRITE|0xface00) },
+       };
+       static const kernel_ulong_t pkeys[] = {
+               0,
+               -1LL,
+               (kernel_ulong_t) 0xface1e55,
+               (kernel_ulong_t) 0xbadc0ded00000001,
+       };
+
+       long rc;
+       unsigned int i;
+       unsigned int j;
+       unsigned int k;
+       unsigned int l;
+
+       for (i = 0; i < ARRAY_SIZE(ptrs); i++) {
+               for (j = 0; j < ARRAY_SIZE(sizes); j++) {
+                       for (k = 0; k < ARRAY_SIZE(prots); k++) {
+                               for (l = 0; l < ARRAY_SIZE(pkeys); l++) {
+                                       rc = syscall(__NR_pkey_mprotect,
+                                                    ptrs[i], sizes[j],
+                                                    prots[k].val, pkeys[l]);
+                                       printf("pkey_mprotect(%s, %llu, %s, %d)"
+                                              " = %s\n",
+                                              sprintptr(ptrs[i]),
+                                              (unsigned long long) sizes[j],
+                                              prots[k].str, (int) pkeys[l],
+                                              sprintrc(rc));
+                               }
+                       }
+               }
+       }
+
+       puts("+++ exited with 0 +++");
+
+       return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_pkey_mprotect");
+
+#endif
diff --git a/tests/pkey_mprotect.test b/tests/pkey_mprotect.test
new file mode 100755 (executable)
index 0000000..922d491
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check decoding of pkey_mprotect syscall.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -a37
diff --git a/xlat/pkey_access.in b/xlat/pkey_access.in
new file mode 100644 (file)
index 0000000..37372a8
--- /dev/null
@@ -0,0 +1,2 @@
+PKEY_DISABLE_ACCESS    0x1
+PKEY_DISABLE_WRITE     0x2