[lxc-devel] [lxd/master] tree-wide: C code hardening

brauner on Github lxc-bot at linuxcontainers.org
Thu Feb 21 15:49:52 UTC 2019


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/20190221/efdfaeb4/attachment-0001.bin>
-------------- next part --------------
From a7d392a9323c59f6294dbb032b6d5e24f8df2f4d Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 15:00:22 +0100
Subject: [PATCH 01/20] lxd: copy C smarts from LXC into lxd/include/

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/include/compiler.h     |  64 +++++++++
 lxd/include/macro.h        | 258 +++++++++++++++++++++++++++++++++++++
 lxd/include/memory_utils.h |  68 ++++++++++
 3 files changed, 390 insertions(+)
 create mode 100644 lxd/include/compiler.h
 create mode 100644 lxd/include/macro.h
 create mode 100644 lxd/include/memory_utils.h

diff --git a/lxd/include/compiler.h b/lxd/include/compiler.h
new file mode 100644
index 0000000000..65457cb31b
--- /dev/null
+++ b/lxd/include/compiler.h
@@ -0,0 +1,64 @@
+/* liblxcapi
+ *
+ * Copyright © 2018 Christian Brauner <christian.brauner at ubuntu.com>.
+ * Copyright © 2018 Canonical Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __LXC_COMPILER_H
+#define __LXC_COMPILER_H
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+#include "config.h"
+
+#ifndef thread_local
+#if __STDC_VERSION__ >= 201112L &&    \
+    !(defined(__STDC_NO_THREADS__) || \
+      (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
+#define thread_local _Thread_local
+#else
+#define thread_local __thread
+#endif
+#endif
+
+#ifndef __fallthrough
+#define __fallthrough /* fall through */
+#endif
+
+#ifndef __noreturn
+#	if __STDC_VERSION__ >= 201112L
+#		if !IS_BIONIC
+#			define __noreturn _Noreturn
+#		else
+#			define __noreturn __attribute__((__noreturn__))
+#		endif
+#	elif IS_BIONIC
+#		define __noreturn __attribute__((__noreturn__))
+#	else
+#		define __noreturn __attribute__((noreturn))
+#	endif
+#endif
+
+#ifndef __hot
+#	define __hot __attribute__((hot))
+#endif
+
+#define __cgfsng_ops
+
+#endif /* __LXC_COMPILER_H */
diff --git a/lxd/include/macro.h b/lxd/include/macro.h
new file mode 100644
index 0000000000..3384184e9c
--- /dev/null
+++ b/lxd/include/macro.h
@@ -0,0 +1,258 @@
+/* liblxcapi
+ *
+ * Copyright © 2018 Christian Brauner <christian.brauner at ubuntu.com>.
+ * Copyright © 2018 Canonical Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __LXC_MACRO_H
+#define __LXC_MACRO_H
+
+#include <asm/types.h>
+#include <limits.h>
+#include <linux/if_link.h>
+#include <linux/loop.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
+/* Calculate the number of chars needed to represent a given integer as a C
+ * string. Include room for '-' to indicate negative numbers and the \0 byte.
+ * This is based on systemd.
+ */
+#define INTTYPE_TO_STRLEN(type)                   \
+	(2 + (sizeof(type) <= 1                   \
+		  ? 3                             \
+		  : sizeof(type) <= 2             \
+			? 5                       \
+			: sizeof(type) <= 4       \
+			      ? 10                \
+			      : sizeof(type) <= 8 \
+				    ? 20          \
+				    : sizeof(int[-2 * (sizeof(type) > 8)])))
+
+/* Useful macros */
+#define LXC_LINELEN 4096
+#define LXC_IDMAPLEN 4096
+#define LXC_MAX_BUFFER 4096
+
+/* /proc/       =    6
+ *                +
+ * <pid-as-str> =   INTTYPE_TO_STRLEN(pid_t)
+ *                +
+ * /fd/         =    4
+ *                +
+ * <fd-as-str>  =   INTTYPE_TO_STRLEN(int)
+ *                +
+ * \0           =    1
+ */
+#define LXC_PROC_PID_FD_LEN \
+	(6 + INTTYPE_TO_STRLEN(pid_t) + 4 + INTTYPE_TO_STRLEN(int) + 1)
+
+/* /proc/        = 6
+ *               +
+ * <pid-as-str>  = INTTYPE_TO_STRLEN(pid_t)
+ *               +
+ * /status       = 7
+ *               +
+ * \0            = 1
+ */
+#define LXC_PROC_STATUS_LEN (6 + INTTYPE_TO_STRLEN(pid_t) + 7 + 1)
+
+/* loop devices */
+#ifndef LO_FLAGS_AUTOCLEAR
+#define LO_FLAGS_AUTOCLEAR 4
+#endif
+
+#ifndef LOOP_CTL_GET_FREE
+#define LOOP_CTL_GET_FREE 0x4C82
+#endif
+
+/* memfd_create() */
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC 0x0001U
+#endif
+
+#ifndef MFD_ALLOW_SEALING
+#define MFD_ALLOW_SEALING 0x0002U
+#endif
+
+/**
+ * BUILD_BUG_ON - break compile if a condition is true.
+ * @condition: the condition which the compiler should know is false.
+ *
+ * If you have some code which relies on certain constants being equal, or
+ * other compile-time-evaluated condition, you should use BUILD_BUG_ON to
+ * detect if someone changes it.
+ *
+ * The implementation uses gcc's reluctance to create a negative array, but
+ * gcc (as of 4.4) only emits that error for obvious cases (eg. not arguments
+ * to inline functions).  So as a fallback we use the optimizer; if it can't
+ * prove the condition is false, it will cause a link error on the undefined
+ * "__build_bug_on_failed".  This error message can be harder to track down
+ * though, hence the two different methods.
+ */
+#ifndef __OPTIMIZE__
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
+#else
+extern int __build_bug_on_failed;
+#define BUILD_BUG_ON(condition)                              \
+	do {                                                 \
+		((void)sizeof(char[1 - 2 * !!(condition)])); \
+		if (condition)                               \
+			__build_bug_on_failed = 1;           \
+	} while (0)
+#endif
+
+#define lxc_iterate_parts(__iterator, __splitme, __separators)                  \
+	for (char *__p = NULL, *__it = strtok_r(__splitme, __separators, &__p); \
+	     (__iterator = __it);                                               \
+	     __iterator = __it = strtok_r(NULL, __separators, &__p))
+
+#define prctl_arg(x) ((unsigned long)x)
+
+/* networking */
+#ifndef NETLINK_DUMP_STRICT_CHK
+#define NETLINK_DUMP_STRICT_CHK 12
+#endif
+
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+
+#ifndef IFLA_LINKMODE
+#define IFLA_LINKMODE 17
+#endif
+
+#ifndef IFLA_LINKINFO
+#define IFLA_LINKINFO 18
+#endif
+
+#ifndef IFLA_NET_NS_PID
+#define IFLA_NET_NS_PID 19
+#endif
+
+#ifndef IFLA_INFO_KIND
+#define IFLA_INFO_KIND 1
+#endif
+
+#ifndef IFLA_VLAN_ID
+#define IFLA_VLAN_ID 1
+#endif
+
+#ifndef IFLA_INFO_DATA
+#define IFLA_INFO_DATA 2
+#endif
+
+#ifndef VETH_INFO_PEER
+#define VETH_INFO_PEER 1
+#endif
+
+#ifndef IFLA_MACVLAN_MODE
+#define IFLA_MACVLAN_MODE 1
+#endif
+
+#ifndef IFLA_NEW_NETNSID
+#define IFLA_NEW_NETNSID 45
+#endif
+
+#ifdef IFLA_IF_NETNSID
+#ifndef IFLA_TARGET_NETNSID
+#define IFLA_TARGET_NETNSID = IFLA_IF_NETNSID
+#endif
+#else
+#define IFLA_IF_NETNSID 46
+#define IFLA_TARGET_NETNSID 46
+#endif
+
+#ifndef IFA_TARGET_NETNSID
+#define IFA_TARGET_NETNSID 10
+#endif
+
+#ifndef IFLA_STATS
+#define IFLA_STATS 7
+#endif
+
+#ifndef IFLA_STATS64
+#define IFLA_STATS64 23
+#endif
+
+#ifndef RTM_NEWNSID
+#define RTM_NEWNSID 88
+#endif
+
+#ifndef RTM_GETNSID
+#define RTM_GETNSID 90
+#endif
+
+#ifndef NLMSG_ERROR
+#define NLMSG_ERROR 0x2
+#endif
+
+/* Attributes of RTM_NEWNSID/RTM_GETNSID messages */
+enum {
+	__LXC_NETNSA_NONE,
+#define __LXC_NETNSA_NSID_NOT_ASSIGNED -1
+	__LXC_NETNSA_NSID,
+	__LXC_NETNSA_PID,
+	__LXC_NETNSA_FD,
+	__LXC_NETNSA_MAX,
+};
+
+/* Length of abstract unix domain socket socket address. */
+#define LXC_AUDS_ADDR_LEN sizeof(((struct sockaddr_un *)0)->sun_path)
+
+/* pointer conversion macros */
+#define PTR_TO_INT(p) ((int)((intptr_t)(p)))
+#define INT_TO_PTR(u) ((void *)((intptr_t)(u)))
+
+#define PTR_TO_INTMAX(p) ((intmax_t)((intptr_t)(p)))
+#define INTMAX_TO_PTR(u) ((void *)((intptr_t)(u)))
+
+#define LXC_INVALID_UID ((uid_t)-1)
+#define LXC_INVALID_GID ((gid_t)-1)
+
+#define STRLITERALLEN(x) (sizeof(""x"") - 1)
+#define STRARRAYLEN(x) (sizeof(x) - 1)
+
+/* Maximum number of bytes sendfile() is able to send in one go. */
+#define LXC_SENDFILE_MAX 0x7ffff000
+
+#define move_ptr(ptr)                                 \
+	({                                            \
+		typeof(ptr) __internal_ptr__ = (ptr); \
+		(ptr) = NULL;                         \
+		__internal_ptr__;                     \
+	})
+
+#define move_fd(fd)                         \
+	({                                  \
+		int __internal_fd__ = (fd); \
+		(fd) = -EBADF;              \
+		__internal_fd__;            \
+	})
+
+#endif /* __LXC_MACRO_H */
diff --git a/lxd/include/memory_utils.h b/lxd/include/memory_utils.h
new file mode 100644
index 0000000000..c1dafb441a
--- /dev/null
+++ b/lxd/include/memory_utils.h
@@ -0,0 +1,68 @@
+/* liblxcapi
+ *
+ * Copyright © 2019 Christian Brauner <christian.brauner at ubuntu.com>.
+ * Copyright © 2019 Canonical Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __LXC_MEMORY_UTILS_H
+#define __LXC_MEMORY_UTILS_H
+
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "macro.h"
+
+static inline void __auto_free__(void *p)
+{
+	free(*(void **)p);
+}
+
+static inline void __auto_fclose__(FILE **f)
+{
+	if (*f)
+		fclose(*f);
+}
+
+static inline void __auto_closedir__(DIR **d)
+{
+	if (*d)
+		closedir(*d);
+}
+
+#define close_prot_errno_disarm(fd) \
+	if (fd >= 0) {              \
+		int _e_ = errno;    \
+		close(fd);          \
+		errno = _e_;        \
+		fd = -EBADF;        \
+	}
+
+static inline void __auto_close__(int *fd)
+{
+	close_prot_errno_disarm(*fd);
+}
+
+#define __do_close_prot_errno __attribute__((__cleanup__(__auto_close__)))
+#define __do_free __attribute__((__cleanup__(__auto_free__)))
+#define __do_fclose __attribute__((__cleanup__(__auto_fclose__)))
+#define __do_closedir __attribute__((__cleanup__(__auto_closedir__)))
+
+#endif /* __LXC_MEMORY_UTILS_H */

