[CRIU] [PATCH 1/2] test: Test for partially mprotect()-ed sysv shmem segment
Pavel Emelyanov
xemul at virtuozzo.com
Thu May 19 03:06:02 PDT 2016
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
test/zdtm/.gitignore | 1 +
test/zdtm/static/Makefile | 1 +
test/zdtm/static/shm-mp.c | 116 +++++++++++++++++++++++++++++++++++++++++++
test/zdtm/static/shm-mp.desc | 1 +
4 files changed, 119 insertions(+)
create mode 100644 test/zdtm/static/shm-mp.c
create mode 100644 test/zdtm/static/shm-mp.desc
diff --git a/test/zdtm/.gitignore b/test/zdtm/.gitignore
index 2e2ac2b..4c2b2de 100644
--- a/test/zdtm/.gitignore
+++ b/test/zdtm/.gitignore
@@ -131,6 +131,7 @@
/static/session02
/static/session03
/static/shm
+/static/shm-mp
/static/sigaltstack
/static/signalfd00
/static/sigpending
diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile
index 36b9252..e07725b 100644
--- a/test/zdtm/static/Makefile
+++ b/test/zdtm/static/Makefile
@@ -45,6 +45,7 @@ TST_NOFILE = \
inotify_system \
inotify_system_nodel \
shm \
+ shm-mp \
ptrace_sig \
pipe00 \
pipe01 \
diff --git a/test/zdtm/static/shm-mp.c b/test/zdtm/static/shm-mp.c
new file mode 100644
index 0000000..b297d76
--- /dev/null
+++ b/test/zdtm/static/shm-mp.c
@@ -0,0 +1,116 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <signal.h>
+#include <setjmp.h>
+
+#include "zdtmtst.h"
+
+const char *test_doc="Tests mprotected SYSVIPC shmems";
+const char *test_author="Pavel Emelyanov <xemul at openvz.org>";
+
+static sigjmp_buf segv_ret; /* we need sig*jmp stuff, otherwise SIGSEGV will reset our handler */
+static void segfault(int signo)
+{
+ siglongjmp(segv_ret, 1);
+}
+
+static int check_prot(char *ptr, char val, int prot)
+{
+ if (signal(SIGSEGV, segfault) == SIG_ERR) {
+ fail("setting SIGSEGV handler failed: %m\n");
+ return -1;
+ }
+
+ if (!sigsetjmp(segv_ret, 1)) {
+ if (*ptr != val) {
+ fail("read value doesn't match what I wrote");
+ return -1;
+ }
+ if (!(prot & PROT_READ)) {
+ fail("PROT_READ bypassed\n");
+ return -1;
+ }
+ } else /* we come here on return from SIGSEGV handler */
+ if (prot & PROT_READ) {
+ fail("PROT_READ rejected\n");
+ return -1;
+ }
+
+ if (!sigsetjmp(segv_ret, 1)) {
+ *ptr = val;
+ if (!(prot & PROT_WRITE)) {
+ fail("PROT_WRITE bypassed\n");
+ return -1;
+ }
+ } else /* we come here on return from SIGSEGV handler */
+ if (prot & PROT_WRITE) {
+ fail("PROT_WRITE rejected\n");
+ return -1;
+ }
+
+ if (signal(SIGSEGV, SIG_DFL) == SIG_ERR) {
+ fail("restoring SIGSEGV handler failed: %m\n");
+ return -1;
+ }
+
+ return 0;
+}
+int main(int argc, char **argv)
+{
+ key_t key;
+ int id, f = 0;
+ char *mem;
+
+ test_init(argc, argv);
+
+ key = ftok(argv[0], 812135646);
+ if (key == -1) {
+ pr_perror("Can't make key");
+ goto out;
+ }
+
+ id = shmget(key, 2 * 4096, 0777 | IPC_CREAT | IPC_EXCL);
+ if (id == -1) {
+ pr_perror("Can't make seg");
+ goto out;
+ }
+
+ mem = shmat(id, NULL, 0);
+ if (mem == (void *)-1) {
+ pr_perror("Can't shmat");
+ goto out_rm;
+ }
+
+ mem[0] = 'R';
+ mem[4096] = 'W';
+
+ if (mprotect(mem, 4096, PROT_READ)) {
+ pr_perror("Can't mprotect shmem");
+ goto out_dt;
+ }
+
+ test_daemon();
+ test_waitsig();
+
+ if (check_prot(mem, 'R', PROT_READ))
+ f++;
+ if (check_prot(mem + 4096, 'W', PROT_READ | PROT_WRITE))
+ f++;
+
+
+ if (!f)
+ pass();
+ else
+ fail("Some checks failed");
+
+out_dt:
+ shmdt(mem);
+out_rm:
+ shmctl(id, IPC_RMID, NULL);
+out:
+ return 0;
+}
diff --git a/test/zdtm/static/shm-mp.desc b/test/zdtm/static/shm-mp.desc
new file mode 100644
index 0000000..6c4afe5
--- /dev/null
+++ b/test/zdtm/static/shm-mp.desc
@@ -0,0 +1 @@
+{'flavor': 'ns uns'}
--
2.5.0
More information about the CRIU
mailing list