[CRIU] [PATCH] zdtm: remove busy loops from seccomp_strict

Andrey Vagin avagin at openvz.org
Wed Jul 22 07:48:14 PDT 2015


Don't heat a planet! :)

Cc: Tycho Andersen <tycho.andersen at canonical.com>
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 test/zdtm/lib/msg.c                    |  6 +++
 test/zdtm/lib/zdtmtst.h                |  1 +
 test/zdtm/live/static/seccomp_strict.c | 73 ++++++++++++++++++++++++++--------
 3 files changed, 63 insertions(+), 17 deletions(-)

diff --git a/test/zdtm/lib/msg.c b/test/zdtm/lib/msg.c
index c88ceac..b366e4f 100644
--- a/test/zdtm/lib/msg.c
+++ b/test/zdtm/lib/msg.c
@@ -34,6 +34,7 @@ int test_log_init(const char *fname, const char *suffix)
 	return 0;
 }
 
+int zdtm_seccomp;
 void test_msg(const char *format, ...)
 {
 	va_list arg;
@@ -43,6 +44,9 @@ void test_msg(const char *format, ...)
 	struct timeval tv;
 	struct tm *tm;
 
+	if (zdtm_seccomp) /* seccomp allows restricted set of syscall-s */
+		goto skip;
+
 	gettimeofday(&tv, NULL);
 	tm = localtime(&tv.tv_sec);
 	if (tm == NULL) {
@@ -53,6 +57,8 @@ void test_msg(const char *format, ...)
 
 	off += sprintf(buf + off, ".%.3ld: ", tv.tv_usec / 1000);
 	off += sprintf(buf + off, "%5d: ", getpid());
+
+skip:
 	va_start(arg, format);
 	off += vsnprintf(buf + off, sizeof(buf) - off, format, arg);
 	va_end(arg);
diff --git a/test/zdtm/lib/zdtmtst.h b/test/zdtm/lib/zdtmtst.h
index 23802d0..db00cad 100644
--- a/test/zdtm/lib/zdtmtst.h
+++ b/test/zdtm/lib/zdtmtst.h
@@ -101,6 +101,7 @@ extern int parse_opt_string(char *param, void *arg);
 /* message helpers */
 extern void setup_outfile(void);
 extern int test_log_init(const char *outfile, const char *suffix);
+extern int zdtm_seccomp;
 #define err(format, arg...)	\
 	test_msg("ERR: %s:%d: " format " (errno = %d (%s))\n", \
 		__FILE__, __LINE__, ## arg, errno, strerror(errno))
diff --git a/test/zdtm/live/static/seccomp_strict.c b/test/zdtm/live/static/seccomp_strict.c
index 97db19b..833e5c6 100644
--- a/test/zdtm/live/static/seccomp_strict.c
+++ b/test/zdtm/live/static/seccomp_strict.c
@@ -4,12 +4,17 @@
 #include <sys/prctl.h>
 #include <linux/seccomp.h>
 #include <linux/limits.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/syscall.h>
 #include "zdtmtst.h"
 
 const char *test_doc	= "Check that SECCOMP_MODE_STRICT is restored";
 const char *test_author	= "Tycho Andersen <tycho.andersen at canonical.com>";
 
-int get_seccomp_mode(pid_t pid, bool after_checkpoint)
+int get_seccomp_mode(pid_t pid)
 {
 	FILE *f;
 	char buf[PATH_MAX];
@@ -23,12 +28,6 @@ int get_seccomp_mode(pid_t pid, bool after_checkpoint)
 
 	while (NULL != fgets(buf, sizeof(buf), f)) {
 		int mode;
-		char state;
-
-		if (after_checkpoint && sscanf(buf, "State: %c %*s", &state) == 1 && state != 'R') {
-			fail("resumed but state is not R (%c), seccomp killed the process during resume\n", state);
-			break;
-		}
 
 		if (sscanf(buf, "Seccomp:\t%d", &mode) != 1)
 			continue;
@@ -44,10 +43,17 @@ int get_seccomp_mode(pid_t pid, bool after_checkpoint)
 int main(int argc, char ** argv)
 {
 	pid_t pid;
-	int ret = 1, mode;
+	int mode, status;
+	int sk_pair[2], sk;
+	char c = 'K';
 
 	test_init(argc, argv);
 
+	if (socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair)) {
+		err("socketpair");
+		return -1;
+	}
+
 	pid = fork();
 	if (pid < 0) {
 		err("fork");
@@ -55,29 +61,62 @@ int main(int argc, char ** argv)
 	}
 
 	if (pid == 0) {
+		sk = sk_pair[1];
+		close(sk_pair[0]);
+		zdtm_seccomp = 1;
+
 		if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT) < 0) {
 			err("prctl failed");
 			return -1;
 		}
+		test_msg("SECCOMP_MODE_STRICT is enabled\n");
 
-		while(1)
-			/* can't sleep() here, seccomp kills us */;
+		if (write(sk, &c, 1) != 1) {
+			err("write");
+			return -1;
+		}
+		if (read(sk, &c, 1) != 1) {
+			_exit(1);
+			err("read");
+			return -1;
+		}
+
+		syscall(__NR_exit, 0);
 	}
 
-	while(get_seccomp_mode(pid, false) != SECCOMP_MODE_STRICT)
-		sleep(1);
+	sk = sk_pair[0];
+	close(sk_pair[1]);
+
+	if (read(sk, &c, 1) != 1) {
+		err("read");
+		goto err;
+	}
 
 	test_daemon();
 	test_waitsig();
 
-	mode = get_seccomp_mode(pid, true);
+	mode = get_seccomp_mode(pid);
+	if (write(sk, &c, 1) != 1) {
+		err("write");
+		goto err;
+	}
+	if (waitpid(pid, &status, 0) != pid) {
+		err("waitpid");
+		exit(1);
+	}
+	if (status != 0) {
+		err("The child exited with an unexpected code %d", status);
+		exit(1);
+	}
 	if (mode != SECCOMP_MODE_STRICT) {
 		fail("seccomp mode mismatch %d\n", mode);
-	} else {
-		pass();
-		ret = 0;
+		return 1;
 	}
 
+	pass();
+
+	return 0;
+err:
 	kill(pid, SIGKILL);
-	return ret;
+	return 1;
 }
-- 
2.1.0



More information about the CRIU mailing list