[CRIU] [PATCH 06/10] opts: use xstrdup () to assign char * options

Adrian Reber adrian at lisas.de
Wed Aug 1 19:31:18 MSK 2018


From: Adrian Reber <areber at redhat.com>

With the previous change to dynamically allocate memory for each
possible configuration source (three different configuration files, CLI,
RPC) the char * options can no longer directly point to the character
strings extracted by getopt() as the memory might be free'd at some
point. This introduces a macro to set the char * options which first
does a xfree() and then a xstrdup().

Signed-off-by: Adrian Reber <areber at redhat.com>
---
 criu/cgroup.c             |  2 +-
 criu/config.c             | 23 ++++++++++++-----------
 criu/cr-service.c         | 18 +++++++++---------
 criu/crtools.c            |  4 ++--
 criu/include/cr_options.h |  6 ++++++
 criu/lsm.c                |  5 +++--
 criu/plugin.c             |  4 ++--
 7 files changed, 35 insertions(+), 27 deletions(-)

diff --git a/criu/cgroup.c b/criu/cgroup.c
index 51759786e..c5d1284d0 100644
--- a/criu/cgroup.c
+++ b/criu/cgroup.c
@@ -1883,7 +1883,7 @@ int new_cg_root_add(char *controller, char *newroot)
 	struct cg_root_opt *o;
 
 	if (!controller) {
-		opts.new_global_cg_root = newroot;
+		SET_CHAR_OPTS(new_global_cg_root, newroot);
 		return 0;
 	}
 
diff --git a/criu/config.c b/criu/config.c
index 04469b613..3d4dc4431 100644
--- a/criu/config.c
+++ b/criu/config.c
@@ -568,7 +568,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd)
 			opts.show_pages_content	= true;
 			break;
 		case 'r':
-			opts.root = optarg;
+			SET_CHAR_OPTS(root, optarg);
 			break;
 		case 'd':
 			opts.restore_detach = true;
@@ -577,13 +577,13 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd)
 			opts.restore_sibling = true;
 			break;
 		case 'D':
-			opts.imgs_dir = optarg;
+			SET_CHAR_OPTS(imgs_dir, optarg);
 			break;
 		case 'W':
-			opts.work_dir = optarg;
+			SET_CHAR_OPTS(work_dir, optarg);
 			break;
 		case 'o':
-			opts.output = optarg;
+			SET_CHAR_OPTS(output, optarg);
 			break;
 		case 'J':
 			if (parse_join_ns(optarg))
@@ -608,7 +608,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd)
 			break;
 		}
 		case 1046:
-			opts.pidfile = optarg;
+			SET_CHAR_OPTS(pidfile, optarg);
 			break;
 		case 1047:
 			{
@@ -628,7 +628,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd)
 				return 1;
 			break;
 		case 1051:
-			opts.addr = optarg;
+			SET_CHAR_OPTS(addr, optarg);
 			break;
 		case 1052:
 			opts.port = atoi(optarg);
@@ -642,7 +642,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd)
 			opts.handle_file_locks = true;
 			break;
 		case 1053:
-			opts.img_parent = optarg;
+			SET_CHAR_OPTS(img_parent, optarg);
 			break;
 		case 1057:
 			if (parse_cpu_cap(&opts, optarg))
@@ -655,6 +655,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd)
 			pr_err("--ms is deprecated; see \"Check options\" of criu --help\n");
 			return 1;
 		case 'L':
+			SET_CHAR_OPTS(libdir, optarg);
 			opts.libdir = optarg;
 			break;
 		case 1059:
@@ -702,7 +703,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd)
 				return 1;
 			break;
 		case 1068:
-			opts.freeze_cgroup = optarg;
+			SET_CHAR_OPTS(freeze_cgroup, optarg);
 			break;
 		case 1069:
 			opts.ghost_limit = parse_size(optarg);
@@ -712,7 +713,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd)
 				return -1;
 			break;
 		case 1071:
-			opts.lsm_profile = optarg;
+			SET_CHAR_OPTS(lsm_profile, optarg);
 			opts.lsm_supplied = true;
 			break;
 		case 1072:
@@ -757,10 +758,10 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd)
 			opts.check_experimental_features = true;
 			break;
 		case 1080:
-			opts.cgroup_props = optarg;
+			SET_CHAR_OPTS(cgroup_props, optarg);
 			break;
 		case 1081:
-			opts.cgroup_props_file = optarg;
+			SET_CHAR_OPTS(cgroup_props_file, optarg);
 			break;
 		case 1082:
 			if (!cgp_add_dump_controller(optarg))
diff --git a/criu/cr-service.c b/criu/cr-service.c
index e9401be3a..c7c28857e 100644
--- a/criu/cr-service.c
+++ b/criu/cr-service.c
@@ -261,7 +261,7 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
 	sprintf(images_dir_path, "/proc/%d/fd/%d", ids.pid, req->images_dir_fd);
 
 	if (req->parent_img)
-		opts.img_parent = req->parent_img;
+		SET_CHAR_OPTS(img_parent, req->parent_img);
 
 	if (open_image_dir(images_dir_path) < 0) {
 		pr_perror("Can't open images directory");
@@ -292,9 +292,9 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
 			goto err;
 		}
 
