[lxc-devel] [lxc/master] tree-wide: thread-safety improvements

brauner on Github lxc-bot at linuxcontainers.org
Fri Feb 23 14:37:00 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180223/9de5556c/attachment.bin>
-------------- next part --------------
From 1a344f2bbd8e52bb29c3ac1e479100d8bee6fa30 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 13:24:35 +0100
Subject: [PATCH 01/18] confile: use mmap() to parse config file

Sigh, this is going to be fun. Essentially, dynamic memory allocation through
malloc() and friends is unsafe when fork()ing in threads. The locking state
that glibc maintains internally might get messed up when the process that
fork()ed calls malloc or calls functions that malloc() internally. Functions
that internally malloc() include fopen(). One solution here is to use open() +
mmap() instead of fopen() + getline().

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/Makefile.am        |  2 +-
 src/lxc/cmd/lxc_user_nic.c |  1 +
 src/lxc/confile.c          |  2 +-
 src/lxc/lxccontainer.c     |  1 +
 src/lxc/parse.c            | 79 ++++++++++++++++++++++++++++++++++++++++++++--
 src/lxc/parse.h            | 13 ++++++++
 src/lxc/utils.c            | 27 ----------------
 src/lxc/utils.h            |  7 ----
 8 files changed, 93 insertions(+), 39 deletions(-)

diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
index 8e7c64c46..bee953808 100644
--- a/src/lxc/Makefile.am
+++ b/src/lxc/Makefile.am
@@ -278,7 +278,7 @@ lxc_checkpoint_SOURCES = tools/lxc_checkpoint.c tools/arguments.c tools/tool_uti
 # Binaries shipping with liblxc
 init_lxc_SOURCES = cmd/lxc_init.c
 lxc_monitord_SOURCES = cmd/lxc_monitord.c
-lxc_user_nic_SOURCES = cmd/lxc_user_nic.c namespace.c network.c
+lxc_user_nic_SOURCES = cmd/lxc_user_nic.c namespace.c network.c parse.c
 lxc_usernsexec_SOURCES = cmd/lxc_usernsexec.c
 
 if ENABLE_DEPRECATED
diff --git a/src/lxc/cmd/lxc_user_nic.c b/src/lxc/cmd/lxc_user_nic.c
index 2a5c3a43a..d071ce0b5 100644
--- a/src/lxc/cmd/lxc_user_nic.c
+++ b/src/lxc/cmd/lxc_user_nic.c
@@ -48,6 +48,7 @@
 #include "config.h"
 #include "namespace.h"
 #include "network.h"
+#include "parse.h"
 #include "utils.h"
 
 #define usernic_debug_stream(stream, format, ...)                              \
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index a9db53630..effff93dd 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -2334,7 +2334,7 @@ int lxc_config_read(const char *file, struct lxc_conf *conf, bool from_include)
 	if (!conf->rcfile)
 		conf->rcfile = strdup(file);
 
-	return lxc_file_for_each_line(file, parse_line, &c);
+	return lxc_file_for_each_line_mmap(file, parse_line, &c);
 }
 
 int lxc_config_define_add(struct lxc_list *defines, char *arg)
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 26fdc23bf..e6ad6d501 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -57,6 +57,7 @@
 #include "monitor.h"
 #include "namespace.h"
 #include "network.h"
+#include "parse.h"
 #include "start.h"
 #include "state.h"
 #include "storage.h"
diff --git a/src/lxc/parse.c b/src/lxc/parse.c
index 9242763e9..fba250683 100644
--- a/src/lxc/parse.c
+++ b/src/lxc/parse.c
@@ -20,13 +20,15 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
+
 #define _GNU_SOURCE
 #include <stdio.h>
 #undef _GNU_SOURCE
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
 #include <dirent.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
 
 #include "parse.h"
 #include "config.h"
@@ -35,6 +37,77 @@
 
 lxc_log_define(lxc_parse, lxc);
 
+void *lxc_strmmap(void *addr, size_t length, int prot, int flags, int fd,
+		  off_t offset)
+{
+	void *tmp = NULL, *overlap = NULL;
+
+	/* We establish an anonymous mapping that is one byte larger than the
+	 * underlying file. The pages handed to us are zero filled. */
+	tmp = mmap(addr, length + 1, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+	if (tmp == MAP_FAILED)
+		return tmp;
+
+	/* Now we establish a fixed-address mapping starting at the address we
+	 * received from our anonymous mapping and replace all bytes excluding
+	 * the additional \0-byte with the file. This allows us to use normal
+	 * string-handling functions. */
+	overlap = mmap(tmp, length, prot, MAP_FIXED | flags, fd, offset);
+	if (overlap == MAP_FAILED)
+		munmap(tmp, length + 1);
+
+	return overlap;
+}
+
+int lxc_strmunmap(void *addr, size_t length)
+{
+	return munmap(addr, length + 1);
+}
+
+int lxc_file_for_each_line_mmap(const char *file, lxc_file_cb callback,
+				void *data)
+{
+	int fd, ret;
+	char *buf, *line;
+	struct stat st;
+	char *saveptr = NULL;
+
+	fd = open(file, O_RDONLY | O_CLOEXEC);
+	if (fd < 0)
+		return -1;
+
+	ret = fstat(fd, &st);
+	if (ret < 0) {
+		close(fd);
+		return -1;
+	}
+
+	if (st.st_size == 0)
+		return 0;
+
+	buf = lxc_strmmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+	if (buf == MAP_FAILED) {
+		close(fd);
+		return -1;
+	}
+
+	for (; (line = strtok_r(buf, "\n\0", &saveptr)); buf = NULL) {
+		ret = callback(line, data);
+		if (ret) {
+			/* Callback rv > 0 means stop here callback rv < 0 means
+			 * error.
+			 */
+			if (ret < 0)
+				ERROR("Failed to parse config: %s", line);
+			break;
+		}
+	}
+
+	lxc_strmunmap(buf, st.st_size);
+	close(fd);
+	return 0;
+}
+
 int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data)
 {
 	FILE *f;
diff --git a/src/lxc/parse.h b/src/lxc/parse.h
index 8f753198b..361ad33ea 100644
--- a/src/lxc/parse.h
+++ b/src/lxc/parse.h
@@ -23,6 +23,9 @@
 #ifndef __LXC_PARSE_H
 #define __LXC_PARSE_H
 
+#include <stdio.h>
+#include <sys/types.h>
+
 typedef int (*lxc_dir_cb)(const char *name, const char *directory,
 			  const char *file, void *data);
 
@@ -31,10 +34,20 @@ typedef int (*lxc_file_cb)(char *buffer, void *data);
 extern int lxc_file_for_each_line(const char *file, lxc_file_cb callback,
 				  void* data);
 
+extern int lxc_file_for_each_line_mmap(const char *file, lxc_file_cb callback,
+				       void *data);
+
 extern int lxc_char_left_gc(const char *buffer, size_t len);
 
 extern int lxc_char_right_gc(const char *buffer, size_t len);
 
 extern int lxc_is_line_empty(const char *line);
 
+/* mmap() wrapper. lxc_strmmap() will take care to \0-terminate files so that
+ * normal string-handling functions can be used on the buffer. */
+extern void *lxc_strmmap(void *addr, size_t length, int prot, int flags, int fd,
+			 off_t offset);
+/* munmap() wrapper. Use it to free memory mmap()ed with lxc_strmmap(). */
+extern int lxc_strmunmap(void *addr, size_t length);
+
 #endif
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index d7527b429..c824e9b99 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -1810,33 +1810,6 @@ int lxc_count_file_lines(const char *fn)
 	return n;
 }
 
-void *lxc_strmmap(void *addr, size_t length, int prot, int flags, int fd,
-		  off_t offset)
-{
-	void *tmp = NULL, *overlap = NULL;
-
-	/* We establish an anonymous mapping that is one byte larger than the
-	 * underlying file. The pages handed to us are zero filled. */
-	tmp = mmap(addr, length + 1, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-	if (tmp == MAP_FAILED)
-		return tmp;
-
-	/* Now we establish a fixed-address mapping starting at the address we
-	 * received from our anonymous mapping and replace all bytes excluding
-	 * the additional \0-byte with the file. This allows us to use normal
-	 * string-handling functions. */
-	overlap = mmap(tmp, length, prot, MAP_FIXED | flags, fd, offset);
-	if (overlap == MAP_FAILED)
-		munmap(tmp, length + 1);
-
-	return overlap;
-}
-
-int lxc_strmunmap(void *addr, size_t length)
-{
-	return munmap(addr, length + 1);
-}
-
 /* Check whether a signal is blocked by a process. */
 /* /proc/pid-to-str/status\0 = (5 + 21 + 7 + 1) */
 #define __PROC_STATUS_LEN (5 + (LXC_NUMSTRLEN64) + 7 + 1)
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 87b5a22b4..f013ef23e 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -426,13 +426,6 @@ extern size_t lxc_array_len(void **array);
 
 extern void **lxc_append_null_to_array(void **array, size_t count);
 
-/* mmap() wrapper. lxc_strmmap() will take care to \0-terminate files so that
- * normal string-handling functions can be used on the buffer. */
-extern void *lxc_strmmap(void *addr, size_t length, int prot, int flags, int fd,
-			 off_t offset);
-/* munmap() wrapper. Use it to free memory mmap()ed with lxc_strmmap(). */
-extern int lxc_strmunmap(void *addr, size_t length);
-
 /* initialize rand with urandom */
 extern int randseed(bool);
 

From f40623b641c88d5f76159ca5a98edf9d22fbd82d Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 13:26:11 +0100
Subject: [PATCH 02/18] lxccontainer: thread-safety: do_lxcapi_start()

s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index e6ad6d501..3b9874eba 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -903,14 +903,14 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		pid = fork();
 		if (pid < 0) {
 			SYSERROR("Failed to fork first child process");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* second parent */
 		if (pid != 0) {
 			free_init_cmd(init_cmd);
 			lxc_free_handler(handler);
-			exit(EXIT_SUCCESS);
+			_exit(EXIT_SUCCESS);
 		}
 
 		/* second child */
@@ -919,7 +919,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		ret = chdir("/");
 		if (ret < 0) {
 			SYSERROR("Failed to change to \"/\" directory");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		keepfds[0] = handler->conf->maincmd_fd;
@@ -928,13 +928,13 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		ret = lxc_check_inherited(conf, true, keepfds,
 					  sizeof(keepfds) / sizeof(keepfds[0]));
 		if (ret < 0)
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 
 		/* redirect std{in,out,err} to /dev/null */
 		ret = null_stdfds();
 		if (ret < 0) {
 			ERROR("Failed to redirect std{in,out,err} to /dev/null");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* become session leader */
@@ -961,7 +961,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 			free_init_cmd(init_cmd);
 			lxc_free_handler(handler);
 			if (daemonize)
-				exit(EXIT_FAILURE);
+				_exit(EXIT_FAILURE);
 			return false;
 		}
 
@@ -972,7 +972,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 			free_init_cmd(init_cmd);
 			lxc_free_handler(handler);
 			if (daemonize)
-				exit(EXIT_FAILURE);
+				_exit(EXIT_FAILURE);
 			return false;
 		}
 
@@ -1043,9 +1043,9 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 	free_init_cmd(init_cmd);
 
 	if (daemonize && ret != 0)
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	else if (daemonize)
-		exit(EXIT_SUCCESS);
+		_exit(EXIT_SUCCESS);
 
 	if (ret != 0)
 		return false;

From 2abab3e45975baaa4223a820683cefd4de17f7a5 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 13:56:35 +0100
Subject: [PATCH 03/18] lxccontainer: thread_safety: create_run_template()

s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 56 +++++++++++++++++++++++++-------------------------
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 3b9874eba..0eb87bd5d 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -1249,19 +1249,19 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		struct lxc_conf *conf = c->lxc_conf;
 
 		if (need_null_stdfds && null_stdfds() < 0) {
-			exit(1);
+			_exit(1);
 		}
 
 		bdev = storage_init(c->lxc_conf);
 		if (!bdev) {
 			ERROR("Error opening rootfs");
-			exit(1);
+			_exit(1);
 		}
 
 		if (geteuid() == 0) {
 			if (unshare(CLONE_NEWNS) < 0) {
 				ERROR("error unsharing mounts");
-				exit(1);
+				_exit(1);
 			}
 			if (detect_shared_rootfs()) {
 				if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
@@ -1273,7 +1273,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		if (strcmp(bdev->type, "dir") && strcmp(bdev->type, "btrfs")) {
 			if (geteuid() != 0) {
 				ERROR("non-root users can only create btrfs and directory-backed containers");
-				exit(EXIT_FAILURE);
+				_exit(EXIT_FAILURE);
 			}
 
 			if (!strcmp(bdev->type, "overlay") || !strcmp(bdev->type, "overlayfs")) {
@@ -1299,7 +1299,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 				src = ovl_get_rootfs(bdev->src, &(size_t){0});
 				if (!src) {
 					ERROR("Failed to get rootfs");
-					exit(EXIT_FAILURE);
+					_exit(EXIT_FAILURE);
 				}
 
 				ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC, NULL);
@@ -1310,7 +1310,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 			} else {
 				if (bdev->ops->mount(bdev) < 0) {
 					ERROR("Failed to mount rootfs");
-					exit(EXIT_FAILURE);
+					_exit(EXIT_FAILURE);
 				}
 			}
 		} else { /* TODO come up with a better way here! */
@@ -1330,33 +1330,33 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 
 		newargv = malloc(nargs * sizeof(*newargv));
 		if (!newargv)
-			exit(1);
+			_exit(1);
 		newargv[0] = lxcbasename(tpath);
 
 		len = strlen(c->config_path) + strlen(c->name) + strlen("--path=") + 2;
 		patharg = malloc(len);
 		if (!patharg)
-			exit(1);
+			_exit(1);
 		ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name);
 		if (ret < 0 || ret >= len)
-			exit(1);
+			_exit(1);
 		newargv[1] = patharg;
 		len = strlen("--name=") + strlen(c->name) + 1;
 		namearg = malloc(len);
 		if (!namearg)
-			exit(1);
+			_exit(1);
 		ret = snprintf(namearg, len, "--name=%s", c->name);
 		if (ret < 0 || ret >= len)
-			exit(1);
+			_exit(1);
 		newargv[2] = namearg;
 
 		len = strlen("--rootfs=") + 1 + strlen(bdev->dest);
 		rootfsarg = malloc(len);
 		if (!rootfsarg)
-			exit(1);
+			_exit(1);
 		ret = snprintf(rootfsarg, len, "--rootfs=%s", bdev->dest);
 		if (ret < 0 || ret >= len)
-			exit(1);
+			_exit(1);
 		newargv[3] = rootfsarg;
 
 		/* add passed-in args */
@@ -1368,7 +1368,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		nargs++;
 		newargv = realloc(newargv, nargs * sizeof(*newargv));
 		if (!newargv)
-			exit(1);
+			_exit(1);
 		newargv[nargs - 1] = NULL;
 
 		/*
@@ -1388,7 +1388,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 
 			if (!n2) {
 				SYSERROR("out of memory");
-				exit(1);
+				_exit(1);
 			}
 			newargv[0] = tpath;
 			tpath = "lxc-usernsexec";
@@ -1398,63 +1398,63 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 				n2args += 2;
 				n2 = realloc(n2, n2args * sizeof(char *));
 				if (!n2)
-					exit(1);
+					_exit(1);
 				n2[n2args-2] = "-m";
 				n2[n2args-1] = malloc(200);
 				if (!n2[n2args-1])
-					exit(1);
+					_exit(1);
 				ret = snprintf(n2[n2args-1], 200, "%c:%lu:%lu:%lu",
 					map->idtype == ID_TYPE_UID ? 'u' : 'g',
 					map->nsid, map->hostid, map->range);
 				if (ret < 0 || ret >= 200)
-					exit(1);
+					_exit(1);
 			}
 			int hostid_mapped = mapped_hostid(geteuid(), conf, ID_TYPE_UID);
 			int extraargs = hostid_mapped >= 0 ? 1 : 3;
 			n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
 			if (!n2)
-				exit(1);
+				_exit(1);
 			if (hostid_mapped < 0) {
 				hostid_mapped = find_unmapped_nsid(conf, ID_TYPE_UID);
 				n2[n2args++] = "-m";
 				if (hostid_mapped < 0) {
 					ERROR("Could not find free uid to map");
-					exit(1);
+					_exit(1);
 				}
 				n2[n2args++] = malloc(200);
 				if (!n2[n2args-1]) {
 					SYSERROR("out of memory");
-					exit(1);
+					_exit(1);
 				}
 				ret = snprintf(n2[n2args-1], 200, "u:%d:%d:1",
 					hostid_mapped, geteuid());
 				if (ret < 0 || ret >= 200) {
 					ERROR("string too long");
-					exit(1);
+					_exit(1);
 				}
 			}
 			int hostgid_mapped = mapped_hostid(getegid(), conf, ID_TYPE_GID);
 			extraargs = hostgid_mapped >= 0 ? 1 : 3;
 			n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
 			if (!n2)
-				exit(1);
+				_exit(1);
 			if (hostgid_mapped < 0) {
 				hostgid_mapped = find_unmapped_nsid(conf, ID_TYPE_GID);
 				n2[n2args++] = "-m";
 				if (hostgid_mapped < 0) {
 					ERROR("Could not find free uid to map");
-					exit(1);
+					_exit(1);
 				}
 				n2[n2args++] = malloc(200);
 				if (!n2[n2args-1]) {
 					SYSERROR("out of memory");
-					exit(1);
+					_exit(1);
 				}
 				ret = snprintf(n2[n2args-1], 200, "g:%d:%d:1",
 					hostgid_mapped, getegid());
 				if (ret < 0 || ret >= 200) {
 					ERROR("string too long");
-					exit(1);
+					_exit(1);
 				}
 			}
 			n2[n2args++] = "--";
@@ -1468,7 +1468,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 			n2 = realloc(n2, n2args * sizeof(char *));
 			if (!n2) {
 				SYSERROR("out of memory");
-				exit(1);
+				_exit(1);
 			}
 			/* note n2[n2args-1] is NULL */
 			n2[n2args-5] = "--mapped-uid";
@@ -1484,7 +1484,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		/* execute */
 		execvp(tpath, newargv);
 		SYSERROR("Failed to execute template %s", tpath);
-		exit(1);
+		_exit(1);
 	}
 
 	if (wait_for_pid(pid) != 0) {

From 927818ba24a65213a4089345940687b2c2f157e9 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 13:59:16 +0100
Subject: [PATCH 04/18] lxccontainer: non-functional changes

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 52 +++++++++++++++++++++++++-------------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 0eb87bd5d..a83e44bab 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -1236,7 +1236,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 
 	pid = fork();
 	if (pid < 0) {
-		SYSERROR("failed to fork task for container creation template");
+		SYSERROR("Failed to fork task for container creation template");
 		return false;
 	}
 
@@ -1249,19 +1249,19 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		struct lxc_conf *conf = c->lxc_conf;
 
 		if (need_null_stdfds && null_stdfds() < 0) {
-			_exit(1);
+			_exit(EXIT_FAILURE);
 		}
 
 		bdev = storage_init(c->lxc_conf);
 		if (!bdev) {
 			ERROR("Error opening rootfs");
-			_exit(1);
+			_exit(EXIT_FAILURE);
 		}
 
 		if (geteuid() == 0) {
 			if (unshare(CLONE_NEWNS) < 0) {
 				ERROR("error unsharing mounts");
-				_exit(1);
+				_exit(EXIT_FAILURE);
 			}
 			if (detect_shared_rootfs()) {
 				if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
@@ -1330,33 +1330,33 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 
 		newargv = malloc(nargs * sizeof(*newargv));
 		if (!newargv)
-			_exit(1);
+			_exit(EXIT_FAILURE);
 		newargv[0] = lxcbasename(tpath);
 
 		len = strlen(c->config_path) + strlen(c->name) + strlen("--path=") + 2;
 		patharg = malloc(len);
 		if (!patharg)
-			_exit(1);
+			_exit(EXIT_FAILURE);
 		ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name);
 		if (ret < 0 || ret >= len)
-			_exit(1);
+			_exit(EXIT_FAILURE);
 		newargv[1] = patharg;
 		len = strlen("--name=") + strlen(c->name) + 1;
 		namearg = malloc(len);
 		if (!namearg)
-			_exit(1);
+			_exit(EXIT_FAILURE);
 		ret = snprintf(namearg, len, "--name=%s", c->name);
 		if (ret < 0 || ret >= len)
-			_exit(1);
+			_exit(EXIT_FAILURE);
 		newargv[2] = namearg;
 
 		len = strlen("--rootfs=") + 1 + strlen(bdev->dest);
 		rootfsarg = malloc(len);
 		if (!rootfsarg)
-			_exit(1);
+			_exit(EXIT_FAILURE);
 		ret = snprintf(rootfsarg, len, "--rootfs=%s", bdev->dest);
 		if (ret < 0 || ret >= len)
-			_exit(1);
+			_exit(EXIT_FAILURE);
 		newargv[3] = rootfsarg;
 
 		/* add passed-in args */
@@ -1368,7 +1368,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		nargs++;
 		newargv = realloc(newargv, nargs * sizeof(*newargv));
 		if (!newargv)
-			_exit(1);
+			_exit(EXIT_FAILURE);
 		newargv[nargs - 1] = NULL;
 
 		/*
@@ -1388,7 +1388,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 
 			if (!n2) {
 				SYSERROR("out of memory");
-				_exit(1);
+				_exit(EXIT_FAILURE);
 			}
 			newargv[0] = tpath;
 			tpath = "lxc-usernsexec";
@@ -1398,63 +1398,63 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 				n2args += 2;
 				n2 = realloc(n2, n2args * sizeof(char *));
 				if (!n2)
-					_exit(1);
+					_exit(EXIT_FAILURE);
 				n2[n2args-2] = "-m";
 				n2[n2args-1] = malloc(200);
 				if (!n2[n2args-1])
-					_exit(1);
+					_exit(EXIT_FAILURE);
 				ret = snprintf(n2[n2args-1], 200, "%c:%lu:%lu:%lu",
 					map->idtype == ID_TYPE_UID ? 'u' : 'g',
 					map->nsid, map->hostid, map->range);
 				if (ret < 0 || ret >= 200)
-					_exit(1);
+					_exit(EXIT_FAILURE);
 			}
 			int hostid_mapped = mapped_hostid(geteuid(), conf, ID_TYPE_UID);
 			int extraargs = hostid_mapped >= 0 ? 1 : 3;
 			n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
 			if (!n2)
-				_exit(1);
+				_exit(EXIT_FAILURE);
 			if (hostid_mapped < 0) {
 				hostid_mapped = find_unmapped_nsid(conf, ID_TYPE_UID);
 				n2[n2args++] = "-m";
 				if (hostid_mapped < 0) {
 					ERROR("Could not find free uid to map");
-					_exit(1);
+					_exit(EXIT_FAILURE);
 				}
 				n2[n2args++] = malloc(200);
 				if (!n2[n2args-1]) {
 					SYSERROR("out of memory");
-					_exit(1);
+					_exit(EXIT_FAILURE);
 				}
 				ret = snprintf(n2[n2args-1], 200, "u:%d:%d:1",
 					hostid_mapped, geteuid());
 				if (ret < 0 || ret >= 200) {
 					ERROR("string too long");
-					_exit(1);
+					_exit(EXIT_FAILURE);
 				}
 			}
 			int hostgid_mapped = mapped_hostid(getegid(), conf, ID_TYPE_GID);
 			extraargs = hostgid_mapped >= 0 ? 1 : 3;
 			n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
 			if (!n2)
-				_exit(1);
+				_exit(EXIT_FAILURE);
 			if (hostgid_mapped < 0) {
 				hostgid_mapped = find_unmapped_nsid(conf, ID_TYPE_GID);
 				n2[n2args++] = "-m";
 				if (hostgid_mapped < 0) {
 					ERROR("Could not find free uid to map");
-					_exit(1);
+					_exit(EXIT_FAILURE);
 				}
 				n2[n2args++] = malloc(200);
 				if (!n2[n2args-1]) {
 					SYSERROR("out of memory");
-					_exit(1);
+					_exit(EXIT_FAILURE);
 				}
 				ret = snprintf(n2[n2args-1], 200, "g:%d:%d:1",
 					hostgid_mapped, getegid());
 				if (ret < 0 || ret >= 200) {
 					ERROR("string too long");
-					_exit(1);
+					_exit(EXIT_FAILURE);
 				}
 			}
 			n2[n2args++] = "--";
@@ -1468,7 +1468,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 			n2 = realloc(n2, n2args * sizeof(char *));
 			if (!n2) {
 				SYSERROR("out of memory");
-				_exit(1);
+				_exit(EXIT_FAILURE);
 			}
 			/* note n2[n2args-1] is NULL */
 			n2[n2args-5] = "--mapped-uid";
@@ -1484,7 +1484,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		/* execute */
 		execvp(tpath, newargv);
 		SYSERROR("Failed to execute template %s", tpath);
-		_exit(1);
+		_exit(EXIT_FAILURE);
 	}
 
 	if (wait_for_pid(pid) != 0) {

From bfde922f7f58958dbbd97560c326d07a67eed552 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:12:47 +0100
Subject: [PATCH 05/18] lxccontainer: non-functional changes

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 186 ++++++++++++++++++++++++++++---------------------
 1 file changed, 106 insertions(+), 80 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index a83e44bab..ac49f5e6f 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -1220,15 +1220,19 @@ static struct lxc_storage *do_storage_create(struct lxc_container *c,
 
 static char *lxcbasename(char *path)
 {
-	char *p = path + strlen(path) - 1;
+	char *p;
+
+	p = path + strlen(path) - 1;
 	while (*p != '/' && p > path)
 		p--;
+
 	return p;
 }
 
-static bool create_run_template(struct lxc_container *c, char *tpath, bool need_null_stdfds,
-				char *const argv[])
+static bool create_run_template(struct lxc_container *c, char *tpath,
+				bool need_null_stdfds, char *const argv[])
 {
+	int ret;
 	pid_t pid;
 
 	if (!tpath)
@@ -1241,42 +1245,53 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 	}
 
 	if (pid == 0) { /* child */
-		char *patharg, *namearg, *rootfsarg;
-		struct lxc_storage *bdev = NULL;
-		int i;
-		int ret, len, nargs = 0;
+		int i, len;
+		char *namearg, *patharg, *rootfsarg;
 		char **newargv;
+		int nargs = 0;
+		struct lxc_storage *bdev = NULL;
 		struct lxc_conf *conf = c->lxc_conf;
+		uid_t euid;
 
-		if (need_null_stdfds && null_stdfds() < 0) {
-			_exit(EXIT_FAILURE);
+		if (need_null_stdfds) {
+			ret = null_stdfds();
+			if (ret < 0)
+				_exit(EXIT_FAILURE);
 		}
 
 		bdev = storage_init(c->lxc_conf);
 		if (!bdev) {
-			ERROR("Error opening rootfs");
+			ERROR("Failed to initialize storage");
 			_exit(EXIT_FAILURE);
 		}
 
-		if (geteuid() == 0) {
-			if (unshare(CLONE_NEWNS) < 0) {
-				ERROR("error unsharing mounts");
+		euid = geteuid();
+		if (euid == 0) {
+			ret = unshare(CLONE_NEWNS);
+			if (ret < 0) {
+				ERROR("Failed to unshare CLONE_NEWNS");
 				_exit(EXIT_FAILURE);
 			}
-			if (detect_shared_rootfs()) {
-				if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
-					SYSERROR("Failed to make / rslave to run template");
+
+			ret = detect_shared_rootfs();
+			if (ret == 1) {
+				ret = mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL);
+				if (ret < 0) {
+					SYSERROR("Failed to make \"/\" rslave");
 					ERROR("Continuing...");
 				}
 			}
 		}
-		if (strcmp(bdev->type, "dir") && strcmp(bdev->type, "btrfs")) {
-			if (geteuid() != 0) {
-				ERROR("non-root users can only create btrfs and directory-backed containers");
+
+		if (strcmp(bdev->type, "dir") != 0 && strcmp(bdev->type, "btrfs") != 0) {
+			if (euid != 0) {
+				ERROR("Unprivileged users can only create "
+				      "btrfs and directory-backed containers");
 				_exit(EXIT_FAILURE);
 			}
 
-			if (!strcmp(bdev->type, "overlay") || !strcmp(bdev->type, "overlayfs")) {
+			if (strcmp(bdev->type, "overlay") == 0 ||
+			    strcmp(bdev->type, "overlayfs") == 0) {
 				/* If we create an overlay container we need to
 				 * rsync the contents into
 				 * <container-path>/<container-name>/rootfs.
@@ -1308,7 +1323,8 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 					return -1;
 				}
 			} else {
-				if (bdev->ops->mount(bdev) < 0) {
+				ret = bdev->ops->mount(bdev);
+				if (ret < 0) {
 					ERROR("Failed to mount rootfs");
 					_exit(EXIT_FAILURE);
 				}
@@ -1320,19 +1336,22 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 			bdev->dest = strdup(src);
 		}
 
-		/*
-		 * create our new array, pre-pend the template name and
-		 * base args
+		/* Create our new array, pre-pend the template name and base
+		 * args.
 		 */
 		if (argv)
-			for (nargs = 0; argv[nargs]; nargs++) ;
-		nargs += 4; /* template, path, rootfs and name args */
+			for (nargs = 0; argv[nargs]; nargs++) {
+				;
+			}
+		/* template, path, rootfs and name args */
+		nargs += 4;
 
 		newargv = malloc(nargs * sizeof(*newargv));
 		if (!newargv)
 			_exit(EXIT_FAILURE);
 		newargv[0] = lxcbasename(tpath);
 
+		/* --path */
 		len = strlen(c->config_path) + strlen(c->name) + strlen("--path=") + 2;
 		patharg = malloc(len);
 		if (!patharg)
@@ -1341,6 +1360,8 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		if (ret < 0 || ret >= len)
 			_exit(EXIT_FAILURE);
 		newargv[1] = patharg;
+
+		/* --name */
 		len = strlen("--name=") + strlen(c->name) + 1;
 		namearg = malloc(len);
 		if (!namearg)
@@ -1350,6 +1371,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 			_exit(EXIT_FAILURE);
 		newargv[2] = namearg;
 
+		/* --rootfs */
 		len = strlen("--rootfs=") + 1 + strlen(bdev->dest);
 		rootfsarg = malloc(len);
 		if (!rootfsarg)
@@ -1362,7 +1384,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		/* add passed-in args */
 		if (argv)
 			for (i = 4; i < nargs; i++)
-				newargv[i] = argv[i-4];
+				newargv[i] = argv[i - 4];
 
 		/* add trailing NULL */
 		nargs++;
@@ -1371,25 +1393,23 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 			_exit(EXIT_FAILURE);
 		newargv[nargs - 1] = NULL;
 
-		/*
-		 * If we're running the template in a mapped userns, then
-		 * we prepend the template command with:
-		 * lxc-usernsexec <-m map1> ... <-m mapn> --
-		 * and we append "--mapped-uid x", where x is the mapped uid
-		 * for our geteuid()
+		/* If we're running the template in a mapped userns, then we
+		 * prepend the template command with: lxc-usernsexec <-m map1>
+		 * ... <-m mapn> -- and we append "--mapped-uid x", where x is
+		 * the mapped uid for our geteuid()
 		 */
 		if (!lxc_list_empty(&conf->id_map)) {
-			int n2args = 1;
-			char txtuid[20];
-			char txtgid[20];
-			char **n2 = malloc(n2args * sizeof(*n2));
+			int extraargs, hostuid_mapped, hostgid_mapped;
+			char **n2;
+			char txtuid[20], txtgid[20];
 			struct lxc_list *it;
 			struct id_map *map;
+			int n2args = 1;
 
-			if (!n2) {
-				SYSERROR("out of memory");
+			n2 = malloc(n2args * sizeof(*n2));
+			if (!n2)
 				_exit(EXIT_FAILURE);
-			}
+
 			newargv[0] = tpath;
 			tpath = "lxc-usernsexec";
 			n2[0] = "lxc-usernsexec";
@@ -1399,96 +1419,102 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 				n2 = realloc(n2, n2args * sizeof(char *));
 				if (!n2)
 					_exit(EXIT_FAILURE);
-				n2[n2args-2] = "-m";
-				n2[n2args-1] = malloc(200);
-				if (!n2[n2args-1])
+
+				n2[n2args - 2] = "-m";
+				n2[n2args - 1] = malloc(200);
+				if (!n2[n2args - 1])
 					_exit(EXIT_FAILURE);
-				ret = snprintf(n2[n2args-1], 200, "%c:%lu:%lu:%lu",
-					map->idtype == ID_TYPE_UID ? 'u' : 'g',
-					map->nsid, map->hostid, map->range);
+
+				ret = snprintf(n2[n2args - 1], 200, "%c:%lu:%lu:%lu",
+					       map->idtype == ID_TYPE_UID ? 'u' : 'g',
+					       map->nsid, map->hostid, map->range);
 				if (ret < 0 || ret >= 200)
 					_exit(EXIT_FAILURE);
 			}
-			int hostid_mapped = mapped_hostid(geteuid(), conf, ID_TYPE_UID);
-			int extraargs = hostid_mapped >= 0 ? 1 : 3;
+
+			hostuid_mapped = mapped_hostid(geteuid(), conf, ID_TYPE_UID);
+			extraargs = hostuid_mapped >= 0 ? 1 : 3;
 			n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
 			if (!n2)
 				_exit(EXIT_FAILURE);
-			if (hostid_mapped < 0) {
-				hostid_mapped = find_unmapped_nsid(conf, ID_TYPE_UID);
+
+			if (hostuid_mapped < 0) {
+				hostuid_mapped = find_unmapped_nsid(conf, ID_TYPE_UID);
 				n2[n2args++] = "-m";
-				if (hostid_mapped < 0) {
-					ERROR("Could not find free uid to map");
+				if (hostuid_mapped < 0) {
+					ERROR("Failed to find free uid to map");
 					_exit(EXIT_FAILURE);
 				}
+
 				n2[n2args++] = malloc(200);
-				if (!n2[n2args-1]) {
+				if (!n2[n2args - 1]) {
 					SYSERROR("out of memory");
 					_exit(EXIT_FAILURE);
 				}
-				ret = snprintf(n2[n2args-1], 200, "u:%d:%d:1",
-					hostid_mapped, geteuid());
-				if (ret < 0 || ret >= 200) {
-					ERROR("string too long");
+				ret = snprintf(n2[n2args - 1], 200, "u:%d:%d:1",
+					       hostuid_mapped, geteuid());
+				if (ret < 0 || ret >= 200)
 					_exit(EXIT_FAILURE);
-				}
 			}
-			int hostgid_mapped = mapped_hostid(getegid(), conf, ID_TYPE_GID);
+
+			hostgid_mapped = mapped_hostid(getegid(), conf, ID_TYPE_GID);
 			extraargs = hostgid_mapped >= 0 ? 1 : 3;
 			n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
 			if (!n2)
 				_exit(EXIT_FAILURE);
+
 			if (hostgid_mapped < 0) {
 				hostgid_mapped = find_unmapped_nsid(conf, ID_TYPE_GID);
 				n2[n2args++] = "-m";
 				if (hostgid_mapped < 0) {
-					ERROR("Could not find free uid to map");
+					ERROR("Failed to find free gid to map");
 					_exit(EXIT_FAILURE);
 				}
+
 				n2[n2args++] = malloc(200);
-				if (!n2[n2args-1]) {
+				if (!n2[n2args - 1]) {
 					SYSERROR("out of memory");
 					_exit(EXIT_FAILURE);
 				}
-				ret = snprintf(n2[n2args-1], 200, "g:%d:%d:1",
-					hostgid_mapped, getegid());
-				if (ret < 0 || ret >= 200) {
-					ERROR("string too long");
+
+				ret = snprintf(n2[n2args - 1], 200, "g:%d:%d:1",
+					       hostgid_mapped, getegid());
+				if (ret < 0 || ret >= 200)
 					_exit(EXIT_FAILURE);
-				}
 			}
 			n2[n2args++] = "--";
 			for (i = 0; i < nargs; i++)
 				n2[i + n2args] = newargv[i];
 			n2args += nargs;
-			/* Finally add "--mapped-uid $uid" to tell template
-			 * what to chown cached images to.
+
+			/* Finally add "--mapped-uid $uid" to tell template what
+			 * to chown cached images to.
 			 */
 			n2args += 4;
 			n2 = realloc(n2, n2args * sizeof(char *));
-			if (!n2) {
-				SYSERROR("out of memory");
+			if (!n2)
 				_exit(EXIT_FAILURE);
-			}
+
 			/* note n2[n2args-1] is NULL */
-			n2[n2args-5] = "--mapped-uid";
-			snprintf(txtuid, 20, "%d", hostid_mapped);
-			n2[n2args-4] = txtuid;
-			n2[n2args-3] = "--mapped-gid";
+			n2[n2args - 5] = "--mapped-uid";
+			snprintf(txtuid, 20, "%d", hostuid_mapped);
+			n2[n2args - 4] = txtuid;
+			n2[n2args - 3] = "--mapped-gid";
 			snprintf(txtgid, 20, "%d", hostgid_mapped);
-			n2[n2args-2] = txtgid;
-			n2[n2args-1] = NULL;
+			n2[n2args - 2] = txtgid;
+			n2[n2args - 1] = NULL;
 			free(newargv);
 			newargv = n2;
 		}
-		/* execute */
+
 		execvp(tpath, newargv);
 		SYSERROR("Failed to execute template %s", tpath);
 		_exit(EXIT_FAILURE);
 	}
 
-	if (wait_for_pid(pid) != 0) {
-		ERROR("container creation template for %s failed", c->name);
+	ret = wait_for_pid(pid);
+	if (ret != 0) {
+		ERROR("Failed to create container from template");
 		return false;
 	}
 

From bc8ffd69e082ad4e56cbeace6b13faddd512d087 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:18:14 +0100
Subject: [PATCH 06/18] lxccontainer: thread-safety: do_lxcapi_create()

s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index ac49f5e6f..6768333a0 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -1645,8 +1645,8 @@ static void lxcapi_clear_config(struct lxc_container *c)
  * arguments, you can just pass NULL.
  */
 static bool do_lxcapi_create(struct lxc_container *c, const char *t,
-		const char *bdevtype, struct bdev_specs *specs, int flags,
-		char *const argv[])
+			     const char *bdevtype, struct bdev_specs *specs,
+			     int flags, char *const argv[])
 {
 	int partial_fd;
 	pid_t pid;
@@ -1740,7 +1740,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
 		if (!bdev) {
 			ERROR("Failed to create %s storage for %s",
 			      bdevtype ? bdevtype : "(none)", c->name);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* Save config file again to store the new rootfs location. */
@@ -1751,9 +1751,9 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
 			 */
 			bdev->ops->umount(bdev);
 			bdev->ops->destroy(bdev);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
-		exit(EXIT_SUCCESS);
+		_exit(EXIT_SUCCESS);
 	}
 	if (wait_for_pid(pid) != 0)
 		goto out_unlock;

From eb0cb9caf4b0c1f408308f99b225cba60bdd5ce7 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:19:34 +0100
Subject: [PATCH 07/18] lxccontainer: do_lxcapi_get_interfaces()

thread-safety: s/exit()/_exit/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 6768333a0..c42548662 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -2192,7 +2192,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
 
 		/* close the write-end of the pipe, thus sending EOF to the reader */
 		close(pipefd[1]);
-		exit(ret);
+		_exit(ret);
 	}
 
 	/* close the write-end of the pipe */

From e6c6cf776cff88d04766ba26ca7e77e00cbb6a2d Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:20:34 +0100
Subject: [PATCH 08/18] lxccontainer: do_lxcapi_get_ips()

thread-safety: s/exit/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index c42548662..5366c21fe 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -2317,7 +2317,7 @@ static char** do_lxcapi_get_ips(struct lxc_container *c, const char* interface,
 
 		/* close the write-end of the pipe, thus sending EOF to the reader */
 		close(pipefd[1]);
-		exit(ret);
+		_exit(ret);
 	}
 
 	/* close the write-end of the pipe */

From af835b3de8810434326da9b98b50688ee15e3e88 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:21:14 +0100
Subject: [PATCH 09/18] lxccontainer: do_lxcapi_clone()

thread-safety: s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 5366c21fe..1d7bc7c43 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -3689,10 +3689,10 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
 	else
 		ret = clone_update_rootfs(&data);
 	if (ret < 0)
-		exit(1);
+		_exit(EXIT_FAILURE);
 
 	container_mem_unlock(c);
-	exit(0);
+	_exit(EXIT_SUCCESS);
 
 out:
 	container_mem_unlock(c);

From 89f73ff22e3e9252fbc3b34eff6c660930dca8aa Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:21:51 +0100
Subject: [PATCH 10/18] lxccontainer: do_add_remove_node()

thread-safety: s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 1d7bc7c43..3072b4c2d 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -4262,11 +4262,11 @@ static bool do_add_remove_node(pid_t init_pid, const char *path, bool add,
 
 	ret = chroot(chrootpath);
 	if (ret < 0)
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 
 	ret = chdir("/");
 	if (ret < 0)
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 
 	/* remove path if it exists */
 	ret = faccessat(AT_FDCWD, path, F_OK, AT_SYMLINK_NOFOLLOW);
@@ -4274,24 +4274,24 @@ static bool do_add_remove_node(pid_t init_pid, const char *path, bool add,
 		ret = unlink(path);
 		if (ret < 0) {
 			ERROR("%s - Failed to remove \"%s\"", strerror(errno), path);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 	}
 
 	if (!add)
-		exit(EXIT_SUCCESS);
+		_exit(EXIT_SUCCESS);
 
 	/* create any missing directories */
 	tmp = strdup(path);
 	if (!tmp)
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 
 	directory_path = dirname(tmp);
 	ret = mkdir_p(directory_path, 0755);
 	if (ret < 0 && errno != EEXIST) {
 		ERROR("%s - Failed to create path \"%s\"", strerror(errno), directory_path);
 		free(tmp);
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	/* create the device node */
@@ -4299,10 +4299,10 @@ static bool do_add_remove_node(pid_t init_pid, const char *path, bool add,
 	free(tmp);
 	if (ret < 0) {
 		ERROR("%s - Failed to create device node at \"%s\"", strerror(errno), path);
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
-	exit(EXIT_SUCCESS);
+	_exit(EXIT_SUCCESS);
 }
 
 static bool add_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path, bool add)

From e99678c184a8f5ef660b1b0effd8783da4a563fb Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:22:24 +0100
Subject: [PATCH 11/18] lxccontainer: do_lxcapi_detach_interface()

thread-safety: s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 3072b4c2d..4b056b6b0 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -4452,13 +4452,13 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
 		init_pid = do_lxcapi_init_pid(c);
 		if (!switch_to_ns(init_pid, "net")) {
 			ERROR("Failed to enter network namespace");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		ret = lxc_netdev_isup(ifname);
 		if (ret < 0) {
 			ERROR("Failed to determine whether network device \"%s\" is up", ifname);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* netdev of ifname is up. */
@@ -4466,7 +4466,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
 			ret = lxc_netdev_down(ifname);
 			if (ret) {
 				ERROR("Failed to set network device \"%s\" down", ifname);
-				exit(EXIT_FAILURE);
+				_exit(EXIT_FAILURE);
 			}
 		}
 
@@ -4477,10 +4477,10 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
 				ERROR("Network device \"%s\" not found", ifname);
 			else
 				ERROR("Failed to remove network device \"%s\"", ifname);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
-		exit(EXIT_SUCCESS);
+		_exit(EXIT_SUCCESS);
 	}
 
 	ret = wait_for_pid(pid);

From 4ee1151a7dec8c59912cc5a484b2c6711a28c3fb Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:28:10 +0100
Subject: [PATCH 12/18] lxclock: {un}lock_mutex()

thread-safety: s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxclock.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c
index 87496f681..fa17310ac 100644
--- a/src/lxc/lxclock.c
+++ b/src/lxc/lxclock.c
@@ -72,10 +72,11 @@ static void lock_mutex(pthread_mutex_t *l)
 {
 	int ret;
 
-	if ((ret = pthread_mutex_lock(l)) != 0) {
-		fprintf(stderr, "pthread_mutex_lock returned:%d %s\n", ret, strerror(ret));
+	ret = pthread_mutex_lock(l);
+	if (ret != 0) {
+		fprintf(stderr, "%s - Failed acquire mutex", strerror(ret));
 		dump_stacktrace();
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 }
 
@@ -83,11 +84,11 @@ static void unlock_mutex(pthread_mutex_t *l)
 {
 	int ret;
 
-	if ((ret = pthread_mutex_unlock(l)) != 0) {
-		fprintf(stderr, "%s: pthread_mutex_unlock returned:%d %s\n",
-				__FILE__, ret, strerror(ret));
+	ret = pthread_mutex_unlock(l);
+	if (ret != 0) {
+		fprintf(stderr, "%s - Failed to release mutex", strerror(ret));
 		dump_stacktrace();
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 }
 

From 5a1d563bb284a81d510d9497369c676816ae31b7 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:30:55 +0100
Subject: [PATCH 13/18] utils: lxc_popen()

thread-safety: s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/utils.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index c824e9b99..98b4655cf 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -478,7 +478,7 @@ struct lxc_popen_FILE *lxc_popen(const char *command)
 			ret = fcntl(pipe_fds[1], F_SETFD, 0);
 		if (ret < 0) {
 			close(pipe_fds[1]);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* duplicate stderr */
@@ -488,19 +488,19 @@ struct lxc_popen_FILE *lxc_popen(const char *command)
 			ret = fcntl(pipe_fds[1], F_SETFD, 0);
 		close(pipe_fds[1]);
 		if (ret < 0)
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 
 		/* unblock all signals */
 		ret = sigfillset(&mask);
 		if (ret < 0)
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 
 		ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
 		if (ret < 0)
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 
 		execl("/bin/sh", "sh", "-c", command, (char *)NULL);
-		exit(127);
+		_exit(127);
 	}
 
 	close(pipe_fds[1]);

From eb6f4af1da19fb5c03b6aec285ae5eca5aa963d0 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:31:12 +0100
Subject: [PATCH 14/18] utils: run_command()

thread-safety: s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/utils.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 98b4655cf..f8d6a3fe1 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -2242,13 +2242,13 @@ int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args)
 
 		if (ret < 0) {
 			SYSERROR("failed to duplicate std{err,out} file descriptor");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* Does not return. */
 		child_fn(args);
 		ERROR("failed to exec command");
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	/* close the write-end of the pipe */

From 049e2538eee4b9a8ed5791ab8fe2475b83d05b92 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:34:52 +0100
Subject: [PATCH 15/18] network: lxc_netdev_rename_by_name_in_netns()

thread-safety: s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/network.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lxc/network.c b/src/lxc/network.c
index 5780e489a..9fe7ef5ce 100644
--- a/src/lxc/network.c
+++ b/src/lxc/network.c
@@ -635,7 +635,7 @@ static int lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old,
 	if (!switch_to_ns(pid, "net"))
 		return -1;
 
-	exit(lxc_netdev_rename_by_name(old, new));
+	_exit(lxc_netdev_rename_by_name(old, new));
 }
 
 static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,

From c9f04e2d902e580235a9d1ed7680adb58df4fc82 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:35:25 +0100
Subject: [PATCH 16/18] network: lxc_netdev_move_wlan()

thread-safety: s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/network.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lxc/network.c b/src/lxc/network.c
index 9fe7ef5ce..145131e30 100644
--- a/src/lxc/network.c
+++ b/src/lxc/network.c
@@ -663,7 +663,7 @@ static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
 		sprintf(pidstr, "%d", pid);
 		execlp("iw", "iw", "phy", physname, "set", "netns", pidstr,
 		       (char *)NULL);
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	if (wait_for_pid(fpid))

From 2837eaf383f6ed51a5917a9c70f4609db82d941c Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:35:57 +0100
Subject: [PATCH 17/18] network: lxc_create_network_unpriv_exec()

thread-safety: s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/network.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/lxc/network.c b/src/lxc/network.c
index 145131e30..3f134c299 100644
--- a/src/lxc/network.c
+++ b/src/lxc/network.c
@@ -2126,7 +2126,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
 		close(pipefd[1]);
 		if (ret < 0) {
 			SYSERROR("Failed to duplicate std{err,out} file descriptor");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		if (netdev->link[0] != '\0')
@@ -2136,7 +2136,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
 
 		ret = snprintf(pidstr, LXC_NUMSTRLEN64, "%d", pid);
 		if (ret < 0 || ret >= LXC_NUMSTRLEN64)
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		pidstr[LXC_NUMSTRLEN64 - 1] = '\0';
 
 		INFO("Execing lxc-user-nic create %s %s %s veth %s %s", lxcpath,
@@ -2151,7 +2151,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
 			       lxcpath, lxcname, pidstr, "veth", netdev_link,
 			       (char *)NULL);
 		SYSERROR("Failed to execute lxc-user-nic");
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	/* close the write-end of the pipe */

From 9e527b5e9a2aaaa82a7be8045d773af102040a28 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 23 Feb 2018 14:36:30 +0100
Subject: [PATCH 18/18] network: lxc_delete_network_unpriv_exec()

thread-safety: s/exit()/_exit()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/network.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/lxc/network.c b/src/lxc/network.c
index 3f134c299..e31066cb9 100644
--- a/src/lxc/network.c
+++ b/src/lxc/network.c
@@ -2269,7 +2269,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
 		close(pipefd[1]);
 		if (ret < 0) {
 			SYSERROR("Failed to duplicate std{err,out} file descriptor");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		if (netdev->priv.veth_attr.pair[0] != '\0')
@@ -2278,13 +2278,13 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
 			hostveth = netdev->priv.veth_attr.veth1;
 		if (hostveth[0] == '\0') {
 			SYSERROR("Host side veth device name is missing");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		if (netdev->link[0] == '\0') {
 			SYSERROR("Network link for network device \"%s\" is "
 				 "missing", netdev->priv.veth_attr.veth1);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		INFO("Execing lxc-user-nic delete %s %s %s veth %s %s", lxcpath,
@@ -2293,7 +2293,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
 		       lxcname, netns_path, "veth", netdev->link, hostveth,
 		       (char *)NULL);
 		SYSERROR("Failed to exec lxc-user-nic.");
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	close(pipefd[1]);


More information about the lxc-devel mailing list