[CRIU] [PATCH] seccomp: add a --no-seccomp option to disable dumping seccomp

Tycho Andersen tycho.andersen at canonical.com
Tue Feb 16 21:03:37 PST 2016


Sometimes we may want to use CRIU on older kernels which don't support
dumping seccomp state where we don't actually care about the seccomp state.
Of course this is unsafe, but it does allow for c/r of things using
seccomp on these older kernels in some cases. When the task is in
SECCOMP_MODE_STRICT or SECCOMP_MODE_FILTER with filters that block the
syscalls criu's parasite code needs, the dump will still fail.

Note that we disable seccomp by simply feigning that we are in mode 0. This
is a little hacky, but avoids distributing ifs throughout the code and
keeps them in this one place.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
CC: Saied Kazemi <saied at google.com>
---
 Documentation/criu.txt    |  5 +++++
 criu/cr-service.c         |  3 +++
 criu/crtools.c            |  8 ++++++++
 criu/include/cr_options.h |  1 +
 criu/proc_parse.c         |  5 +++++
 images/rpc.proto          |  2 ++
 lib/c/criu.c              | 11 +++++++++++
 lib/c/criu.h              |  2 ++
 8 files changed, 37 insertions(+)

diff --git a/Documentation/criu.txt b/Documentation/criu.txt
index e7ba6dd..c1eeb72 100644
--- a/Documentation/criu.txt
+++ b/Documentation/criu.txt
@@ -205,6 +205,11 @@ In other words, do not use it until really needed.
     information into image file. If the option is omitted or set to *none*
     then image will not be written. By default *criu* do not write this image.
 
+*--no-seccomp*::
+    Disable the dumping of seccomp state; this is useful for c/r of tasks using
+    seccomp running on old kernels which do not have support for dump and
+    restore of seccomp state.
+
 *restore*
 ~~~~~~~~~
 Restores previously checkpointed processes.
diff --git a/criu/cr-service.c b/criu/cr-service.c
index a1987e7..c4105ce 100644
--- a/criu/cr-service.c
+++ b/criu/cr-service.c
@@ -466,6 +466,9 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
 		}
 	}
 
+	if (req->has_no_seccomp)
+		opts.no_seccomp = req->no_seccomp;
+
 	return 0;
 
 err:
diff --git a/criu/crtools.c b/criu/crtools.c
index 9cf7475..fa6b86d 100644
--- a/criu/crtools.c
+++ b/criu/crtools.c
@@ -272,6 +272,7 @@ int main(int argc, char *argv[], char *envp[])
 		{ "lsm-profile",		required_argument,	0, 1071 },
 		{ "timeout",			required_argument,	0, 1072 },
 		{ "external",			required_argument,	0, 1073	},
+		{ "no-seccomp",			no_argument,		0, 1074 },
 		{ },
 	};
 
@@ -543,6 +544,9 @@ int main(int argc, char *argv[], char *envp[])
 			if (add_external(optarg))
 				return 1;
 			break;
+		case 1074:
+			opts.no_seccomp = true;
+			break;
 		case 'V':
 			pr_msg("Version: %s\n", CRIU_VERSION);
 			if (strcmp(CRIU_GITID, "0"))
@@ -792,6 +796,10 @@ usage:
 "                            tty[rdev:dev]\n"
 "                            pipe[inode]\n"
 "                            socket[inode]\n"
+"  --no-seccomp          Disable the dumping of seccomp state; this is useful\n"
+"                        for c/r of tasks using seccomp running on old kernels\n"
+"                        which do not have support for dump and restore\n"
+"                        of seccomp state.\n"
 "\n"
 "* Logging:\n"
 "  -o|--log-file FILE    log file name\n"
diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
index 5c0e633..8afb4cd 100644
--- a/criu/include/cr_options.h
+++ b/criu/include/cr_options.h
@@ -106,6 +106,7 @@ struct cr_options {
 	bool			lsm_supplied;
 	char			*lsm_profile;
 	unsigned int		timeout;
+	bool			no_seccomp;
 };
 
 extern struct cr_options opts;
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index 9825da9..1d11770 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -1004,6 +1004,11 @@ int parse_pid_status(pid_t pid, struct proc_status_creds *cr)
 				goto err_parse;
 			}
 
+			if (opts.no_seccomp && cr->seccomp_mode != SECCOMP_MODE_DISABLED) {
+				pr_warn("task %d has seccomp, not disabling, dump may fail\n", pid);
+				cr->seccomp_mode = SECCOMP_MODE_DISABLED;
+			}
+
 			parsed_seccomp = true;
 			done++;
 			continue;
diff --git a/images/rpc.proto b/images/rpc.proto
index 4f6ed8d..1a1f0d1 100644
--- a/images/rpc.proto
+++ b/images/rpc.proto
@@ -89,6 +89,8 @@ message criu_opts {
 	optional uint32			ghost_limit	= 35 [default = 0x100000];
 	repeated string			irmap_scan_paths = 36;
 	repeated string			external	= 37;
+
+	optional bool			no_seccomp	= 38;
 }
 
 message criu_dump_resp {
diff --git a/lib/c/criu.c b/lib/c/criu.c
index 52d1b61..3fb4005 100644
--- a/lib/c/criu.c
+++ b/lib/c/criu.c
@@ -700,6 +700,12 @@ err:
 	return -ENOMEM;
 }
 
+void criu_local_set_no_seccomp(criu_opts *opts, bool val)
+{
+	opts->rpc->has_no_seccomp = true;
+	opts->rpc->no_seccomp = val;
+}
+
 int criu_add_skip_mnt(char *mnt)
 {
 	return criu_local_add_skip_mnt(global_opts, mnt);
@@ -721,6 +727,11 @@ int criu_add_irmap_path(char *path)
 	return criu_local_add_irmap_path(global_opts, path);
 }
 
+void criu_set_no_seccomp(bool val)
+{
+	return criu_local_set_no_seccomp(global_opts, val);
+}
+
 static CriuResp *recv_resp(int socket_fd)
 {
 	unsigned char *buf = NULL;
diff --git a/lib/c/criu.h b/lib/c/criu.h
index 0898be0..38bf0ce 100644
--- a/lib/c/criu.h
+++ b/lib/c/criu.h
@@ -89,6 +89,7 @@ int criu_add_enable_fs(char *fs);
 int criu_add_skip_mnt(char *mnt);
 void criu_set_ghost_limit(unsigned int limit);
 int criu_add_irmap_path(char *path);
+void criu_set_no_seccomp(bool no_seccomp);
 
 /*
  * The criu_notify_arg_t na argument is an opaque
@@ -191,6 +192,7 @@ int criu_local_add_enable_fs(criu_opts *opts, char *fs);
 int criu_local_add_skip_mnt(criu_opts *opts, char *mnt);
 void criu_local_set_ghost_limit(criu_opts *opts, unsigned int limit);
 int criu_local_add_irmap_path(criu_opts *opts, char *path);
+void criu_local_set_no_seccomp(criu_opots *opts, bool val);
 
 void criu_local_set_notify_cb(criu_opts *opts, int (*cb)(char *action, criu_notify_arg_t na));
 
-- 
2.6.4



More information about the CRIU mailing list