The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/5497
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
From eab4f0aafdc812fe5fecc91bca0f910eb1555cae Mon Sep 17 00:00:00 2001 From: Christian Brauner <christian.brau...@ubuntu.com> Date: Sat, 16 Feb 2019 00:19:37 +0100 Subject: [PATCH] nsexec: make cmdline parsing more reliable Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com> --- lxd/main_nsexec.go | 81 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/lxd/main_nsexec.go b/lxd/main_nsexec.go index c03a5d24f0..770f87b90f 100644 --- a/lxd/main_nsexec.go +++ b/lxd/main_nsexec.go @@ -41,9 +41,16 @@ 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 -#define CMDLINE_SIZE (8 * PATH_MAX) -char cmdline_buf[CMDLINE_SIZE]; +char *cmdline_buf = NULL; char *cmdline_cur = NULL; ssize_t cmdline_size = -1; @@ -210,26 +217,68 @@ void attach_userns(int pid) { } } -__attribute__((constructor)) void init(void) { - int cmdline; +static ssize_t lxc_read_nointr(int fd, void *buf, size_t count) +{ + ssize_t ret; +again: + ret = read(fd, buf, count); + if (ret < 0 && errno == EINTR) + goto again; - // Extract arguments - cmdline = open("/proc/self/cmdline", O_RDONLY); - if (cmdline < 0) { - error("error: open"); - _exit(232); + return ret; +} + +static char *file_to_buf(char *path, size_t *length) +{ + int fd; + char buf[PATH_MAX]; + char *copy = NULL; + + if (!length) + return NULL; + + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd < 0) + return NULL; + + *length = 0; + for (;;) { + int n; + char *old = copy; + + n = lxc_read_nointr(fd, buf, sizeof(buf)); + if (n < 0) + goto on_error; + if (!n) + break; + + copy = realloc(old, (*length + n) * sizeof(*old)); + if (!copy) + goto on_error; + + memcpy(copy + *length, buf, n); + *length += n; } - memset(cmdline_buf, 0, sizeof(cmdline_buf)); - if ((cmdline_size = read(cmdline, cmdline_buf, sizeof(cmdline_buf)-1)) < 0) { - close(cmdline); - error("error: read"); + close(fd); + return copy; + +on_error: + close(fd); + free(copy); + + return NULL; +} + +__attribute__((constructor)) void init(void) { + __do_free char *cmdline = NULL; + + cmdline_buf = file_to_buf("/proc/self/cmdline", &cmdline_size); + if (!cmdline_buf) _exit(232); - } - close(cmdline); // Skip the first argument (but don't fail on missing second argument) - cmdline_cur = cmdline_buf; + cmdline = cmdline_cur = cmdline_buf; while (*cmdline_cur != 0) cmdline_cur++; cmdline_cur++;
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel