Skip to contentSkip to conversation

pkey: Add test for memory protection keys

PATCH New Li Wang 2 participants 3 messages Jun 20, 2019 – Jun 21, 2019

lore
Share & tools
lore

Li Wang

author
#0 lore raw

PATCH 1/1 pkey: Add test for memory protection keys

---
 configure.ac                               |   1 +
 include/lapi/syscalls/aarch64.in           |   3 +
 include/lapi/syscalls/arm.in               |   3 +
 include/lapi/syscalls/i386.in              |   3 +
 include/lapi/syscalls/ia64.in              |   3 +
 include/lapi/syscalls/powerpc.in           |   3 +
 include/lapi/syscalls/powerpc64.in         |   3 +
 include/lapi/syscalls/s390.in              |   3 +
 include/lapi/syscalls/s390x.in             |   3 +
 include/lapi/syscalls/sh.in                |   3 +
 include/lapi/syscalls/sparc.in             |   3 +
 include/lapi/syscalls/sparc64.in           |   3 +
 include/lapi/syscalls/x86_64.in            |   3 +
 runtest/syscalls                           |   2 +
 testcases/kernel/syscalls/pkeys/.gitignore |   1 +
 testcases/kernel/syscalls/pkeys/Makefile   |   8 ++
 testcases/kernel/syscalls/pkeys/pkey.h     |  44 +++++++++
 testcases/kernel/syscalls/pkeys/pkey01.c   | 105 +++++++++++++++++++++
 18 files changed, 197 insertions(+)
 create mode 100644 testcases/kernel/syscalls/pkeys/.gitignore
 create mode 100644 testcases/kernel/syscalls/pkeys/Makefile
 create mode 100644 testcases/kernel/syscalls/pkeys/pkey.h
 create mode 100644 testcases/kernel/syscalls/pkeys/pkey01.c
configure.ac +1 -0
index 5ecc92781..35997699f 100644
@@ -76,6 +76,7 @@ AC_CHECK_FUNCS([ \
     profil \
     pwritev \
     pwritev2 \
+    pkey_mprotect \
     readlinkat \
     renameat \
     renameat2 \
include/lapi/syscalls/aarch64.in +3 -0
index 177dd0115..4232defbe 100644
@@ -266,3 +266,6 @@ copy_file_range 285
 preadv2 286
 pwritev2 287
 _sysctl 1078
+pkey_mprotect 394
+pkey_alloc 395
+pkey_free 396
include/lapi/syscalls/arm.in +3 -0
index f4adedb2c..48b55b5ff 100644
@@ -350,3 +350,6 @@ copy_file_range (__NR_SYSCALL_BASE+391)
 preadv2 (__NR_SYSCALL_BASE+392)
 pwritev2 (__NR_SYSCALL_BASE+393)
 statx (__NR_SYSCALL_BASE+397)
+pkey_mprotect (__NR_SYSCALL_BASE+394)
+pkey_alloc (__NR_SYSCALL_BASE+395)
+pkey_free (__NR_SYSCALL_BASE+396)
include/lapi/syscalls/i386.in +3 -0
index af5254f77..c54573547 100644
@@ -348,3 +348,6 @@ copy_file_range 377
 preadv2 378
 pwritev2 379
 statx 383
+pkey_mprotect 380
+pkey_alloc 381
+pkey_free 382
include/lapi/syscalls/ia64.in +3 -0
index c0aeed08b..56bfd7928 100644
@@ -305,3 +305,6 @@ mlock2 1346
 copy_file_range 1347
 preadv2 1348
 pwritev2 1349
+pkey_mprotect 330
+pkey_alloc 331
+pkey_free 332
include/lapi/syscalls/powerpc.in +3 -0
index 6b6be58a7..eaf8d45ed 100644
@@ -355,3 +355,6 @@ copy_file_range 379
 preadv2 380
 pwritev2 381
 statx 383
+pkey_mprotect 386
+pkey_alloc 384
+pkey_free 385
include/lapi/syscalls/powerpc64.in +3 -0
index 6b6be58a7..eaf8d45ed 100644
@@ -355,3 +355,6 @@ copy_file_range 379
 preadv2 380
 pwritev2 381
 statx 383
+pkey_mprotect 386
+pkey_alloc 384
+pkey_free 385
include/lapi/syscalls/s390.in +3 -0
index 2a2ffe223..3ee5547f1 100644
@@ -338,3 +338,6 @@ mlock2 374
 copy_file_range 375
 preadv2 376
 pwritev2 377
+pkey_mprotect 384
+pkey_alloc 385
+pkey_free 386
include/lapi/syscalls/s390x.in +3 -0
index 4c36ce17c..92e882aae 100644
@@ -337,3 +337,6 @@ mlock2 374
 copy_file_range 375
 preadv2 376
 pwritev2 377
+pkey_mprotect 384
+pkey_alloc 385
+pkey_free 386
include/lapi/syscalls/sh.in +3 -0
index a942fb506..00726c1cc 100644
@@ -369,3 +369,6 @@ mlock2 390
 copy_file_range 391
 preadv2 392
 pwritev2 393
+pkey_mprotect 384
+pkey_alloc 385
+pkey_free 386
include/lapi/syscalls/sparc.in +3 -0
index 20dc37b01..1b34ab489 100644
@@ -343,3 +343,6 @@ mlock2 356
 copy_file_range 357
 preadv2 358
 pwritev2 359
+pkey_mprotect 362
+pkey_alloc 363
+pkey_free 364
include/lapi/syscalls/sparc64.in +3 -0
index c100b8e3e..f3142fbdd 100644
@@ -319,3 +319,6 @@ mlock2 356
 copy_file_range 357
 preadv2 358
 pwritev2 359
+pkey_mprotect 362
+pkey_alloc 363
+pkey_free 364
include/lapi/syscalls/x86_64.in +3 -0
index 87849e5c0..9c77f1c67 100644
@@ -315,3 +315,6 @@ copy_file_range 326
 preadv2 327
 pwritev2 328
 statx 332
+pkey_mprotect 329
+pkey_alloc 330
+pkey_free 331
runtest/syscalls +2 -0
index a1106fb84..a236fce09 100644
@@ -723,6 +723,8 @@ mprotect02 mprotect02
 mprotect03 mprotect03
 mprotect04 mprotect04
 
+pkey01 pkey01
+
 mq_notify01 mq_notify01
 mq_notify02 mq_notify02
 mq_open01 mq_open01
testcases/kernel/syscalls/pkeys/.gitignore new file +1 -0
new file mode 100644
index 000000000..6fd5addb8
@@ -0,0 +1 @@
+/pkey01
testcases/kernel/syscalls/pkeys/Makefile new file +8 -0
new file mode 100644
index 000000000..9ee2c2ea5
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2019 Red Hat, Inc.
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/pkeys/pkey.h new file +44 -0

44 lines not on this page · raw message

testcases/kernel/syscalls/pkeys/pkey01.c new file +105 -0

105 lines not on this page · raw message

Signature · 1 line
2.20.1
#1 lore raw

PATCH 1/1 pkey: Add test for memory protection keys

----- Original Message -----

Quoted 44 lines
---
 configure.ac                               |   1 +
 include/lapi/syscalls/aarch64.in           |   3 +
 include/lapi/syscalls/arm.in               |   3 +
 include/lapi/syscalls/i386.in              |   3 +
 include/lapi/syscalls/ia64.in              |   3 +
 include/lapi/syscalls/powerpc.in           |   3 +
 include/lapi/syscalls/powerpc64.in         |   3 +
 include/lapi/syscalls/s390.in              |   3 +
 include/lapi/syscalls/s390x.in             |   3 +
 include/lapi/syscalls/sh.in                |   3 +
 include/lapi/syscalls/sparc.in             |   3 +
 include/lapi/syscalls/sparc64.in           |   3 +
 include/lapi/syscalls/x86_64.in            |   3 +
 runtest/syscalls                           |   2 +
 testcases/kernel/syscalls/pkeys/.gitignore |   1 +
 testcases/kernel/syscalls/pkeys/Makefile   |   8 ++
 testcases/kernel/syscalls/pkeys/pkey.h     |  44 +++++++++
 testcases/kernel/syscalls/pkeys/pkey01.c   | 105 +++++++++++++++++++++
 18 files changed, 197 insertions(+)
 create mode 100644 testcases/kernel/syscalls/pkeys/.gitignore
 create mode 100644 testcases/kernel/syscalls/pkeys/Makefile
 create mode 100644 testcases/kernel/syscalls/pkeys/pkey.h
 create mode 100644 testcases/kernel/syscalls/pkeys/pkey01.c
configure.ac +1 -0
index 5ecc92781..35997699f 100644
@@ -76,6 +76,7 @@ AC_CHECK_FUNCS([ \
     profil \
     pwritev \
     pwritev2 \
+    pkey_mprotect \
     readlinkat \
     renameat \
     renameat2 \
include/lapi/syscalls/aarch64.in +0 -0
index 177dd0115..4232defbe 100644

include/lapi/syscalls/aarch64.in copy_file_range 285 · line 271

Quoted 6 lines
include/lapi/syscalls/aarch64.in +3 -0
@@ -266,3 +266,6 @@ copy_file_range 285
 preadv2 286
 pwritev2 287
 _sysctl 1078
+pkey_mprotect 394
+pkey_alloc 395
+pkey_free 396

288, 289, 290

Quoted 196 lines
include/lapi/syscalls/arm.in +3 -0
index f4adedb2c..48b55b5ff 100644
@@ -350,3 +350,6 @@ copy_file_range (__NR_SYSCALL_BASE+391)
 preadv2 (__NR_SYSCALL_BASE+392)
 pwritev2 (__NR_SYSCALL_BASE+393)
 statx (__NR_SYSCALL_BASE+397)
+pkey_mprotect (__NR_SYSCALL_BASE+394)
+pkey_alloc (__NR_SYSCALL_BASE+395)
+pkey_free (__NR_SYSCALL_BASE+396)
include/lapi/syscalls/i386.in +3 -0
index af5254f77..c54573547 100644
@@ -348,3 +348,6 @@ copy_file_range 377
 preadv2 378
 pwritev2 379
 statx 383
+pkey_mprotect 380
+pkey_alloc 381
+pkey_free 382
include/lapi/syscalls/ia64.in +3 -0
index c0aeed08b..56bfd7928 100644
@@ -305,3 +305,6 @@ mlock2 1346
 copy_file_range 1347
 preadv2 1348
 pwritev2 1349
+pkey_mprotect 330
+pkey_alloc 331
+pkey_free 332
include/lapi/syscalls/powerpc.in +3 -0
index 6b6be58a7..eaf8d45ed 100644
@@ -355,3 +355,6 @@ copy_file_range 379
 preadv2 380
 pwritev2 381
 statx 383
+pkey_mprotect 386
+pkey_alloc 384
+pkey_free 385
include/lapi/syscalls/powerpc64.in +3 -0
index 6b6be58a7..eaf8d45ed 100644
@@ -355,3 +355,6 @@ copy_file_range 379
 preadv2 380
 pwritev2 381
 statx 383
+pkey_mprotect 386
+pkey_alloc 384
+pkey_free 385
include/lapi/syscalls/s390.in +3 -0
index 2a2ffe223..3ee5547f1 100644
@@ -338,3 +338,6 @@ mlock2 374
 copy_file_range 375
 preadv2 376
 pwritev2 377
+pkey_mprotect 384
+pkey_alloc 385
+pkey_free 386
include/lapi/syscalls/s390x.in +3 -0
index 4c36ce17c..92e882aae 100644
@@ -337,3 +337,6 @@ mlock2 374
 copy_file_range 375
 preadv2 376
 pwritev2 377
+pkey_mprotect 384
+pkey_alloc 385
+pkey_free 386
include/lapi/syscalls/sh.in +3 -0
index a942fb506..00726c1cc 100644
@@ -369,3 +369,6 @@ mlock2 390
 copy_file_range 391
 preadv2 392
 pwritev2 393
+pkey_mprotect 384
+pkey_alloc 385
+pkey_free 386
include/lapi/syscalls/sparc.in +3 -0
index 20dc37b01..1b34ab489 100644
@@ -343,3 +343,6 @@ mlock2 356
 copy_file_range 357
 preadv2 358
 pwritev2 359
+pkey_mprotect 362
+pkey_alloc 363
+pkey_free 364
include/lapi/syscalls/sparc64.in +3 -0
index c100b8e3e..f3142fbdd 100644
@@ -319,3 +319,6 @@ mlock2 356
 copy_file_range 357
 preadv2 358
 pwritev2 359
+pkey_mprotect 362
+pkey_alloc 363
+pkey_free 364
include/lapi/syscalls/x86_64.in +3 -0
index 87849e5c0..9c77f1c67 100644
@@ -315,3 +315,6 @@ copy_file_range 326
 preadv2 327
 pwritev2 328
 statx 332
+pkey_mprotect 329
+pkey_alloc 330
+pkey_free 331
runtest/syscalls +2 -0
index a1106fb84..a236fce09 100644
@@ -723,6 +723,8 @@ mprotect02 mprotect02
 mprotect03 mprotect03
 mprotect04 mprotect04
 
+pkey01 pkey01
+
 mq_notify01 mq_notify01
 mq_notify02 mq_notify02
 mq_open01 mq_open01
testcases/kernel/syscalls/pkeys/.gitignore new file +1 -0
new file mode 100644
index 000000000..6fd5addb8
@@ -0,0 +1 @@
+/pkey01
testcases/kernel/syscalls/pkeys/Makefile new file +8 -0
new file mode 100644
index 000000000..9ee2c2ea5
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2019 Red Hat, Inc.
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/pkeys/pkey.h new file +28 -0
new file mode 100644
index 000000000..bd86bebcc
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 Red Hat, Inc.
+ */
+
+#ifndef PKEYS_H
+#define PKEYS_H
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+
+#ifndef PKEY_DISABLE_ACCESS
+# define PKEY_DISABLE_ACCESS 0x1
+# define PKEY_DISABLE_WRITE  0x2
+#endif
+
+#ifndef HAVE_PKEY_MPROTECT
+static inline int pkey_mprotect(void *addr, size_t len, int prot, int pkey)
+{
+	return tst_syscall(SYS_pkey_mprotect, addr, len, prot, pkey);
+}
+
+static inline int pkey_alloc(unsigned int flags, unsigned int access_rights)
+{
+	return tst_syscall(SYS_pkey_alloc, flags, access_rights);
+}
+
+static inline int pkey_free(int pkey)

testcases/kernel/syscalls/pkeys/pkey.h line 38

Quoted 10 lines
testcases/kernel/syscalls/pkeys/pkey.h new file +10 -0
+{
+	return tst_syscall(SYS_pkey_free, pkey);
+}
+#endif /* HAVE_PKEY_MPROTECT */
+
+static inline void check_pkey_support(void)
+{
+	int pkey = pkey_alloc(0, 0);
+
+	if ((pkey == -1) && (errno == EINVAL))

Shouldn't this handle also ENOSPC?

ENOSPC (pkey_alloc()) All protection keys available for the current process have been allocated. The number of keys available is
architecture-specific and implementation-specific and may be reduced by kernel-internal use of certain keys. There are currently 15 keys available to user programs on x86.

This error will also be returned if the processor or operating system does not support protection keys. Applications
should always be prepared to handle this error, since factors outside of the application's control can reduce the number of available pkeys.

Quoted 61 lines
testcases/kernel/syscalls/pkeys/pkey.h new file +6 -0
+		tst_brk(TCONF, "pkey_alloc is not supported");
+	else
+		pkey_free(pkey);
+}
+
+#endif /* PKEYS_H */
testcases/kernel/syscalls/pkeys/pkey01.c new file +48 -0
new file mode 100644
index 000000000..8faa4be4c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 Red Hat, Inc.
+ *
+ * Test for Memory Protection Keys
+ * Reference: https://lwn.net/Articles/689395/
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/syscall.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+#include "pkey.h"
+
+static int psize;
+static char *buffer;
+
+static struct tcase {
+	unsigned long flags;
+	unsigned long access_rights;
+	char *name;
+} tcases[] = {
+	{0, PKEY_DISABLE_ACCESS, "PKEY_DISABLE_ACCESS"},
+	{0, PKEY_DISABLE_WRITE, "PKEY_DISABLE_WRITE"},
+};
+
+static void setup(void)
+{
+	check_pkey_support();
+
+	psize = getpagesize();
+	buffer = SAFE_MMAP(NULL, psize, PROT_READ | PROT_WRITE,
+			MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+	memset(buffer, 'a', psize);
+}
+
+static void verify_pkey(unsigned int i)
+{
+	int pkey, status;
+	pid_t pid;
+
+	struct tcase *tc = &tcases[i];
+

testcases/kernel/syscalls/pkeys/pkey01.c line 58

Quoted 10 lines
testcases/kernel/syscalls/pkeys/pkey01.c new file +10 -0
+	pkey = pkey_alloc(tc->flags, tc->access_rights);
+	if (pkey == -1)
+		tst_brk(TBROK, "pkey_alloc failed");
+
+	tst_res(TINFO, "Set %s on buffer", tc->name);
+	if (pkey_mprotect(buffer, psize, PROT_READ | PROT_WRITE, pkey) == -1)
+		tst_brk(TBROK, "pkey_mprotect failed");
+
+	pid = SAFE_FORK();
+	if (pid == 0) {

I'd suggest something like:

                struct rlimit r;                                                                                                            
                                                                                                                                            
                r.rlim_cur = 1;                                                                                                             
                r.rlim_max = 1;                                                                                                             
                SAFE_SETRLIMIT(RLIMIT_CORE, &r); 

to avoid getting cores from this child - since it is expected to segfault.

Quoted 54 lines
testcases/kernel/syscalls/pkeys/pkey01.c new file +47 -1
+		switch (tc->access_rights) {
+		case PKEY_DISABLE_ACCESS:
+			tst_res(TFAIL, "Read buffer success, buffer[0] = %d", *buffer);
+		break;
+		case PKEY_DISABLE_WRITE:
+			*buffer = 'b';
+		break;
+		}
+		exit(0);
+	}
+
+	SAFE_WAITPID(pid, &status, 0);
+	if (WIFSIGNALED(status)) {
+		if (WTERMSIG(status) == SIGSEGV) {
+			tst_res(TPASS, "Child ended by %s as expected",
+				tst_strsig(SIGSEGV));
+		} else {
+			tst_res(TFAIL, "Child ended by %s unexpected" ,
+				tst_strsig(WTERMSIG(status)));
+		}
+	} else {
+		tst_res(TFAIL, "Child unexpectedly ended");
+	}
+
+	tst_res(TINFO, "Remove %s from buffer", tc->name);
+	if (pkey_mprotect(buffer, psize, PROT_READ | PROT_WRITE, 0x0) == -1)
+		tst_brk(TBROK, "pkey_mprotect failed");
+	*buffer = i;
+	tst_res(TPASS, "Write buffer success, buffer[0] = %d", *buffer);
+
+	if (pkey_free(pkey) == -1)
+		tst_brk(TBROK, "pkey_free failed");
+}
+
+static void cleanup(void)
+{
+	if (buffer)
+		SAFE_MUNMAP(buffer, psize);
+}
+
+static struct tst_test test = {
+	.tcnt = ARRAY_SIZE(tcases),
+	.forks_child = 1,
+	.test = verify_pkey,
+	.setup = setup,
+	.cleanup = cleanup,
+};
--

2.20.1

--
Mailing list info: https://lists.linux.it/listinfo/ltp

author
#2 lore raw

PATCH 1/1 pkey: Add test for memory protection keys

Quoted 47 lines · Jan Stancek

----- Original Message -----

Quoted 44 lines
---
 configure.ac                               |   1 +
 include/lapi/syscalls/aarch64.in           |   3 +
 include/lapi/syscalls/arm.in               |   3 +
 include/lapi/syscalls/i386.in              |   3 +
 include/lapi/syscalls/ia64.in              |   3 +
 include/lapi/syscalls/powerpc.in           |   3 +
 include/lapi/syscalls/powerpc64.in         |   3 +
 include/lapi/syscalls/s390.in              |   3 +
 include/lapi/syscalls/s390x.in             |   3 +
 include/lapi/syscalls/sh.in                |   3 +
 include/lapi/syscalls/sparc.in             |   3 +
 include/lapi/syscalls/sparc64.in           |   3 +
 include/lapi/syscalls/x86_64.in            |   3 +
 runtest/syscalls                           |   2 +
 testcases/kernel/syscalls/pkeys/.gitignore |   1 +
 testcases/kernel/syscalls/pkeys/Makefile   |   8 ++
 testcases/kernel/syscalls/pkeys/pkey.h     |  44 +++++++++
 testcases/kernel/syscalls/pkeys/pkey01.c   | 105 +++++++++++++++++++++
 18 files changed, 197 insertions(+)
 create mode 100644 testcases/kernel/syscalls/pkeys/.gitignore
 create mode 100644 testcases/kernel/syscalls/pkeys/Makefile
 create mode 100644 testcases/kernel/syscalls/pkeys/pkey.h
 create mode 100644 testcases/kernel/syscalls/pkeys/pkey01.c
configure.ac +1 -0
index 5ecc92781..35997699f 100644
@@ -76,6 +76,7 @@ AC_CHECK_FUNCS([ \
     profil \
     pwritev \
     pwritev2 \
+    pkey_mprotect \
     readlinkat \
     renameat \
     renameat2 \
include/lapi/syscalls/aarch64.in +0 -0
index 177dd0115..4232defbe 100644
@@ -266,3 +266,6 @@ copy_file_range 285
Quoted 9 lines

include/lapi/syscalls/aarch64.in copy_file_range 285 · line 271

Quoted 6 lines
include/lapi/syscalls/aarch64.in +3 -0
 preadv2 286
 pwritev2 287
 _sysctl 1078
+pkey_mprotect 394
+pkey_alloc 395
+pkey_free 396

288, 289, 290

Good eyes.

Quoted 26 lines

include/lapi/syscalls/

Quoted 13 lines
include/lapi/syscalls/arm.in +3 -0
index f4adedb2c..48b55b5ff 100644
@@ -350,3 +350,6 @@ copy_file_range (__NR_SYSCALL_BASE+391)
 preadv2 (__NR_SYSCALL_BASE+392)
 pwritev2 (__NR_SYSCALL_BASE+393)
 statx (__NR_SYSCALL_BASE+397)
+pkey_mprotect (__NR_SYSCALL_BASE+394)
+pkey_alloc (__NR_SYSCALL_BASE+395)
+pkey_free (__NR_SYSCALL_BASE+396)
include/lapi/syscalls/ renamed from include/lapi/syscalls/i386.in +0 -0

i386.in

include/lapi/syscalls/

Quoted 11 lines

index af5254f77..c54573547 100644

include/lapi/syscalls/i386.in +3 -0
@@ -348,3 +348,6 @@ copy_file_range 377
 preadv2 378
 pwritev2 379
 statx 383
+pkey_mprotect 380
+pkey_alloc 381
+pkey_free 382
include/lapi/syscalls/ renamed from include/lapi/syscalls/ia64.in +0 -0

ia64.in

Quoted 11 lines

include/lapi/syscalls/ia64.in mlock2 1346 · line 310

Quoted 10 lines

index c0aeed08b..56bfd7928 100644

include/lapi/syscalls/ia64.in +3 -0
@@ -305,3 +305,6 @@ mlock2 1346
 copy_file_range 1347
 preadv2 1348
 pwritev2 1349
+pkey_mprotect 330
+pkey_alloc 331
+pkey_free 332

And here should be:

    pkey_mprotect 1354
    pkey_alloc 1355
    pkey_free 1356
Quoted 172 lines

include/lapi/syscalls/

Quoted 25 lines
include/lapi/syscalls/powerpc.in +3 -0
index 6b6be58a7..eaf8d45ed 100644
@@ -355,3 +355,6 @@ copy_file_range 379
 preadv2 380
 pwritev2 381
 statx 383
+pkey_mprotect 386
+pkey_alloc 384
+pkey_free 385
include/lapi/syscalls/powerpc64.in +3 -0
index 6b6be58a7..eaf8d45ed 100644
@@ -355,3 +355,6 @@ copy_file_range 379
 preadv2 380
 pwritev2 381
 statx 383
+pkey_mprotect 386
+pkey_alloc 384
+pkey_free 385
include/lapi/syscalls/ renamed from include/lapi/syscalls/s390.in +0 -0

s390.in

include/lapi/syscalls/

Quoted 11 lines

index 2a2ffe223..3ee5547f1 100644

include/lapi/syscalls/s390.in +3 -0
@@ -338,3 +338,6 @@ mlock2 374
 copy_file_range 375
 preadv2 376
 pwritev2 377
+pkey_mprotect 384
+pkey_alloc 385
+pkey_free 386
include/lapi/syscalls/ renamed from include/lapi/syscalls/s390x.in +0 -0

s390x.in

include/lapi/syscalls/

Quoted 22 lines

index 4c36ce17c..92e882aae 100644

include/lapi/syscalls/s390x.in +3 -0
@@ -337,3 +337,6 @@ mlock2 374
 copy_file_range 375
 preadv2 376
 pwritev2 377
+pkey_mprotect 384
+pkey_alloc 385
+pkey_free 386
include/lapi/syscalls/sh.in +3 -0
index a942fb506..00726c1cc 100644
@@ -369,3 +369,6 @@ mlock2 390
 copy_file_range 391
 preadv2 392
 pwritev2 393
+pkey_mprotect 384
+pkey_alloc 385
+pkey_free 386
include/lapi/syscalls/ renamed from include/lapi/syscalls/sparc.in +0 -0

sparc.in

Quoted 85 lines

index 20dc37b01..1b34ab489 100644

include/lapi/syscalls/sparc.in +3 -0
@@ -343,3 +343,6 @@ mlock2 356
 copy_file_range 357
 preadv2 358
 pwritev2 359
+pkey_mprotect 362
+pkey_alloc 363
+pkey_free 364
include/lapi/syscalls/sparc64.in +3 -0
index c100b8e3e..f3142fbdd 100644
@@ -319,3 +319,6 @@ mlock2 356
 copy_file_range 357
 preadv2 358
 pwritev2 359
+pkey_mprotect 362
+pkey_alloc 363
+pkey_free 364
include/lapi/syscalls/x86_64.in +3 -0
index 87849e5c0..9c77f1c67 100644
@@ -315,3 +315,6 @@ copy_file_range 326
 preadv2 327
 pwritev2 328
 statx 332
+pkey_mprotect 329
+pkey_alloc 330
+pkey_free 331
runtest/syscalls +2 -0
index a1106fb84..a236fce09 100644
@@ -723,6 +723,8 @@ mprotect02 mprotect02
 mprotect03 mprotect03
 mprotect04 mprotect04
 
+pkey01 pkey01
+
 mq_notify01 mq_notify01
 mq_notify02 mq_notify02
 mq_open01 mq_open01
testcases/kernel/syscalls/pkeys/.gitignore new file +1 -0
new file mode 100644
index 000000000..6fd5addb8
@@ -0,0 +1 @@
+/pkey01
testcases/kernel/syscalls/pkeys/Makefile new file +8 -0
new file mode 100644
index 000000000..9ee2c2ea5
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2019 Red Hat, Inc.
+
+top_srcdir           ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/pkeys/pkey.h new file +8 -0
new file mode 100644
index 000000000..bd86bebcc
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 Red Hat, Inc.
+ */
+
+#ifndef PKEYS_H
+#define PKEYS_H
+

testcases/kernel/syscalls/pkeys/pkey.h line 18

Quoted 10 lines
testcases/kernel/syscalls/pkeys/pkey.h new file +10 -0
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+
+#ifndef PKEY_DISABLE_ACCESS
+# define PKEY_DISABLE_ACCESS 0x1
+# define PKEY_DISABLE_WRITE  0x2
+#endif
+
+#ifndef HAVE_PKEY_MPROTECT
+static inline int pkey_mprotect(void *addr, size_t len, int prot, int

pkey)

testcases/kernel/syscalls/pkeys/pkey.h

Quoted 5 lines
testcases/kernel/syscalls/pkeys/pkey.h new file +5 -0
+{
+     return tst_syscall(SYS_pkey_mprotect, addr, len, prot, pkey);
+}
+
+static inline int pkey_alloc(unsigned int flags, unsigned int

access_rights)

Quoted 9 lines
testcases/kernel/syscalls/pkeys/pkey.h new file +9 -0
+{
+     return tst_syscall(SYS_pkey_alloc, flags, access_rights);
+}
+
+static inline int pkey_free(int pkey)
+{
+     return tst_syscall(SYS_pkey_free, pkey);
+}
+#endif /* HAVE_PKEY_MPROTECT */
Quoted 9 lines

testcases/kernel/syscalls/pkeys/pkey.h line 38

Quoted 6 lines
testcases/kernel/syscalls/pkeys/pkey.h new file +6 -0
+
+static inline void check_pkey_support(void)
+{
+     int pkey = pkey_alloc(0, 0);
+
+     if ((pkey == -1) && (errno == EINVAL))

Shouldn't this handle also ENOSPC?

Yes, if all pkeys have been allocated on a system, then we will get this error in allocating a new pkey.
I will handle this in v2.

Quoted 95 lines

ENOSPC (pkey_alloc()) All protection keys available for the current
process have been allocated. The number of keys available is
architecture-specific and implementation-specific and may
be reduced by kernel-internal use of certain keys. There are
currently 15 keys available to user programs on x86.

This error will also be returned if the processor or
operating system does not support protection keys. Applications
should always be prepared to handle this error, since
factors outside of the application's control can reduce the number
of available pkeys.

Quoted 57 lines
testcases/kernel/syscalls/pkeys/pkey.h new file +6 -0
+             tst_brk(TCONF, "pkey_alloc is not supported");
+     else
+             pkey_free(pkey);
+}
+
+#endif /* PKEYS_H */
testcases/kernel/syscalls/pkeys/pkey01.c new file +44 -0
new file mode 100644
index 000000000..8faa4be4c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 Red Hat, Inc.
+ *
+ * Test for Memory Protection Keys
+ * Reference: https://lwn.net/Articles/689395/
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/syscall.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+#include "pkey.h"
+
+static int psize;
+static char *buffer;
+
+static struct tcase {
+     unsigned long flags;
+     unsigned long access_rights;
+     char *name;
+} tcases[] = {
+     {0, PKEY_DISABLE_ACCESS, "PKEY_DISABLE_ACCESS"},
+     {0, PKEY_DISABLE_WRITE, "PKEY_DISABLE_WRITE"},
+};
+
+static void setup(void)
+{
+     check_pkey_support();
+
+     psize = getpagesize();
+     buffer = SAFE_MMAP(NULL, psize, PROT_READ | PROT_WRITE,
+                     MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+     memset(buffer, 'a', psize);
+}
+
+static void verify_pkey(unsigned int i)
+{
+     int pkey, status;

testcases/kernel/syscalls/pkeys/pkey01.c line 54

Quoted 10 lines
testcases/kernel/syscalls/pkeys/pkey01.c new file +10 -0
+     pid_t pid;
+
+     struct tcase *tc = &tcases[i];
+
+     pkey = pkey_alloc(tc->flags, tc->access_rights);
+     if (pkey == -1)
+             tst_brk(TBROK, "pkey_alloc failed");
+
+     tst_res(TINFO, "Set %s on buffer", tc->name);
+     if (pkey_mprotect(buffer, psize, PROT_READ | PROT_WRITE, pkey) ==

-1)

testcases/kernel/syscalls/pkeys/pkey01.c line 58

Quoted 4 lines
testcases/kernel/syscalls/pkeys/pkey01.c new file +4 -0
+             tst_brk(TBROK, "pkey_mprotect failed");
+
+     pid = SAFE_FORK();
+     if (pid == 0) {

I'd suggest something like:

                struct rlimit r;


                r.rlim_cur = 1;

                r.rlim_max = 1;

                SAFE_SETRLIMIT(RLIMIT_CORE, &r);
Quoted 2 lines

to avoid getting cores from this child - since it is expected to segfault.

Good advice.

Quoted 58 lines

testcases/kernel/syscalls/pkeys/pkey01.c

Quoted 4 lines
testcases/kernel/syscalls/pkeys/pkey01.c new file +3 -0
+             switch (tc->access_rights) {
+             case PKEY_DISABLE_ACCESS:
+                     tst_res(TFAIL, "Read buffer success, buffer[0] =

%d", *buffer);

Quoted 13 lines
testcases/kernel/syscalls/pkeys/pkey01.c new file +13 -0
+             break;
+             case PKEY_DISABLE_WRITE:
+                     *buffer = 'b';
+             break;
+             }
+             exit(0);
+     }
+
+     SAFE_WAITPID(pid, &status, 0);
+     if (WIFSIGNALED(status)) {
+             if (WTERMSIG(status) == SIGSEGV) {
+                     tst_res(TPASS, "Child ended by %s as expected",
+                             tst_strsig(SIGSEGV));

testcases/kernel/syscalls/pkeys/pkey01.c

Quoted 10 lines
testcases/kernel/syscalls/pkeys/pkey01.c new file +10 -0
+             } else {
+                     tst_res(TFAIL, "Child ended by %s unexpected" ,
+                             tst_strsig(WTERMSIG(status)));
+             }
+     } else {
+             tst_res(TFAIL, "Child unexpectedly ended");
+     }
+
+     tst_res(TINFO, "Remove %s from buffer", tc->name);
+     if (pkey_mprotect(buffer, psize, PROT_READ | PROT_WRITE, 0x0) ==

-1)

Quoted 28 lines
testcases/kernel/syscalls/pkeys/pkey01.c new file +21 -1
+             tst_brk(TBROK, "pkey_mprotect failed");
+     *buffer = i;
+     tst_res(TPASS, "Write buffer success, buffer[0] = %d", *buffer);
+
+     if (pkey_free(pkey) == -1)
+             tst_brk(TBROK, "pkey_free failed");
+}
+
+static void cleanup(void)
+{
+     if (buffer)
+             SAFE_MUNMAP(buffer, psize);
+}
+
+static struct tst_test test = {
+     .tcnt = ARRAY_SIZE(tcases),
+     .forks_child = 1,
+     .test = verify_pkey,
+     .setup = setup,
+     .cleanup = cleanup,
+};
--

2.20.1

--
Mailing list info: https://lists.linux.it/listinfo/ltp

Signature · 5 lines
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190621/2dcd470b/attachment-0001.html>