From f0bf4007800d61bb072d51c4b5697aa5cff90398 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 14:58:32 +0100
Subject: [PATCH 02/20] tree-wide: enable compiler-based hardening for C

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd-p2c/setns.go               |  2 +-
 lxd/devlxd_gccgo.go            |  2 +-
 lxd/main_checkfeature.go       |  2 +-
 lxd/main_forkfile.go           | 13 +++++++++----
 lxd/main_forkmount.go          | 17 +++++++++++------
 lxd/main_forknet.go            |  2 +-
 lxd/main_forkproxy.go          |  2 +-
 lxd/main_forkuevent.go         |  2 +-
 lxd/main_nsexec.go             |  2 +-
 lxd/storage_cgo.go             |  2 +-
 shared/idmap/shift_linux.go    |  2 +-
 shared/network_linux.go        |  2 +-
 shared/termios/termios_unix.go |  2 +-
 shared/util_linux_cgo.go       |  4 ++--
 14 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/lxd-p2c/setns.go b/lxd-p2c/setns.go
index 7d82162574..4603cce964 100644
--- a/lxd-p2c/setns.go
+++ b/lxd-p2c/setns.go
@@ -30,5 +30,5 @@ __attribute__((constructor)) void init(void) {
 	// We're done, jump back to Go
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
diff --git a/lxd/devlxd_gccgo.go b/lxd/devlxd_gccgo.go
index abf22d521f..31f10eb16f 100644
--- a/lxd/devlxd_gccgo.go
+++ b/lxd/devlxd_gccgo.go
@@ -33,7 +33,7 @@ void getucred(int sock, uint *uid, uint *gid, int *pid) {
 	return;
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I./include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
 
 func getUcred(fd int) (uint32, uint32, int32, error) {
diff --git a/lxd/main_checkfeature.go b/lxd/main_checkfeature.go
index 565902517a..d5a5b6c992 100644
--- a/lxd/main_checkfeature.go
+++ b/lxd/main_checkfeature.go
@@ -149,7 +149,7 @@ static bool is_empty_string(char *s)
 	return (errbuf[0] == '\0');
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I./include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
 
 func CanUseNetnsGetifaddrs() bool {
diff --git a/lxd/main_forkfile.go b/lxd/main_forkfile.go
index 38030e2ae0..af78497287 100644
--- a/lxd/main_forkfile.go
+++ b/lxd/main_forkfile.go
@@ -19,6 +19,8 @@ import (
 #include <unistd.h>
 #include <limits.h>
 
+#include "include/compiler.h"
+
 extern char* advance_arg(bool required);
 extern void error(char *msg);
 extern void attach_userns(int pid);
@@ -272,7 +274,8 @@ close_host:
 	return ret;
 }
 
-void forkdofile(bool is_put, char *rootfs, pid_t pid) {
+__noreturn void forkdofile(bool is_put, char *rootfs, pid_t pid)
+{
 	char *cur = NULL;
 
 	uid_t uid = 0;
@@ -325,7 +328,8 @@ void forkdofile(bool is_put, char *rootfs, pid_t pid) {
 	_exit(manip_file_in_ns(rootfs, pid, source, target, is_put, type, uid, gid, mode, defaultUid, defaultGid, defaultMode, append));
 }
 
-void forkcheckfile(char *rootfs, pid_t pid) {
+__noreturn void forkcheckfile(char *rootfs, pid_t pid)
+{
 	char *path = NULL;
 
 	path = advance_arg(true);
@@ -357,7 +361,8 @@ void forkcheckfile(char *rootfs, pid_t pid) {
 	_exit(0);
 }
 
-void forkremovefile(char *rootfs, pid_t pid) {
+__noreturn void forkremovefile(char *rootfs, pid_t pid)
+{
 	char *path = NULL;
 	struct stat sb;
 
@@ -440,7 +445,7 @@ void forkfile() {
 	}
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I./include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
 
 type cmdForkfile struct {
diff --git a/lxd/main_forkmount.go b/lxd/main_forkmount.go
index c5a3db37c5..91494d427f 100644
--- a/lxd/main_forkmount.go
+++ b/lxd/main_forkmount.go
@@ -24,6 +24,8 @@ import (
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "include/compiler.h"
+
 #define VERSION_AT_LEAST(major, minor, micro)							\
 	((LXC_DEVEL == 1) || (!(major > LXC_VERSION_MAJOR ||					\
 	major == LXC_VERSION_MAJOR && minor > LXC_VERSION_MINOR ||				\
@@ -127,7 +129,8 @@ void create(char *src, char *dest) {
 	}
 }
 
-void do_lxd_forkmount(pid_t pid) {
+__noreturn void do_lxd_forkmount(pid_t pid)
+{
 	char *src, *dest, *opts;
 
 	attach_userns(pid);
@@ -163,7 +166,8 @@ void do_lxd_forkmount(pid_t pid) {
 	_exit(0);
 }
 
-void do_lxd_forkumount(pid_t pid) {
+__noreturn void do_lxd_forkumount(pid_t pid)
+{
 	int ret;
 	char *path = NULL;
 
@@ -215,7 +219,7 @@ static int lxc_safe_ulong(const char *numstr, unsigned long *converted)
 }
 #endif
 
-void do_lxc_forkmount()
+__noreturn void do_lxc_forkmount()
 {
 #if VERSION_AT_LEAST(3, 1, 0)
 	int ret;
@@ -254,11 +258,11 @@ void do_lxc_forkmount()
 	if (ret < 0)
 		_exit(1);
 
-	_exit(0);
 #endif
+	_exit(0);
 }
 
-void do_lxc_forkumount()
+__noreturn void do_lxc_forkumount()
 {
 #if VERSION_AT_LEAST(3, 1, 0)
 	int ret;
@@ -287,6 +291,7 @@ void do_lxc_forkumount()
 	if (ret < 0)
 		_exit(1);
 #endif
+	_exit(0);
 }
 
 void forkmount() {
@@ -334,7 +339,7 @@ void forkmount() {
 	}
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I./include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 // #cgo LDFLAGS: -llxc
 // #cgo pkg-config: lxc
 import "C"
diff --git a/lxd/main_forknet.go b/lxd/main_forknet.go
index e7ef06e664..0753c03b62 100644
--- a/lxd/main_forknet.go
+++ b/lxd/main_forknet.go
@@ -62,7 +62,7 @@ void forknet() {
 	}
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I./include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
 
 type cmdForknet struct {
diff --git a/lxd/main_forkproxy.go b/lxd/main_forkproxy.go
index 914c44bad2..9717907ccc 100644
--- a/lxd/main_forkproxy.go
+++ b/lxd/main_forkproxy.go
@@ -282,7 +282,7 @@ void forkproxy()
 	}
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I./include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
 
 const forkproxyUDSSockFDNum int = C.FORKPROXY_UDS_SOCK_FD_NUM
diff --git a/lxd/main_forkuevent.go b/lxd/main_forkuevent.go
index 6a07b7f6e5..6c360b8d0e 100644
--- a/lxd/main_forkuevent.go
+++ b/lxd/main_forkuevent.go
@@ -222,7 +222,7 @@ void forkuevent() {
 	}
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I./include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
 
 type cmdForkuevent struct {
diff --git a/lxd/main_nsexec.go b/lxd/main_nsexec.go
index 770f87b90f..9426587c20 100644
--- a/lxd/main_nsexec.go
+++ b/lxd/main_nsexec.go
@@ -302,5 +302,5 @@ __attribute__((constructor)) void init(void) {
 		checkfeature();
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I./include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
diff --git a/lxd/storage_cgo.go b/lxd/storage_cgo.go
index c1bd2a4142..e177b408fa 100644
--- a/lxd/storage_cgo.go
+++ b/lxd/storage_cgo.go
@@ -281,7 +281,7 @@ int unset_autoclear_loop_device(int fd_loop)
 	return ioctl(fd_loop, LOOP_SET_STATUS64, &lo64);
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I./include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
 
 import (
diff --git a/shared/idmap/shift_linux.go b/shared/idmap/shift_linux.go
index 3aee917148..98e99cb75c 100644
--- a/shared/idmap/shift_linux.go
+++ b/shared/idmap/shift_linux.go
@@ -153,7 +153,7 @@ int shiftowner(char *basepath, char *path, int uid, int gid)
 	return 0;
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I../../lxd/include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
 
 // ShiftOwner updates uid and gid for a file when entering/exiting a namespace
diff --git a/shared/network_linux.go b/shared/network_linux.go
index 4de04e4cda..4efb975e48 100644
--- a/shared/network_linux.go
+++ b/shared/network_linux.go
@@ -18,7 +18,7 @@ import (
 /*
 #include "../shared/netns_getifaddrs.c"
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I../lxd/include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
 
 func NetnsGetifaddrs(initPID int32) (map[string]api.ContainerStateNetwork, error) {
diff --git a/shared/termios/termios_unix.go b/shared/termios/termios_unix.go
index 153d826909..27d9267ff9 100644
--- a/shared/termios/termios_unix.go
+++ b/shared/termios/termios_unix.go
@@ -10,7 +10,7 @@ import (
 )
 
 // #include <termios.h>
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I../../lxd/include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
 import "C"
 
 // State contains the state of a terminal.
diff --git a/shared/util_linux_cgo.go b/shared/util_linux_cgo.go
index 1a9549f1dc..af4b21e8d2 100644
--- a/shared/util_linux_cgo.go
+++ b/shared/util_linux_cgo.go
@@ -16,7 +16,6 @@ import (
 	"github.com/lxc/lxd/shared/logger"
 )
 
-// #cgo LDFLAGS: -lutil -lpthread
 /*
 #define _GNU_SOURCE
 #include <errno.h>
@@ -234,7 +233,8 @@ out:
 	return ret;
 }
 */
-// #cgo CFLAGS: -std=gnu11 -Wvla
+// #cgo CFLAGS: -I../lxd/include/ -std=gnu11 -Wvla -Wimplicit-fallthrough=5 -Wcast-align -fno-strict-aliasing -fstack-clash-protection -fstack-protector-strong --param=ssp-buffer-size=4 -g -Werror=implicit-function-declaration -Wlogical-op -Wmissing-include-dirs -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wshadow -Wendif-labels -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs
+// #cgo LDFLAGS: -lutil
 import "C"
 
 const ABSTRACT_UNIX_SOCK_LEN int = C.ABSTRACT_UNIX_SOCK_LEN

From db0b2297db75359c40c90dc88fff2aa2da8bfc6c Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 14:26:01 +0100
Subject: [PATCH 03/20] nsexec: cleanup macros do_setns

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_nsexec.go | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/lxd/main_nsexec.go b/lxd/main_nsexec.go
index 9426587c20..c9b50347d9 100644
--- a/lxd/main_nsexec.go
+++ b/lxd/main_nsexec.go
@@ -33,6 +33,8 @@ package main
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "include/memory_utils.h"
+
 // External functions
 extern void checkfeature();
 extern void forkfile();
@@ -41,14 +43,6 @@ extern void forknet();
 extern void forkproxy();
 extern void forkuevent();
 
-// Make the compiler our memory housekeeper.
-static inline void __auto_free__(void *p)
-{
-	free(*(void **)p);
-}
-
-#define __do_free __attribute__((__cleanup__(__auto_free__)))
-
 // Command line parsing and tracking
 char *cmdline_buf = NULL;
 char *cmdline_cur = NULL;
@@ -85,7 +79,7 @@ void error(char *msg)
 }
 
 int dosetns(int pid, char *nstype) {
-	int mntns;
+	__do_close_prot_errno int mntns = -EBADF;
 	char buf[PATH_MAX];
 
 	sprintf(buf, "/proc/%d/ns/%s", pid, nstype);
@@ -97,10 +91,8 @@ int dosetns(int pid, char *nstype) {
 
 	if (setns(mntns, 0) < 0) {
 		error("error: setns");
-		close(mntns);
 		return -1;
 	}
-	close(mntns);
 
 	return 0;
 }

From 35924aadaedbcc922eca22422156da316e91d322 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 14:31:15 +0100
Subject: [PATCH 04/20] nsexec: cleanup macros in_same_namespace

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_nsexec.go | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/lxd/main_nsexec.go b/lxd/main_nsexec.go
index c9b50347d9..f21397f034 100644
--- a/lxd/main_nsexec.go
+++ b/lxd/main_nsexec.go
@@ -128,7 +128,8 @@ static int preserve_ns(const int pid, const char *ns)
 // in the same namespace returns -EINVAL, -1 if an error occurred.
 static int in_same_namespace(pid_t pid1, pid_t pid2, const char *ns)
 {
-	int ns_fd1 = -1, ns_fd2 = -1, ret = -1;
+	__do_close_prot_errno int ns_fd1 = -1, ns_fd2 = -1;
+	int ret = -1;
 	struct stat ns_st1, ns_st2;
 
 	ns_fd1 = preserve_ns(pid1, ns);
@@ -138,38 +139,28 @@ static int in_same_namespace(pid_t pid1, pid_t pid2, const char *ns)
 		if (errno == ENOENT)
 			return -EINVAL;
 
-		goto out;
+		return -1;
 	}
 
 	ns_fd2 = preserve_ns(pid2, ns);
 	if (ns_fd2 < 0)
-		goto out;
+		return -1;
 
 	ret = fstat(ns_fd1, &ns_st1);
 	if (ret < 0)
-		goto out;
+		return -1;
 
 	ret = fstat(ns_fd2, &ns_st2);
 	if (ret < 0)
-		goto out;
+		return -1;
 
 	// processes are in the same namespace
 	ret = -EINVAL;
 	if ((ns_st1.st_dev == ns_st2.st_dev ) && (ns_st1.st_ino == ns_st2.st_ino))
-		goto out;
+		return -1;
 
 	// processes are in different namespaces
-	ret = ns_fd2;
-	ns_fd2 = -1;
-
-out:
-
-	if (ns_fd1 >= 0)
-		close(ns_fd1);
-	if (ns_fd2 >= 0)
-		close(ns_fd2);
-
-	return ret;
+	return move_fd(ns_fd2);
 }
 
 void attach_userns(int pid) {

From 239e2aab9b543cade5b0e72f8e82df8dd501f21a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 14:32:10 +0100
Subject: [PATCH 05/20] nsexec: cleanup macros attach_userns

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

diff --git a/lxd/main_nsexec.go b/lxd/main_nsexec.go
index f21397f034..77b884ae2f 100644
--- a/lxd/main_nsexec.go
+++ b/lxd/main_nsexec.go
@@ -164,7 +164,8 @@ static int in_same_namespace(pid_t pid1, pid_t pid2, const char *ns)
 }
 
 void attach_userns(int pid) {
-	int ret, userns_fd;
+	__do_close_prot_errno int userns_fd = -EBADF;
+	int ret;
 
 	userns_fd = in_same_namespace(getpid(), pid, "user");
 	if (userns_fd < 0) {
@@ -175,7 +176,6 @@ void attach_userns(int pid) {
 	}
 
 	ret = setns(userns_fd, CLONE_NEWUSER);
-	close(userns_fd);
 	if (ret < 0) {
 		fprintf(stderr, "Failed setns to container user namespace: %s\n", strerror(errno));
 		_exit(EXIT_FAILURE);

From 237fd9d89931d922a21ba14f12716da24c95cb75 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 14:35:36 +0100
Subject: [PATCH 06/20] nsexec: cleanup macros file_to_buf

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_nsexec.go | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/lxd/main_nsexec.go b/lxd/main_nsexec.go
index 77b884ae2f..46d4977976 100644
--- a/lxd/main_nsexec.go
+++ b/lxd/main_nsexec.go
@@ -213,9 +213,9 @@ again:
 
 static char *file_to_buf(char *path, size_t *length)
 {
-	int fd;
+	__do_close_prot_errno int fd = -EBADF;
+	__do_free char *copy = NULL;
 	char buf[PATH_MAX];
-	char *copy = NULL;
 
 	if (!length)
 		return NULL;
@@ -231,26 +231,20 @@ static char *file_to_buf(char *path, size_t *length)
 
 		n = lxc_read_nointr(fd, buf, sizeof(buf));
 		if (n < 0)
-			goto on_error;
+			return NULL;
 		if (!n)
 			break;
 
 		copy = realloc(old, (*length + n) * sizeof(*old));
 		if (!copy)
-			goto on_error;
+			return NULL;
 
 		memcpy(copy + *length, buf, n);
 		*length += n;
 	}
 
 	close(fd);
-	return copy;
-
-on_error:
-	close(fd);
-	free(copy);
-
-	return NULL;
+	return move_ptr(copy);
 }
 
 __attribute__((constructor)) void init(void) {

From cad90f9a988835cb5676246fa406247711a62169 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 15:03:06 +0100
Subject: [PATCH 07/20] devlxd_gccgo: initialize to 0

There's no need to risk returning uninitialized data.

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

diff --git a/lxd/devlxd_gccgo.go b/lxd/devlxd_gccgo.go
index 31f10eb16f..1784ad23de 100644
--- a/lxd/devlxd_gccgo.go
+++ b/lxd/devlxd_gccgo.go
@@ -15,12 +15,12 @@ import (
 #include <stdio.h>
 #include <string.h>
 
-void getucred(int sock, uint *uid, uint *gid, int *pid) {
-	struct ucred peercred;
+void getucred(int sock, uint *uid, uint *gid, int *pid)
+{
+	struct ucred peercred = {0};
 	socklen_t len;
 
 	len = sizeof(struct ucred);
-
 	if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &len) != 0 || len != sizeof(peercred)) {
 		fprintf(stderr, "getsockopt failed: %s\n", strerror(errno));
 		return;

From e7e69acd52f5e872fd13390f16bd83022c1b8e6e Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 15:07:06 +0100
Subject: [PATCH 08/20] network: include macro.h

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/network.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/shared/network.c b/shared/network.c
index 83563357c8..421f99b49f 100644
--- a/shared/network.c
+++ b/shared/network.c
@@ -19,6 +19,8 @@
 #include <sys/socket.h>
 #include <unistd.h>
 
+#include "../lxd/include/macro.h"
+
 #ifndef NETNS_RTA
 #define NETNS_RTA(r) \
 	((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))))
@@ -94,15 +96,6 @@
 	((struct rtattr *)(((void *)(nmsg)) + \
 			   __NETLINK_ALIGN((nmsg)->nlmsg_len)))
 
-enum {
-	__LXC_NETNSA_NONE,
-#define __LXC_NETNSA_NSID_NOT_ASSIGNED -1
-	__LXC_NETNSA_NSID,
-	__LXC_NETNSA_PID,
-	__LXC_NETNSA_FD,
-	__LXC_NETNSA_MAX,
-};
-
 static int netlink_open(int protocol)
 {
 	int fd, ret;

From a50caab681c25260ebf620d2de74a0e5532709fa Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 15:09:15 +0100
Subject: [PATCH 09/20] checkfeature: cleanup macros netns_set_nsid

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_checkfeature.go | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/lxd/main_checkfeature.go b/lxd/main_checkfeature.go
index d5a5b6c992..459e4e4125 100644
--- a/lxd/main_checkfeature.go
+++ b/lxd/main_checkfeature.go
@@ -20,6 +20,7 @@ import (
 #include <unistd.h>
 
 #include "../shared/netns_getifaddrs.c"
+#include "include/memory_utils.h"
 
 bool netnsid_aware = false;
 bool uevent_aware = false;
@@ -29,13 +30,13 @@ extern int can_inject_uevent(const char *uevent, size_t len);
 
 static int netns_set_nsid(int fd)
 {
-	int sockfd, ret;
+	__do_close_prot_errno int sockfd = -EBADF;
+	int ret;
 	char buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
 		 NLMSG_ALIGN(sizeof(struct rtgenmsg)) +
 		 NLMSG_ALIGN(1024)];
 	struct nlmsghdr *hdr;
 	struct rtgenmsg *msg;
-	int saved_errno;
 	__s32 ns_id = -1;
 	__u32 netns_fd = fd;
 
@@ -58,9 +59,6 @@ static int netns_set_nsid(int fd)
 	addattr(hdr, 1024, __LXC_NETNSA_NSID, &ns_id, sizeof(ns_id));
 
 	ret = netlink_transaction(sockfd, hdr, hdr);
-	saved_errno = errno;
-	close(sockfd);
-	errno = saved_errno;
 	if (ret < 0)
 		return -1;
 

From 78af33a654c35712bb0847d95c8d6e0f6c2457a3 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 15:12:11 +0100
Subject: [PATCH 10/20] checkfeature: cleanup macros is_netnsid_aware

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_checkfeature.go | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/lxd/main_checkfeature.go b/lxd/main_checkfeature.go
index 459e4e4125..47ada37afa 100644
--- a/lxd/main_checkfeature.go
+++ b/lxd/main_checkfeature.go
@@ -67,7 +67,8 @@ static int netns_set_nsid(int fd)
 
 void is_netnsid_aware(int *hostnetns_fd, int *newnetns_fd)
 {
-	int sock_fd, netnsid, ret;
+	__do_close_prot_errno int sock_fd = -EBADF;
+	int netnsid, ret;
 	struct netns_ifaddrs *ifaddrs;
 
 	*hostnetns_fd = open("/proc/self/ns/net", O_RDONLY | O_CLOEXEC);
@@ -107,7 +108,6 @@ void is_netnsid_aware(int *hostnetns_fd, int *newnetns_fd)
 	}
 
 	ret = setsockopt(sock_fd, SOL_NETLINK, NETLINK_DUMP_STRICT_CHK, &(int){1}, sizeof(int));
-	close(sock_fd);
 	if (ret < 0) {
 		// NETLINK_DUMP_STRICT_CHK isn't supported
 		return;
@@ -125,8 +125,9 @@ void is_uevent_aware()
 	uevent_aware = true;
 }
 
-void checkfeature() {
-	int hostnetns_fd = -1, newnetns_fd = -1;
+void checkfeature()
+{
+	__do_close_prot_errno int hostnetns_fd = -EBADF, newnetns_fd = -EBADF;
 
 	is_netnsid_aware(&hostnetns_fd, &newnetns_fd);
 	is_uevent_aware();
@@ -134,12 +135,6 @@ void checkfeature() {
 	if (setns(hostnetns_fd, CLONE_NEWNET) < 0)
 		(void)sprintf(errbuf, "%s", "Failed to attach to host network namespace");
 
-	if (hostnetns_fd >= 0)
-		close(hostnetns_fd);
-
-	if (newnetns_fd >= 0)
-		close(newnetns_fd);
-
 }
 
 static bool is_empty_string(char *s)

From 017bbd4ae1574e8ae3fabd13f266fc37d9ae5178 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 16:10:18 +0100
Subject: [PATCH 11/20] forkfile: cleanup macros manip_file_in_ns

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_forkfile.go | 36 +++++++++++++++++-------------------
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/lxd/main_forkfile.go b/lxd/main_forkfile.go
index af78497287..a9b2517e7f 100644
--- a/lxd/main_forkfile.go
+++ b/lxd/main_forkfile.go
@@ -20,6 +20,7 @@ import (
 #include <limits.h>
 
 #include "include/compiler.h"
+#include "include/memory_utils.h"
 
 extern char* advance_arg(bool required);
 extern void error(char *msg);
@@ -57,7 +58,7 @@ int copy(int target, int source, bool append)
 }
 
 int manip_file_in_ns(char *rootfs, int pid, char *host, char *container, bool is_put, char *type, uid_t uid, gid_t gid, mode_t mode, uid_t defaultUid, gid_t defaultGid, mode_t defaultMode, bool append) {
-	int host_fd = -1, container_fd = -1;
+	__do_close_prot_errno int host_fd = -1, container_fd = -1;
 	int ret = -1;
 	int container_open_flags;
 	struct stat st;
@@ -83,17 +84,17 @@ int manip_file_in_ns(char *rootfs, int pid, char *host, char *container, bool is
 
 		if (dosetns(pid, "mnt") < 0) {
 			error("error: setns");
-			goto close_host;
+			return -1;
 		}
 	} else {
 		if (chroot(rootfs) < 0) {
 			error("error: chroot");
-			goto close_host;
+			return -1;
 		}
 
 		if (chdir("/") < 0) {
 			error("error: chdir");
-			goto close_host;
+			return -1;
 		}
 	}
 
@@ -159,7 +160,7 @@ int manip_file_in_ns(char *rootfs, int pid, char *host, char *container, bool is
 
 	if (is_put && !is_dir_manip && exists && S_ISDIR(st.st_mode)) {
 		error("error: Path already exists as a directory");
-		goto close_host;
+		return -1;
 	}
 
 	if (exists && S_ISDIR(st.st_mode))
@@ -174,19 +175,19 @@ int manip_file_in_ns(char *rootfs, int pid, char *host, char *container, bool is
 		link_length = readlink(container, link_target, PATH_MAX);
 		if (link_length < 0 || link_length >= PATH_MAX) {
 			error("error: readlink");
-			goto close_host;
+			return -1;
 		}
 		link_target[link_length] = '\0';
 
 		dprintf(host_fd, "%s\n", link_target);
-		goto close_container;
+		return -1;
 	}
 
 	umask(0);
 	container_fd = open(container, container_open_flags, 0);
 	if (container_fd < 0) {
 		error("error: open");
-		goto close_host;
+		return -1;
 	}
 	if (is_put) {
 		if (!exists) {
@@ -205,23 +206,23 @@ int manip_file_in_ns(char *rootfs, int pid, char *host, char *container, bool is
 
 		if (copy(container_fd, host_fd, append) < 0) {
 			error("error: copy");
-			goto close_container;
+			return -1;
 		}
 
 		if (mode != -1 && fchmod(container_fd, mode) < 0) {
 			error("error: chmod");
-			goto close_container;
+			return -1;
 		}
 
 		if (fchown(container_fd, uid, gid) < 0) {
 			error("error: chown");
-			goto close_container;
+			return -1;
 		}
 		ret = 0;
 	} else {
 		if (fstat(container_fd, &st) < 0) {
 			error("error: stat");
-			goto close_container;
+			return -1;
 		}
 
 		fprintf(stderr, "uid: %ld\n", (long)st.st_uid);
@@ -231,10 +232,10 @@ int manip_file_in_ns(char *rootfs, int pid, char *host, char *container, bool is
 			DIR *fdir;
 			struct dirent *de;
 
-			fdir = fdopendir(container_fd);
+			fdir = fdopendir(move_fd(container_fd));
 			if (!fdir) {
 				error("error: fdopendir");
-				goto close_container;
+				return -1;
 			}
 
 			fprintf(stderr, "type: directory\n");
@@ -259,7 +260,7 @@ int manip_file_in_ns(char *rootfs, int pid, char *host, char *container, bool is
 
 			closedir(fdir);
 			// container_fd is dead now that we fdopendir'd it
-			goto close_host;
+			return -1;
 		} else {
 			fprintf(stderr, "type: file\n");
 			ret = copy(host_fd, container_fd, false);
@@ -267,10 +268,7 @@ int manip_file_in_ns(char *rootfs, int pid, char *host, char *container, bool is
 		fprintf(stderr, "type: %s", S_ISDIR(st.st_mode) ? "directory" : "file");
 	}
 
-close_container:
-	close(container_fd);
-close_host:
-	close(host_fd);
+out:
 	return ret;
 }
 

From 39f36c4040623e115ccdda2f03728c1a687772c3 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 16:16:05 +0100
Subject: [PATCH 12/20] forkmount: cleanup macros

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_forkmount.go | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/lxd/main_forkmount.go b/lxd/main_forkmount.go
index 91494d427f..0adce81204 100644
--- a/lxd/main_forkmount.go
+++ b/lxd/main_forkmount.go
@@ -25,6 +25,7 @@ import (
 #include <unistd.h>
 
 #include "include/compiler.h"
+#include "include/memory_utils.h"
 
 #define VERSION_AT_LEAST(major, minor, micro)							\
 	((LXC_DEVEL == 1) || (!(major > LXC_VERSION_MAJOR ||					\
@@ -40,20 +41,19 @@ int mkdir_p(const char *dir, mode_t mode)
 {
 	const char *tmp = dir;
 	const char *orig = dir;
-	char *makeme;
 
 	do {
+		__do_free char *makeme = NULL;
+
 		dir = tmp + strspn(tmp, "/");
 		tmp = dir + strcspn(dir, "/");
 		makeme = strndup(orig, dir - orig);
 		if (*makeme) {
 			if (mkdir(makeme, mode) && errno != EEXIST) {
 				fprintf(stderr, "failed to create directory '%s': %s\n", makeme, strerror(errno));
-				free(makeme);
 				return -1;
 			}
 		}
-		free(makeme);
 	} while(tmp != dir);
 
 	return 0;
@@ -75,9 +75,10 @@ void ensure_dir(char *dest) {
 	}
 }
 
-void ensure_file(char *dest) {
+void ensure_file(char *dest)
+{
+	__do_close_prot_errno int fd = -EBADF;
 	struct stat sb;
-	int fd;
 
 	if (stat(dest, &sb) == 0) {
 		if ((sb.st_mode & S_IFMT) != S_IFDIR)
@@ -93,12 +94,11 @@ void ensure_file(char *dest) {
 		fprintf(stderr, "Failed to mkdir %s: %s\n", dest, strerror(errno));
 		_exit(1);
 	}
-	close(fd);
 }
 
-void create(char *src, char *dest) {
-	char *dirdup;
-	char *destdirname;
+void create(char *src, char *dest)
+{
+	__do_free char *destdirname = NULL, *dirdup = NULL;
 
 	struct stat sb;
 	if (stat(src, &sb) < 0) {
@@ -114,10 +114,8 @@ void create(char *src, char *dest) {
 
 	if (mkdir_p(destdirname, 0755) < 0) {
 		fprintf(stderr, "failed to create path: %s\n", destdirname);
-		free(dirdup);
 		_exit(1);
 	}
-	free(dirdup);
 
 	switch (sb.st_mode & S_IFMT) {
 	case S_IFDIR:

From 7be7316f3ee11254ad9b8bf30636a8aaff2363ee Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 16:27:29 +0100
Subject: [PATCH 13/20] forkuevent: cleanup macros

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_forkuevent.go | 71 ++++++++++++++----------------------------
 1 file changed, 24 insertions(+), 47 deletions(-)

diff --git a/lxd/main_forkuevent.go b/lxd/main_forkuevent.go
index 6c360b8d0e..051c631fdb 100644
--- a/lxd/main_forkuevent.go
+++ b/lxd/main_forkuevent.go
@@ -26,6 +26,7 @@ import (
 #include <unistd.h>
 
 #include "../shared/network.c"
+#include "include/memory_utils.h"
 
 #ifndef UEVENT_SEND
 #define UEVENT_SEND 16
@@ -42,7 +43,7 @@ struct nlmsg {
 
 static struct nlmsg *nlmsg_alloc(size_t size)
 {
-	struct nlmsg *nlmsg;
+	__do_free struct nlmsg *nlmsg = NULL;
 	size_t len = NLMSG_HDRLEN + NLMSG_ALIGN(size);
 
 	nlmsg = (struct nlmsg *)malloc(sizeof(struct nlmsg));
@@ -51,16 +52,13 @@ static struct nlmsg *nlmsg_alloc(size_t size)
 
 	nlmsg->nlmsghdr = (struct nlmsghdr *)malloc(len);
 	if (!nlmsg->nlmsghdr)
-		goto errout;
+		return NULL;
 
 	memset(nlmsg->nlmsghdr, 0, len);
 	nlmsg->cap = len;
 	nlmsg->nlmsghdr->nlmsg_len = NLMSG_HDRLEN;
 
 	return nlmsg;
-errout:
-	free(nlmsg);
-	return NULL;
 }
 
 static void *nlmsg_reserve_unaligned(struct nlmsg *nlmsg, size_t len)
@@ -83,9 +81,10 @@ static void *nlmsg_reserve_unaligned(struct nlmsg *nlmsg, size_t len)
 
 int can_inject_uevent(const char *uevent, size_t len)
 {
-	int ret, sock_fd;
+	__do_close_prot_errno int sock_fd = -EBADF;
+	__do_free struct nlmsg *nlmsg = NULL;
+	int ret;
 	char *umsg = NULL;
-	struct nlmsg *nlmsg = NULL;
 
 	sock_fd = netlink_open(NETLINK_KOBJECT_UEVENT);
 	if (sock_fd < 0) {
@@ -93,78 +92,56 @@ int can_inject_uevent(const char *uevent, size_t len)
 	}
 
 	nlmsg = nlmsg_alloc(len);
-	if (!nlmsg) {
-		ret = -1;
-		goto on_error;
-	}
+	if (!nlmsg)
+		return -1;
 
 	nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST;
 	nlmsg->nlmsghdr->nlmsg_type = UEVENT_SEND;
 	nlmsg->nlmsghdr->nlmsg_pid = 0;
 
 	umsg = nlmsg_reserve_unaligned(nlmsg, len);
-	if (!umsg) {
-		ret = -1;
-		goto on_error;
-	}
+	if (!umsg)
+		return -1;
 
 	memcpy(umsg, uevent, len);
 
 	ret = __netlink_send(sock_fd, nlmsg->nlmsghdr);
-	if (ret < 0) {
-		ret = -1;
-		goto on_error;
-	}
-
-	ret = 0;
+	if (ret < 0)
+		return -1;
 
-on_error:
-	close(sock_fd);
-	free(nlmsg);
-	return ret;
+	return 0;
 }
 
 static int inject_uevent(const char *uevent, size_t len)
 {
-	int ret, sock_fd;
+	__do_close_prot_errno int sock_fd = -EBADF;
+	__do_free struct nlmsg *nlmsg = NULL;
+	int ret;
 	char *umsg = NULL;
-	struct nlmsg *nlmsg = NULL;
 
 	sock_fd = netlink_open(NETLINK_KOBJECT_UEVENT);
-	if (sock_fd < 0) {
+	if (sock_fd < 0)
 		return -1;
-	}
 
 	nlmsg = nlmsg_alloc(len);
-	if (!nlmsg) {
-		ret = -1;
-		goto on_error;
-	}
+	if (!nlmsg)
+		return -1;
 
 	nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK | NLM_F_REQUEST;
 	nlmsg->nlmsghdr->nlmsg_type = UEVENT_SEND;
 	nlmsg->nlmsghdr->nlmsg_pid = 0;
 
 	umsg = nlmsg_reserve_unaligned(nlmsg, len);
-	if (!umsg) {
-		ret = -1;
-		goto on_error;
-	}
+	if (!umsg)
+		return -1;
 
 	memcpy(umsg, uevent, len);
 
 	ret = netlink_transaction(sock_fd, nlmsg->nlmsghdr, nlmsg->nlmsghdr);
-	if (ret < 0) {
-		ret = -1;
-		goto on_error;
-	}
-
-	ret = 0;
+	if (ret < 0)
+		return -1;
 
-on_error:
-	close(sock_fd);
-	free(nlmsg);
-	return ret;
+	return 0;
 }
 
 void forkuevent() {

From 16d2954ea548cc15cb54702857c66252870d593c Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 16:28:35 +0100
Subject: [PATCH 14/20] storage_cgo: include macro.h

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_cgo.go | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lxd/storage_cgo.go b/lxd/storage_cgo.go
index e177b408fa..ca1a0cc69b 100644
--- a/lxd/storage_cgo.go
+++ b/lxd/storage_cgo.go
@@ -19,9 +19,7 @@ package main
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#ifndef LO_FLAGS_AUTOCLEAR
-#define LO_FLAGS_AUTOCLEAR 4
-#endif
+#include "include/macro.h"
 
 #ifndef MS_LAZYTIME
 #define MS_LAZYTIME (1<<25)

From 703d1c71cc4d4b8384fd0fdf83c8469537b56b00 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 16:33:50 +0100
Subject: [PATCH 15/20] storage_cgo: cleanup macros find_associated_[...]

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_cgo.go | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/lxd/storage_cgo.go b/lxd/storage_cgo.go
index ca1a0cc69b..d9511f0ed3 100644
--- a/lxd/storage_cgo.go
+++ b/lxd/storage_cgo.go
@@ -20,6 +20,7 @@ package main
 #include <sys/types.h>
 
 #include "include/macro.h"
+#include "include/memory_utils.h"
 
 #ifndef MS_LAZYTIME
 #define MS_LAZYTIME (1<<25)
@@ -36,20 +37,21 @@ package main
 static int find_associated_loop_device(const char *loop_file,
 				       char *loop_dev_name)
 {
+	__do_closedir DIR *dir = NULL;
 	char looppath[LXD_MAX_LOOP_PATHLEN];
 	char buf[LXD_MAXPATH];
 	struct dirent *dp;
-	DIR *dir;
-	int dfd = -1, fd = -1;
 
 	dir = opendir("/sys/block");
 	if (!dir)
 		return -1;
 
 	while ((dp = readdir(dir))) {
+		__do_close_prot_errno int loop_path_fd = -EBADF;
 		int ret;
 		size_t totlen;
 		struct stat fstatbuf;
+		int dfd = -1;
 
 		if (!dp)
 			break;
@@ -69,17 +71,15 @@ static int find_associated_loop_device(const char *loop_file,
 		if (ret < 0)
 			continue;
 
-		fd = openat(dfd, looppath, O_RDONLY | O_CLOEXEC, 0);
+		loop_path_fd = openat(dfd, looppath, O_RDONLY | O_CLOEXEC, 0);
 		if (ret < 0)
 			continue;
 
 		// Clear buffer.
 		memset(buf, 0, sizeof(buf));
-		ret = read(fd, buf, sizeof(buf));
+		ret = read(loop_path_fd, buf, sizeof(buf));
 		if (ret < 0)
 			continue;
-		close(fd);
-		fd = -1;
 
 		totlen = strlen(buf);
 
@@ -97,16 +97,10 @@ static int find_associated_loop_device(const char *loop_file,
 			continue;
 
 		// Open fd to loop device.
-		fd = open(loop_dev_name, O_RDWR);
-		break;
+		return open(loop_dev_name, O_RDWR);
 	}
 
-	closedir(dir);
-
-	if (fd < 0)
-		return -1;
-
-	return fd;
+	return -1;
 }
 
 static int get_unused_loop_dev_legacy(char *loop_name)

From 1a120b53427da3ed8e4cbc80a20454aafbd5be43 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 16:36:30 +0100
Subject: [PATCH 16/20] storage_cgo: cleanup macros get_un[...]_legacy

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_cgo.go | 28 ++++++++--------------------
 1 file changed, 8 insertions(+), 20 deletions(-)

diff --git a/lxd/storage_cgo.go b/lxd/storage_cgo.go
index d9511f0ed3..5808289a25 100644
--- a/lxd/storage_cgo.go
+++ b/lxd/storage_cgo.go
@@ -105,16 +105,17 @@ static int find_associated_loop_device(const char *loop_file,
 
 static int get_unused_loop_dev_legacy(char *loop_name)
 {
+	__do_closedir DIR *dir = NULL;
 	struct dirent *dp;
 	struct loop_info64 lo64;
-	DIR *dir;
-	int dfd = -1, fd = -1, ret = -1;
 
 	dir = opendir("/dev");
 	if (!dir)
 		return -1;
 
 	while ((dp = readdir(dir))) {
+		__do_close_prot_errno int dfd = -EBADF, fd = -EBADF, ret = -1;
+
 		if (!dp)
 			break;
 
@@ -130,31 +131,18 @@ static int get_unused_loop_dev_legacy(char *loop_name)
 			continue;
 
 		ret = ioctl(fd, LOOP_GET_STATUS64, &lo64);
-		if (ret < 0) {
-			if (ioctl(fd, LOOP_GET_STATUS64, &lo64) == 0 ||
-			    errno != ENXIO) {
-				close(fd);
-				fd = -1;
+		if (ret < 0)
+			if (ioctl(fd, LOOP_GET_STATUS64, &lo64) == 0 || errno != ENXIO)
 				continue;
-			}
-		}
 
 		ret = snprintf(loop_name, LO_NAME_SIZE, "/dev/%s", dp->d_name);
-		if (ret < 0 || ret >= LO_NAME_SIZE) {
-			close(fd);
-			fd = -1;
+		if (ret < 0 || ret >= LO_NAME_SIZE)
 			continue;
-		}
 
-		break;
+		return move_fd(fd);
 	}
 
-	closedir(dir);
-
-	if (fd < 0)
-		return -1;
-
-	return fd;
+	return -1;
 }
 
 static int get_unused_loop_dev(char *name_loop)

From 952c48a34d282eb73e3f1e9f3cb180c65c65eb06 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 16:38:31 +0100
Subject: [PATCH 17/20] storage_cgo: cleanup macros get_unused_loop_dev

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_cgo.go | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/lxd/storage_cgo.go b/lxd/storage_cgo.go
index 5808289a25..8ef6f78673 100644
--- a/lxd/storage_cgo.go
+++ b/lxd/storage_cgo.go
@@ -147,8 +147,8 @@ static int get_unused_loop_dev_legacy(char *loop_name)
 
 static int get_unused_loop_dev(char *name_loop)
 {
+	__do_close_prot_errno int fd_ctl = -1;
 	int loop_nr, ret;
-	int fd_ctl = -1, fd_tmp = -1;
 
 	fd_ctl = open("/dev/loop-control", O_RDWR | O_CLOEXEC);
 	if (fd_ctl < 0)
@@ -156,19 +156,13 @@ static int get_unused_loop_dev(char *name_loop)
 
 	loop_nr = ioctl(fd_ctl, LOOP_CTL_GET_FREE);
 	if (loop_nr < 0)
-		goto on_error;
+		return -1;
 
 	ret = snprintf(name_loop, LO_NAME_SIZE, "/dev/loop%d", loop_nr);
 	if (ret < 0 || ret >= LO_NAME_SIZE)
-		goto on_error;
-
-	fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC);
-	if (fd_tmp < 0)
-		goto on_error;
+		return -1;
 
-on_error:
-	close(fd_ctl);
-	return fd_tmp;
+	return open(name_loop, O_RDWR | O_CLOEXEC);
 }
 
 static int prepare_loop_dev(const char *source, char *loop_dev, int flags)

From 71bed8f54f8fbd88ddeca7ab63cf7110d363e680 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 16:40:22 +0100
Subject: [PATCH 18/20] storage_cgo: cleanup macros prepare_loop_dev

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_cgo.go | 23 ++++++-----------------
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/lxd/storage_cgo.go b/lxd/storage_cgo.go
index 8ef6f78673..c1db803b88 100644
--- a/lxd/storage_cgo.go
+++ b/lxd/storage_cgo.go
@@ -167,45 +167,34 @@ static int get_unused_loop_dev(char *name_loop)
 
 static int prepare_loop_dev(const char *source, char *loop_dev, int flags)
 {
+	__do_close_prot_errno int fd_img = -1, fd_loop = -1;
 	int ret;
 	struct loop_info64 lo64;
-	int fd_img = -1, fret = -1, fd_loop = -1;
 
 	fd_loop = get_unused_loop_dev(loop_dev);
 	if (fd_loop < 0) {
 		if (fd_loop == -ENODEV)
 			fd_loop = get_unused_loop_dev_legacy(loop_dev);
 		else
-			goto on_error;
+			return -1;
 	}
 
 	fd_img = open(source, O_RDWR | O_CLOEXEC);
 	if (fd_img < 0)
-		goto on_error;
+		return -1;
 
 	ret = ioctl(fd_loop, LOOP_SET_FD, fd_img);
 	if (ret < 0)
-		goto on_error;
+		return -1;
 
 	memset(&lo64, 0, sizeof(lo64));
 	lo64.lo_flags = flags;
 
 	ret = ioctl(fd_loop, LOOP_SET_STATUS64, &lo64);
 	if (ret < 0)
-		goto on_error;
-
-	fret = 0;
-
-on_error:
-	if (fd_img >= 0)
-		close(fd_img);
-
-	if (fret < 0 && fd_loop >= 0) {
-		close(fd_loop);
-		fd_loop = -1;
-	}
+		return -1;
 
-	return fd_loop;
+	return move_fd(fd_loop);
 }
 
 static inline int prepare_loop_dev_retry(const char *source, char *loop_dev, int flags)

From 860f45a839d33a049e921df3146cda583518c94c Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 16:42:55 +0100
Subject: [PATCH 19/20] shift_linux: cleanup macros shiftowner

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/idmap/shift_linux.go | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/shared/idmap/shift_linux.go b/shared/idmap/shift_linux.go
index 98e99cb75c..562e777bf9 100644
--- a/shared/idmap/shift_linux.go
+++ b/shared/idmap/shift_linux.go
@@ -33,6 +33,8 @@ import (
 // Needs to be included at the end
 #include <sys/xattr.h>
 
+#include "../../lxd/include/memory_utils.h"
+
 #ifndef VFS_CAP_REVISION_1
 #define VFS_CAP_REVISION_1 0x01000000
 #endif
@@ -90,7 +92,8 @@ int set_dummy_fs_ns_caps(const char *path)
 
 int shiftowner(char *basepath, char *path, int uid, int gid)
 {
-	int fd, ret;
+	__do_close_prot_errno int fd = -EBADF;
+	int ret;
 	char fdpath[PATH_MAX], realpath[PATH_MAX];
 	struct stat sb;
 
@@ -103,40 +106,34 @@ int shiftowner(char *basepath, char *path, int uid, int gid)
 	ret = sprintf(fdpath, "/proc/self/fd/%d", fd);
 	if (ret < 0) {
 		perror("Failed sprintf");
-		close(fd);
 		return 1;
 	}
 
 	ret = readlink(fdpath, realpath, PATH_MAX);
 	if (ret < 0) {
 		perror("Failed readlink");
-		close(fd);
 		return 1;
 	}
 
 	if (strlen(realpath) < strlen(basepath)) {
 		printf("Invalid path, source (%s) is outside of basepath (%s)\n", realpath, basepath);
-		close(fd);
 		return 1;
 	}
 
 	if (strncmp(realpath, basepath, strlen(basepath))) {
 		printf("Invalid path, source (%s) is outside of basepath " "(%s).\n", realpath, basepath);
-		close(fd);
 		return 1;
 	}
 
 	ret = fstat(fd, &sb);
 	if (ret < 0) {
 		perror("Failed fstat");
-		close(fd);
 		return 1;
 	}
 
 	ret = fchownat(fd, "", uid, gid, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
 	if (ret < 0) {
 		perror("Failed chown");
-		close(fd);
 		return 1;
 	}
 
@@ -144,12 +141,10 @@ int shiftowner(char *basepath, char *path, int uid, int gid)
 		ret = chmod(fdpath, sb.st_mode);
 		if (ret < 0) {
 			perror("Failed chmod");
-			close(fd);
 			return 1;
 		}
 	}
 
-	close(fd);
 	return 0;
 }
 */

From c0ba344b39d1e2a6b49917e35495aee9ea23734c Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 21 Feb 2019 16:45:51 +0100
Subject: [PATCH 20/20] util_linux_cgo: cleanup macros lxc_abstract_[...]

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/util_linux_cgo.go | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/shared/util_linux_cgo.go b/shared/util_linux_cgo.go
index af4b21e8d2..c5986a86d6 100644
--- a/shared/util_linux_cgo.go
+++ b/shared/util_linux_cgo.go
@@ -34,6 +34,8 @@ import (
 #include <sys/types.h>
 #include <sys/un.h>
 
+#include "../lxd/include/memory_utils.h"
+
 #ifndef AT_SYMLINK_FOLLOW
 #define AT_SYMLINK_FOLLOW    0x400
 #endif
@@ -149,12 +151,11 @@ again:
 int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
 			       void *data, size_t size)
 {
-	int ret;
+	__do_free char *cmsgbuf = NULL;
 	struct msghdr msg;
 	struct iovec iov;
 	struct cmsghdr *cmsg = NULL;
 	char buf[1] = {0};
-	char *cmsgbuf;
 	size_t cmsgbufsize = CMSG_SPACE(num_sendfds * sizeof(int));
 
 	memset(&msg, 0, sizeof(msg));
@@ -181,22 +182,18 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
 	msg.msg_iov = &iov;
 	msg.msg_iovlen = 1;
 
-	ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
-	if (ret < 0)
-		fprintf(stderr, "%s - Failed to send file descriptor\n", strerror(errno));
-	free(cmsgbuf);
-	return ret;
+	return sendmsg(fd, &msg, MSG_NOSIGNAL);
 }
 
 int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
 			       void *data, size_t size)
 {
+	__do_free char *cmsgbuf = NULL;
 	int ret;
 	struct msghdr msg;
 	struct iovec iov;
 	struct cmsghdr *cmsg = NULL;
 	char buf[1] = {0};
-	char *cmsgbuf;
 	size_t cmsgbufsize = CMSG_SPACE(num_recvfds * sizeof(int));
 
 	memset(&msg, 0, sizeof(msg));
@@ -217,7 +214,7 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
 	ret = recvmsg(fd, &msg, 0);
 	if (ret <= 0) {
 		fprintf(stderr, "%s - Failed to receive file descriptor\n", strerror(errno));
-		goto out;
+		return -1;
 	}
 
 	cmsg = CMSG_FIRSTHDR(&msg);
@@ -228,8 +225,6 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
 		memcpy(recvfds, CMSG_DATA(cmsg), num_recvfds * sizeof(int));
 	}
 
-out:
-	free(cmsgbuf);
 	return ret;
 }
 */


More information about the lxc-devel mailing list