From 89a39ea2597bb5e6f3c4cad04828337c717ea30d Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Thu, 11 Apr 2019 15:27:31 +0800
Subject: [PATCH 082/131] lxc: fix memory leak cause by setenv

isulad will call do_lxcapi_clean_resource(), so setenv at here, will
change env of isulad.

Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
 src/lxc/start.c | 107 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 76 insertions(+), 31 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index 10f922d0..87e07d33 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -2635,44 +2635,85 @@ on_error:
 }
 
 /*isulad: set env for clean resources */
-static void clean_resource_set_env(struct lxc_handler *handler)
+static int clean_resource_set_env(struct lxc_handler *handler)
 {
 	const char *name = handler->name;
 	struct lxc_conf *conf = handler->conf;
-	char pidstr[20];
-
-	/* Start of environment variable setup for hooks. */
-	if (name && setenv("LXC_NAME", name, 1))
-		SYSERROR("Failed to set environment variable: LXC_NAME=%s.", name);
-
-	if (conf->rcfile && setenv("LXC_CONFIG_FILE", conf->rcfile, 1))
-		SYSERROR("Failed to set environment variable: LXC_CONFIG_FILE=%s.", conf->rcfile);
-
-	if (conf->rootfs.mount && setenv("LXC_ROOTFS_MOUNT", conf->rootfs.mount, 1))
-		SYSERROR("Failed to set environment variable: LXC_ROOTFS_MOUNT=%s.", conf->rootfs.mount);
+	char bufstr[PATH_MAX + 1];
+	int i = 0;
+	int j = 0;
+	int len = 2; //set "LXC_PID" and "LXC_CGNS_AWARE"
 
-	if (conf->rootfs.path && setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1))
-		SYSERROR("Failed to set environment variable: LXC_ROOTFS_PATH=%s.", conf->rootfs.path);
-
-	if (conf->console.path && setenv("LXC_CONSOLE", conf->console.path, 1))
-		SYSERROR("Failed to set environment variable: LXC_CONSOLE=%s.", conf->console.path);
-
-	if (conf->console.log_path && setenv("LXC_CONSOLE_LOGPATH", conf->console.log_path, 1))
-		SYSERROR("Failed to set environment variable: LXC_CONSOLE_LOGPATH=%s.", conf->console.log_path);
-
-	if (setenv("LXC_CGNS_AWARE", "1", 1))
-		SYSERROR("Failed to set environment variable LXC_CGNS_AWARE=1.");
+	if (conf == NULL || conf->ocihooks == NULL || conf->ocihooks->poststop_len == 0) {
+		return 0;
+	}
 
+	if (name) {
+		len++;
+	}
+	if (conf->rcfile) {
+		len++;
+	}
+	if (conf->rootfs.mount) {
+		len++;
+	}
+	if (conf->rootfs.path) {
+		len++;
+	}
+	if (conf->console.path) {
+		len++;
+	}
+	if (conf->console.log_path) {
+		len++;
+	}
+	if (handler->cgroup_ops->container_cgroup) {
+		len++;
+	}
 
-	snprintf(pidstr, 20, "%d", handler->pid);
-	if (setenv("LXC_PID", pidstr, 1))
-		SYSERROR("Failed to set environment variable: LXC_PID=%s.", pidstr);
+	for (; i < conf->ocihooks->poststop_len; i++) {
+		size_t cap = conf->ocihooks->poststop[i]->env_len;
+		size_t newcap = cap + len + 1;
+		if (lxc_grow_array((void ***)&(conf->ocihooks->poststop[i]->env), &cap, newcap, 1) != 0) {
+			return -1;
+		}
+		j = conf->ocihooks->poststop[i]->env_len;
+		/* Start of environment variable setup for hooks. */
+		if (name) {
+			snprintf(bufstr, PATH_MAX + 1, "LXC_NAME=%s", name);
+			conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr);
+		}
+		if (conf->rcfile) {
+			snprintf(bufstr, PATH_MAX + 1, "LXC_CONFIG_FILE=%s", conf->rcfile);
+			conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr);
+		}
+		if (conf->rootfs.mount) {
+			snprintf(bufstr, PATH_MAX + 1, "LXC_ROOTFS_MOUNT=%s", conf->rootfs.mount);
+			conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr);
+		}
+		if (conf->rootfs.path) {
+			snprintf(bufstr, PATH_MAX + 1, "LXC_ROOTFS_PATH=%s", conf->rootfs.path);
+			conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr);
+		}
+		if (conf->console.path) {
+			snprintf(bufstr, PATH_MAX + 1, "LXC_CONSOLE=%s", conf->console.path);
+			conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr);
+		}
+		if (conf->console.log_path) {
+			snprintf(bufstr, PATH_MAX + 1, "LXC_CONSOLE_LOGPATH=%s", conf->console.log_path);
+			conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr);
+		}
+		conf->ocihooks->poststop[i]->env[j++] = strdup("LXC_CGNS_AWARE=1");
 
-	if (handler->cgroup_ops->container_cgroup) {
-		if (setenv("LXC_CGROUP_PATH", handler->cgroup_ops->container_cgroup, 1))
-			SYSERROR("Failed to set environment variable: LXC_CGROUP_PATH=%s.", handler->cgroup_ops->container_cgroup);
+		snprintf(bufstr, PATH_MAX + 1, "LXC_PID=%d", handler->pid);
+		conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr);
+		if (handler->cgroup_ops->container_cgroup) {
+			snprintf(bufstr, PATH_MAX + 1, "LXC_CGROUP_PATH=%s", handler->cgroup_ops->container_cgroup);
+			conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr);
+		}
+		conf->ocihooks->poststop[i]->env_len = j;
+		/* End of environment variable setup for hooks. */
 	}
-	/* End of environment variable setup for hooks. */
+	return 0;
 }
 
 /*isulad: do_lxcapi_clean_resource */
@@ -2690,7 +2731,11 @@ int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, p
 		goto out;
 	}
 
-	clean_resource_set_env(handler);
+	if (clean_resource_set_env(handler) != 0) {
+		ERROR("Failed to set env for poststop hooks");
+		ret = -1;
+		goto out;
+	}
 	// if we shared pid namespace with others, should kill all processes within container cgroup
 	if (handler->conf->ns_share[LXC_NS_PID] != NULL) {
 		signal_all_processes(handler);
-- 
2.23.0