-		opts.output = req->log_file;
+		SET_CHAR_OPTS(output, req->log_file);
 	} else
-		opts.output = DEFAULT_LOG_FILENAME;
+		SET_CHAR_OPTS(output, DEFAULT_LOG_FILENAME);
 
 	log_set_loglevel(req->log_level);
 	if (log_init(opts.output) == -1) {
@@ -325,7 +325,7 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
 	}
 
 	if (req->root)
-		opts.root = req->root;
+		SET_CHAR_OPTS(root, req->root);
 
 	if (req->has_rst_sibling) {
 		if (!opts.swrk_restore) {
@@ -381,7 +381,7 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
 
 		if (!opts.lazy_pages) {
 			opts.use_page_server = true;
-			opts.addr = req->ps->address;
+			SET_CHAR_OPTS(addr, req->ps->address);
 
 			if (req->ps->has_fd) {
 				if (!opts.swrk_restore)
@@ -485,16 +485,16 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
 	}
 
 	if (req->freeze_cgroup)
-		opts.freeze_cgroup = req->freeze_cgroup;
+		SET_CHAR_OPTS(freeze_cgroup, req->freeze_cgroup);
 
 	if (req->has_timeout)
 		opts.timeout = req->timeout;
 
 	if (req->cgroup_props)
-		opts.cgroup_props = req->cgroup_props;
+		SET_CHAR_OPTS(cgroup_props, req->cgroup_props);
 
 	if (req->cgroup_props_file)
-		opts.cgroup_props_file = req->cgroup_props_file;
+		SET_CHAR_OPTS(cgroup_props_file, req->cgroup_props_file);
 
 	for (i = 0; i < req->n_cgroup_dump_controller; i++) {
 		if (!cgp_add_dump_controller(req->cgroup_dump_controller[i]))
@@ -1158,7 +1158,7 @@ int cr_service(bool daemon_mode)
 
 		if (opts.addr == NULL) {
 			pr_warn("Binding to local dir address!\n");
-			opts.addr = CR_DEFAULT_SERVICE_ADDRESS;
+			SET_CHAR_OPTS(addr, CR_DEFAULT_SERVICE_ADDRESS);
 		}
 
 		strcpy(server_addr.sun_path, opts.addr);
diff --git a/criu/crtools.c b/criu/crtools.c
index 452bf0624..0d4eff948 100644
--- a/criu/crtools.c
+++ b/criu/crtools.c
@@ -176,10 +176,10 @@ int main(int argc, char *argv[], char *envp[])
 	}
 
 	if (opts.imgs_dir == NULL)
-		opts.imgs_dir = ".";
+		SET_CHAR_OPTS(imgs_dir, ".");
 
 	if (opts.work_dir == NULL)
-		opts.work_dir = opts.imgs_dir;
+		SET_CHAR_OPTS(work_dir, opts.imgs_dir);
 
 	if (optind >= argc) {
 		pr_msg("Error: command is required\n");
diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
index fde9adae0..95dc5ade5 100644
--- a/criu/include/cr_options.h
+++ b/criu/include/cr_options.h
@@ -6,6 +6,12 @@
 #include "common/config.h"
 #include "common/list.h"
 
+#define SET_CHAR_OPTS(__dest, __src) \
+	do { \
+		free(opts.__dest); \
+		opts.__dest = xstrdup(__src); \
+	} while(0)
+
 /*
  * CPU capability options.
  */
diff --git a/criu/lsm.c b/criu/lsm.c
index fd098581f..eec73ede5 100644
--- a/criu/lsm.c
+++ b/criu/lsm.c
@@ -230,15 +230,16 @@ int lsm_check_opts(void)
 			return -1;
 		}
 
-		opts.lsm_profile = aux;
+		SET_CHAR_OPTS(lsm_profile, aux);
 	} else if (strcmp(opts.lsm_profile, "selinux") == 0) {
 		if (kdat.lsm != LSMTYPE__SELINUX) {
 			pr_err("selinux LSM specified but selinux not supported by kernel\n");
 			return -1;
 		}
 
-		opts.lsm_profile = aux;
+		SET_CHAR_OPTS(lsm_profile, aux);
 	} else if (strcmp(opts.lsm_profile, "none") == 0) {
+		xfree(opts.lsm_profile);
 		opts.lsm_profile = NULL;
 	} else {
 		pr_err("unknown lsm %s\n", opts.lsm_profile);
diff --git a/criu/plugin.c b/criu/plugin.c
index 6d9511857..0db862924 100644
--- a/criu/plugin.c
+++ b/criu/plugin.c
@@ -203,12 +203,12 @@ int cr_plugin_init(int stage)
 	if (opts.libdir == NULL) {
 		path = getenv("CRIU_LIBS_DIR");
 		if (path)
-			opts.libdir = path;
+			SET_CHAR_OPTS(libdir, path);
 		else {
 			if (access(CR_PLUGIN_DEFAULT, F_OK))
 				return 0;
 
-			opts.libdir = CR_PLUGIN_DEFAULT;
+			SET_CHAR_OPTS(libdir, CR_PLUGIN_DEFAULT);
 		}
 	}
 
-- 
2.18.0



More information about the CRIU mailing list