[lxc-devel] [lxc/master] conf: fix run_script_argv()
brauner on Github
lxc-bot at linuxcontainers.org
Fri Feb 16 21:00:11 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 488 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180216/978c7b5c/attachment.bin>
-------------- next part --------------
From 920bafdb1b3377b799a2f6f5a716113ce55f64f3 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 16 Feb 2018 21:48:09 +0100
Subject: [PATCH] conf: fix run_script_argv()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This fixes a SIGBUS/SIGSEGV Stéphane reported on aarch64 and armf.
Reported-by: Stéphane Graber <stgraber at ubuntu.com>
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/conf.c | 66 ++++++++++++++++++++++++++++++++++------------------------
1 file changed, 39 insertions(+), 27 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index f75d69656..d42024068 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -354,7 +354,7 @@ static int run_buffer(char *buffer)
int run_script_argv(const char *name, unsigned int hook_version,
const char *section, const char *script,
- const char *hookname, char **argsin)
+ const char *hookname, char **argv)
{
int buf_pos, i, ret;
char *buffer;
@@ -366,8 +366,8 @@ int run_script_argv(const char *name, unsigned int hook_version,
else
INFO("Executing script \"%s\" for container \"%s\"", script, name);
- for (i = 0; argsin && argsin[i]; i++)
- size += strlen(argsin[i]) + 1;
+ for (i = 0; argv && argv[i]; i++)
+ size += strlen(argv[i]) + 1;
size += sizeof("exec");
size += strlen(script);
@@ -376,8 +376,6 @@ int run_script_argv(const char *name, unsigned int hook_version,
if (size > INT_MAX)
return -EFBIG;
- buffer = alloca(size);
-
if (hook_version == 0) {
size += strlen(hookname);
size++;
@@ -389,14 +387,22 @@ int run_script_argv(const char *name, unsigned int hook_version,
size++;
if (size > INT_MAX)
- return -EFBIG;
+ goto on_error;
+
+ buffer = malloc(size);
+ if (!buffer)
+ return -ENOMEM;
buf_pos = snprintf(buffer, size, "exec %s %s %s %s", script, name, section, hookname);
if (buf_pos < 0 || (size_t)buf_pos >= size) {
ERROR("Failed to create command line for script \"%s\"", script);
- return -1;
+ goto on_error;
}
} else {
+ buffer = malloc(size);
+ if (!buffer)
+ return -ENOMEM;
+
buf_pos = snprintf(buffer, size, "exec %s", script);
if (buf_pos < 0 || (size_t)buf_pos >= size) {
ERROR("Failed to create command line for script \"%s\"", script);
@@ -407,7 +413,7 @@ int run_script_argv(const char *name, unsigned int hook_version,
if (ret < 0) {
SYSERROR("Failed to set environment variable: "
"LXC_HOOK_TYPE=%s", hookname);
- return -1;
+ goto on_error;
}
TRACE("Set environment variable: LXC_HOOK_TYPE=%s", hookname);
@@ -415,50 +421,50 @@ int run_script_argv(const char *name, unsigned int hook_version,
if (ret < 0) {
SYSERROR("Failed to set environment variable: "
"LXC_HOOK_SECTION=%s", section);
- return -1;
+ goto on_error;
}
TRACE("Set environment variable: LXC_HOOK_SECTION=%s", section);
if (strcmp(section, "net") == 0) {
char *parent;
- if (!argsin[0])
+ if (!argv || !argv[0])
return -EINVAL;
- ret = setenv("LXC_NET_TYPE", argsin[0], 1);
+ ret = setenv("LXC_NET_TYPE", argv[0], 1);
if (ret < 0) {
SYSERROR("Failed to set environment variable: "
- "LXC_NET_TYPE=%s", argsin[0]);
- return -1;
+ "LXC_NET_TYPE=%s", argv[0]);
+ goto on_error;
}
- TRACE("Set environment variable: LXC_NET_TYPE=%s", argsin[0]);
+ TRACE("Set environment variable: LXC_NET_TYPE=%s", argv[0]);
- parent = argsin[1] ? argsin[1] : "";
+ parent = argv[1] ? argv[1] : "";
- if (strcmp(argsin[0], "macvlan")) {
+ if (strcmp(argv[0], "macvlan")) {
ret = setenv("LXC_NET_PARENT", parent, 1);
if (ret < 0) {
SYSERROR("Failed to set environment "
"variable: LXC_NET_PARENT=%s", parent);
- return -1;
+ goto on_error;
}
TRACE("Set environment variable: LXC_NET_PARENT=%s", parent);
- } else if (strcmp(argsin[0], "phys")) {
+ } else if (strcmp(argv[0], "phys")) {
ret = setenv("LXC_NET_PARENT", parent, 1);
if (ret < 0) {
SYSERROR("Failed to set environment "
"variable: LXC_NET_PARENT=%s", parent);
- return -1;
+ goto on_error;
}
TRACE("Set environment variable: LXC_NET_PARENT=%s", parent);
- } else if (strcmp(argsin[0], "veth")) {
- char *peer = argsin[2] ? argsin[2] : "";
+ } else if (strcmp(argv[0], "veth")) {
+ char *peer = argv[2] ? argv[2] : "";
ret = setenv("LXC_NET_PEER", peer, 1);
if (ret < 0) {
SYSERROR("Failed to set environment "
"variable: LXC_NET_PEER=%s", peer);
- return -1;
+ goto on_error;
}
TRACE("Set environment variable: LXC_NET_PEER=%s", peer);
@@ -466,25 +472,31 @@ int run_script_argv(const char *name, unsigned int hook_version,
if (ret < 0) {
SYSERROR("Failed to set environment "
"variable: LXC_NET_PARENT=%s", parent);
- return -1;
+ goto on_error;
}
TRACE("Set environment variable: LXC_NET_PARENT=%s", parent);
}
}
}
- for (i = 0; argsin && argsin[i]; i++) {
+ for (i = 0; argv && argv[i]; i++) {
size_t len = size - buf_pos;
- ret = snprintf(buffer + buf_pos, len, " %s", argsin[i]);
+ ret = snprintf(buffer + buf_pos, len, " %s", argv[i]);
if (ret < 0 || (size_t)ret >= len) {
ERROR("Failed to create command line for script \"%s\"", script);
- return -1;
+ goto on_error;
}
buf_pos += ret;
}
- return run_buffer(buffer);
+ ret = run_buffer(buffer);
+ free(buffer);
+ return 0;
+
+on_error:
+ free(buffer);
+ return -1;
}
int run_script(const char *name, const char *section, const char *script, ...)
More information about the lxc-devel
mailing list