From b9aaab661fb879e891d34a91b5d2e78088fd9d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Gallou=C3=ABt?= Date: Thu, 14 Nov 2019 19:19:23 +0000 Subject: [PATCH] Probe run/tmp directory at runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Adrien Gallouët --- Makefile | 3 +-- src/bind.c | 11 ++++++++--- src/common.h | 4 ---- src/ctl.c | 53 ++++++++++++++++++++++++++++++++++++++++++---------- src/ctl.h | 9 +++++---- src/path.c | 2 +- src/set.c | 2 +- src/show.c | 2 +- 8 files changed, 60 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 2744661..52020cb 100644 --- a/Makefile +++ b/Makefile @@ -6,11 +6,10 @@ DESTDIR ?= CC ?= gcc INSTALL ?= install prefix ?= /usr -rundir ?= /run CFLAGS ?= -std=c11 -O2 -Wall -fstack-protector-strong FLAGS := $(CFLAGS) $(LDFLAGS) $(CPPFLAGS) -FLAGS += -DPACKAGE_NAME=\"$(NAME)\" -DPACKAGE_VERSION=\"$(VERSION)\" -DGT_RUNDIR=\"$(DESTDIR)$(rundir)/$(NAME)\" +FLAGS += -DPACKAGE_NAME=\"$(NAME)\" -DPACKAGE_VERSION=\"$(VERSION)\" FLAGS += -I.static/$(CROSS)/libsodium-stable/src/libsodium/include FLAGS += -L.static/$(CROSS)/libsodium-stable/src/libsodium/.libs diff --git a/src/bind.c b/src/bind.c index b126b0a..9c2d572 100644 --- a/src/bind.c +++ b/src/bind.c @@ -185,11 +185,16 @@ gt_bind(int argc, char **argv) } } - const int ctl_fd = ctl_create(GT_RUNDIR, tun_name); + const int ctl_fd = ctl_create(tun_name); if (ctl_fd == -1) { - gt_log("couldn't create "GT_RUNDIR"/%s: %s\n", - tun_name, strerror(errno)); + char dir[64]; + if (ctl_rundir(dir, sizeof(dir))) { + gt_log("couldn't create %s/%s: %s\n", + dir, tun_name, strerror(errno)); + } else { + gt_log("couldn't find a writable run/tmp directory\n"); + } return 1; } diff --git a/src/common.h b/src/common.h index b375ccd..4f0b0f4 100644 --- a/src/common.h +++ b/src/common.h @@ -21,10 +21,6 @@ #define PACKAGE_VERSION "0.0.0" #endif -#ifndef GT_RUNDIR -#define GT_RUNDIR "/run/" PACKAGE_NAME -#endif - #define COUNT(x) (sizeof(x)/sizeof(x[0])) #define ALIGN_SIZE (1<<4) diff --git a/src/ctl.c b/src/ctl.c index 383113d..b094862 100644 --- a/src/ctl.c +++ b/src/ctl.c @@ -5,11 +5,44 @@ #include #include #include +#include #include #include #include #include +char * +ctl_rundir(char *dst, size_t size) +{ + if (dst && size) + dst[0] = 0; + + const char *fmt[] = { + "/run/user/%u/" PACKAGE_NAME, + "/run/" PACKAGE_NAME ".%u", + "/var/run/" PACKAGE_NAME ".%u", + "/tmp/" PACKAGE_NAME ".%u", + }; + + for (int i = 0; i < COUNT(fmt); i++) { + char path[128]; + int ret = snprintf(dst, size, fmt[i], geteuid()); + + if ((ret <= 0) || + ((size_t)ret >= size) || + ((size_t)ret >= sizeof(path))) + continue; + + memcpy(path, dst, ret + 1); + + if (!access(dirname(path), W_OK)) + return dst; + } + + errno = EINTR; + return NULL; +} + int ctl_reply(int fd, struct ctl_msg *res, struct ctl_msg *req) { @@ -88,12 +121,12 @@ ctl_delete(int fd) } int -ctl_create(const char *dir, const char *file) +ctl_create(const char *file) { - if (str_empty(dir)) { - errno = EINVAL; + char dir[64]; + + if (!ctl_rundir(dir, sizeof(dir))) return -1; - } if (mkdir(dir, 0700) == -1 && errno != EEXIST) return -1; @@ -111,14 +144,13 @@ ctl_create(const char *dir, const char *file) } int -ctl_connect(const char *dir, const char *file) +ctl_connect(const char *file) { + char dir[64]; DIR *dp = NULL; - if (str_empty(dir)) { - errno = EINVAL; + if (!ctl_rundir(dir, sizeof(dir))) return -1; - } if (!file) { if (dp = opendir(dir), !dp) @@ -156,9 +188,10 @@ ctl_connect(const char *dir, const char *file) if (ret) return -1; - int fd = ctl_create(dir, NULL); + int fd = socket(AF_UNIX, SOCK_DGRAM, 0); - if (connect(fd, (struct sockaddr *)&sun, sizeof(sun))) { + if (ctl_bind(fd, dir, NULL) || + connect(fd, (struct sockaddr *)&sun, sizeof(sun))) { int err = errno; ctl_delete(fd); errno = err; diff --git a/src/ctl.h b/src/ctl.h index 291276e..42403db 100644 --- a/src/ctl.h +++ b/src/ctl.h @@ -47,7 +47,8 @@ struct ctl_msg { }; }; -int ctl_create (const char *, const char *); -int ctl_connect (const char *, const char *); -int ctl_reply (int, struct ctl_msg *, struct ctl_msg *); -void ctl_delete (int); +char *ctl_rundir (char *, size_t); +int ctl_create (const char *); +int ctl_connect (const char *); +int ctl_reply (int, struct ctl_msg *, struct ctl_msg *); +void ctl_delete (int); diff --git a/src/path.c b/src/path.c index 5903948..d294659 100644 --- a/src/path.c +++ b/src/path.c @@ -164,7 +164,7 @@ gt_path(int argc, char **argv) if (argz(pathz, argc, argv)) return 1; - int fd = ctl_connect(GT_RUNDIR, dev); + int fd = ctl_connect(dev); if (fd < 0) { switch (fd) { diff --git a/src/set.c b/src/set.c index c708d6f..e17bcb9 100644 --- a/src/set.c +++ b/src/set.c @@ -147,7 +147,7 @@ gt_set(int argc, char **argv) if (argz(pathz, argc, argv)) return 1; - int fd = ctl_connect(GT_RUNDIR, dev); + int fd = ctl_connect(dev); if (fd < 0) { switch (fd) { diff --git a/src/show.c b/src/show.c index 72a9386..7e1a21b 100644 --- a/src/show.c +++ b/src/show.c @@ -129,7 +129,7 @@ gt_show(int argc, char **argv) if (argz(showz, argc, argv)) return 1; - int fd = ctl_connect(GT_RUNDIR, dev); + int fd = ctl_connect(dev); if (fd < 0) { switch (fd) {