From a98014f306be4b4fefdf01af31e1efa5d83e5e4f Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Wed, 17 Feb 2016 08:03:00 +0300 Subject: [PATCH] seccomp: add a --no-seccomp option to disable dumping seccomp 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 CC: Saied Kazemi Signed-off-by: Pavel Emelyanov --- 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 | 1 + lib/c/criu.c | 11 +++++++++++ lib/c/criu.h | 2 ++ 8 files changed, 36 insertions(+) diff --git a/Documentation/criu.txt b/Documentation/criu.txt index e7ba6ddb6..c1eeb7227 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 88d4af725..84d1657f0 100644 --- a/criu/cr-service.c +++ b/criu/cr-service.c @@ -473,6 +473,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 fa4c4f766..748dd4cee 100644 --- a/criu/crtools.c +++ b/criu/crtools.c @@ -274,6 +274,7 @@ int main(int argc, char *argv[], char *envp[]) { "timeout", required_argument, 0, 1072 }, { "external", required_argument, 0, 1073 }, { "empty-ns", required_argument, 0, 1074 }, + { "no-seccomp", no_argument, 0, 1075 }, { }, }; @@ -553,6 +554,9 @@ int main(int argc, char *argv[], char *envp[]) return 1; } break; + case 1075: + opts.no_seccomp = true; + break; case 'V': pr_msg("Version: %s\n", CRIU_VERSION); if (strcmp(CRIU_GITID, "0")) @@ -805,6 +809,10 @@ usage: " --empty-ns {net}\n" " Create a namespace, but don't restore its properies.\n" " An user will retore them from action scripts.\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 a6f0b3ee6..dff08522a 100644 --- a/criu/include/cr_options.h +++ b/criu/include/cr_options.h @@ -107,6 +107,7 @@ struct cr_options { char *lsm_profile; unsigned int timeout; unsigned int empty_ns; + bool no_seccomp; }; extern struct cr_options opts; diff --git a/criu/proc_parse.c b/criu/proc_parse.c index 9825da917..1d117704b 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 fac4b9fa0..34fa98844 100644 --- a/images/rpc.proto +++ b/images/rpc.proto @@ -90,6 +90,7 @@ message criu_opts { repeated string irmap_scan_paths = 36; repeated string external = 37; optional uint32 empty_ns = 38; + optional bool no_seccomp = 39; } message criu_dump_resp { diff --git a/lib/c/criu.c b/lib/c/criu.c index 52d1b61d6..3fb4005f8 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 0898be024..38bf0ce4a 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));