Commit 430a9be9 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

zdtm: remove busy loops from seccomp_strict

Don't heat a planet! :)

Cc: Tycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Acked-by: 's avatarTycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 6c572bee
...@@ -34,6 +34,7 @@ int test_log_init(const char *fname, const char *suffix) ...@@ -34,6 +34,7 @@ int test_log_init(const char *fname, const char *suffix)
return 0; return 0;
} }
int zdtm_seccomp;
void test_msg(const char *format, ...) void test_msg(const char *format, ...)
{ {
va_list arg; va_list arg;
...@@ -43,6 +44,9 @@ void test_msg(const char *format, ...) ...@@ -43,6 +44,9 @@ void test_msg(const char *format, ...)
struct timeval tv; struct timeval tv;
struct tm *tm; struct tm *tm;
if (zdtm_seccomp) /* seccomp allows restricted set of syscall-s */
goto skip;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
tm = localtime(&tv.tv_sec); tm = localtime(&tv.tv_sec);
if (tm == NULL) { if (tm == NULL) {
...@@ -53,6 +57,8 @@ void test_msg(const char *format, ...) ...@@ -53,6 +57,8 @@ void test_msg(const char *format, ...)
off += sprintf(buf + off, ".%.3ld: ", tv.tv_usec / 1000); off += sprintf(buf + off, ".%.3ld: ", tv.tv_usec / 1000);
off += sprintf(buf + off, "%5d: ", getpid()); off += sprintf(buf + off, "%5d: ", getpid());
skip:
va_start(arg, format); va_start(arg, format);
off += vsnprintf(buf + off, sizeof(buf) - off, format, arg); off += vsnprintf(buf + off, sizeof(buf) - off, format, arg);
va_end(arg); va_end(arg);
......
...@@ -101,6 +101,7 @@ extern int parse_opt_string(char *param, void *arg); ...@@ -101,6 +101,7 @@ extern int parse_opt_string(char *param, void *arg);
/* message helpers */ /* message helpers */
extern void setup_outfile(void); extern void setup_outfile(void);
extern int test_log_init(const char *outfile, const char *suffix); extern int test_log_init(const char *outfile, const char *suffix);
extern int zdtm_seccomp;
#define err(format, arg...) \ #define err(format, arg...) \
test_msg("ERR: %s:%d: " format " (errno = %d (%s))\n", \ test_msg("ERR: %s:%d: " format " (errno = %d (%s))\n", \
__FILE__, __LINE__, ## arg, errno, strerror(errno)) __FILE__, __LINE__, ## arg, errno, strerror(errno))
......
...@@ -4,12 +4,17 @@ ...@@ -4,12 +4,17 @@
#include <sys/prctl.h> #include <sys/prctl.h>
#include <linux/seccomp.h> #include <linux/seccomp.h>
#include <linux/limits.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" #include "zdtmtst.h"
const char *test_doc = "Check that SECCOMP_MODE_STRICT is restored"; const char *test_doc = "Check that SECCOMP_MODE_STRICT is restored";
const char *test_author = "Tycho Andersen <tycho.andersen@canonical.com>"; const char *test_author = "Tycho Andersen <tycho.andersen@canonical.com>";
int get_seccomp_mode(pid_t pid, bool after_checkpoint) int get_seccomp_mode(pid_t pid)
{ {
FILE *f; FILE *f;
char buf[PATH_MAX]; char buf[PATH_MAX];
...@@ -23,12 +28,6 @@ int get_seccomp_mode(pid_t pid, bool after_checkpoint) ...@@ -23,12 +28,6 @@ int get_seccomp_mode(pid_t pid, bool after_checkpoint)
while (NULL != fgets(buf, sizeof(buf), f)) { while (NULL != fgets(buf, sizeof(buf), f)) {
int mode; 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) if (sscanf(buf, "Seccomp:\t%d", &mode) != 1)
continue; continue;
...@@ -44,10 +43,17 @@ int get_seccomp_mode(pid_t pid, bool after_checkpoint) ...@@ -44,10 +43,17 @@ int get_seccomp_mode(pid_t pid, bool after_checkpoint)
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
pid_t pid; pid_t pid;
int ret = 1, mode; int mode, status;
int sk_pair[2], sk;
char c = 'K';
test_init(argc, argv); test_init(argc, argv);
if (socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair)) {
err("socketpair");
return -1;
}
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0) {
err("fork"); err("fork");
...@@ -55,29 +61,62 @@ int main(int argc, char ** argv) ...@@ -55,29 +61,62 @@ int main(int argc, char ** argv)
} }
if (pid == 0) { if (pid == 0) {
sk = sk_pair[1];
close(sk_pair[0]);
zdtm_seccomp = 1;
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT) < 0) { if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT) < 0) {
err("prctl failed"); err("prctl failed");
return -1; return -1;
} }
test_msg("SECCOMP_MODE_STRICT is enabled\n");
while(1) if (write(sk, &c, 1) != 1) {
/* can't sleep() here, seccomp kills us */; 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) sk = sk_pair[0];
sleep(1); close(sk_pair[1]);
if (read(sk, &c, 1) != 1) {
err("read");
goto err;
}
test_daemon(); test_daemon();
test_waitsig(); 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) { if (mode != SECCOMP_MODE_STRICT) {
fail("seccomp mode mismatch %d\n", mode); fail("seccomp mode mismatch %d\n", mode);
} else { return 1;
pass();
ret = 0;
} }
pass();
return 0;
err:
kill(pid, SIGKILL); kill(pid, SIGKILL);
return ret; return 1;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment