diff --git a/Makefile b/Makefile index c225118..9236c64 100644 --- a/Makefile +++ b/Makefile @@ -18,12 +18,19 @@ # CC ?= gcc -CFLAGS += -O2 -g -ggdb -c -std=c11 \ + +CFLAGS += -O2 -g -ggdb -c -std=gnu11 \ -D_GNU_SOURCE \ - -fstack-protector-all -Wformat -Wformat=2 -Wformat-security -fPIE -Wa,--noexecstack \ + -fstack-protector-all -Wformat -Wformat=2 -Wformat-security -fPIE \ -Wall -Wextra -Werror -LDFLAGS += -Wl,-z,now -Wl,-z,relro -pie +LDFLAGS += -Wl,-z,now -Wl,-z,relro -pie -Wa,--noexecstack + +COMPILER_CLANG = $(shell $(CC) -v 2>&1 | grep version | head -n1 | egrep -o clang) +ifeq ($(COMPILER_CLANG),clang) + CFLAGS += -fblocks + LDFLAGS += -lBlocksRuntime +endif SRCS = nsjail.c cmdline.c contain.c log.c net.c mount.c user.c subproc.c sandbox.c util.c uts.c seccomp/bpf-helper.c OBJS = $(SRCS:.c=.o) diff --git a/common.h b/common.h index 0f3eb88..ca95342 100644 --- a/common.h +++ b/common.h @@ -31,6 +31,17 @@ #define ARRAYSIZE(array) (sizeof(array) / sizeof(*array)) +#define _STRMERGE(a, b) a##b + +#ifdef __clang__ + static void __attribute__((unused)) _clang_cleanup_func(void (^*dfunc)(void)) { (*dfunc)(); } + #define defer(a) void (^_STRMERGE(__df_, __COUNTER__))(void) __attribute__((cleanup(_clang_cleanup_func))) __attribute__((unused)) = ^{ a; } +#else + #define __block + #define defer(a) void _STRMERGE(_cleanup_func_, __LINE__)(void *_STRMERGE(_cleanup_unused_, __LINE__) __attribute__((unused))) { a; } ; int _STRMERGE(_cleanup_var_, __LINE__) __attribute__((cleanup(_STRMERGE(_cleanup_func_, __LINE__)))) __attribute__((unused)) +#endif + + struct pids_t { pid_t pid; time_t start; diff --git a/net.c b/net.c index 2719f2e..a41a4c6 100644 --- a/net.c +++ b/net.c @@ -322,11 +322,12 @@ void netConnToText(int fd, bool remote, char *buf, size_t s, struct sockaddr_in6 static bool netIfaceUp(const char *ifacename) { - int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + __block int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (sock == -1) { PLOG_E("socket(AF_INET, SOCK_STREAM, IPPROTO_IP)"); return false; } + defer(close(sock)); struct ifreq ifr; memset(&ifr, '\0', sizeof(ifr)); @@ -334,7 +335,6 @@ static bool netIfaceUp(const char *ifacename) if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { PLOG_E("ioctl(iface='%s', SIOCGIFFLAGS, IFF_UP)", ifacename); - close(sock); return false; } @@ -342,11 +342,9 @@ static bool netIfaceUp(const char *ifacename) if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { PLOG_E("ioctl(iface='%s', SIOCSIFFLAGS, IFF_UP)", ifacename); - close(sock); return false; } - close(sock); return true; } @@ -357,21 +355,19 @@ static bool netConfigureVs(struct nsjconf_t *nsjconf) snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", IFACE_NAME); struct in_addr addr; - int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + __block int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (sock == -1) { PLOG_E("socket(AF_INET, SOCK_STREAM, IPPROTO_IP)"); - close(sock); return false; } + defer(close(sock)); if (inet_pton(AF_INET, nsjconf->iface_vs_ip, &addr) != 1) { PLOG_E("Cannot convert '%s' into an IPv4 address", nsjconf->iface_vs_ip); - close(sock); return false; } if (addr.s_addr == INADDR_ANY) { LOG_I("IPv4 address for interface '%s' not set", IFACE_NAME); - close(sock); return true; } @@ -380,20 +376,17 @@ static bool netConfigureVs(struct nsjconf_t *nsjconf) sa->sin_addr = addr; if (ioctl(sock, SIOCSIFADDR, &ifr) == -1) { PLOG_E("ioctl(iface='%s', SIOCSIFADDR, '%s')", IFACE_NAME, nsjconf->iface_vs_ip); - close(sock); return false; } if (inet_pton(AF_INET, nsjconf->iface_vs_nm, &addr) != 1) { PLOG_E("Cannot convert '%s' into a IPv4 netmask", nsjconf->iface_vs_nm); - close(sock); return false; } sa->sin_family = AF_INET; sa->sin_addr = addr; if (ioctl(sock, SIOCSIFNETMASK, &ifr) == -1) { PLOG_E("ioctl(iface='%s', SIOCSIFNETMASK, '%s')", IFACE_NAME, nsjconf->iface_vs_nm); - close(sock); return false; } @@ -403,12 +396,10 @@ static bool netConfigureVs(struct nsjconf_t *nsjconf) if (inet_pton(AF_INET, nsjconf->iface_vs_gw, &addr) != 1) { PLOG_E("Cannot convert '%s' into a IPv4 GW address", nsjconf->iface_vs_gw); - close(sock); return false; } if (addr.s_addr == INADDR_ANY) { LOG_I("Gateway address for '%s' is not set", IFACE_NAME); - close(sock); return true; } @@ -430,11 +421,9 @@ static bool netConfigureVs(struct nsjconf_t *nsjconf) if (ioctl(sock, SIOCADDRT, &rt) == -1) { PLOG_E("ioctl(SIOCADDRT, '%s')", nsjconf->iface_vs_gw); - close(sock); return false; } - close(sock); return true; }