[lxc-devel] [lxd/master] nsexec: make cmdline parsing more reliable
brauner on Github
lxc-bot at linuxcontainers.org
Fri Feb 15 23:21:01 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/20190215/78ba5053/attachment.bin>
-------------- next part --------------
From eab4f0aafdc812fe5fecc91bca0f910eb1555cae Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at 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.brauner at 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++;
More information about the lxc-devel
mailing list