Merge pull request #2171 from brauner/2018-02-16/rework_hooks

conf: fix run_script_argv()
This commit is contained in:
Serge Hallyn 2018-02-16 18:51:56 -06:00 committed by GitHub
commit 3d7868ae53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 40 deletions

View File

@ -354,10 +354,11 @@ static int run_buffer(char *buffer)
int run_script_argv(const char *name, unsigned int hook_version, int run_script_argv(const char *name, unsigned int hook_version,
const char *section, const char *script, const char *section, const char *script,
const char *hookname, char **argsin) const char *hookname, char **argv)
{ {
int buf_pos, i, ret; int buf_pos, i, ret;
char *buffer; char *buffer;
int fret = -1;
size_t size = 0; size_t size = 0;
if (hook_version == 0) if (hook_version == 0)
@ -366,8 +367,8 @@ int run_script_argv(const char *name, unsigned int hook_version,
else else
INFO("Executing script \"%s\" for container \"%s\"", script, name); INFO("Executing script \"%s\" for container \"%s\"", script, name);
for (i = 0; argsin && argsin[i]; i++) for (i = 0; argv && argv[i]; i++)
size += strlen(argsin[i]) + 1; size += strlen(argv[i]) + 1;
size += sizeof("exec"); size += sizeof("exec");
size += strlen(script); size += strlen(script);
@ -376,8 +377,6 @@ int run_script_argv(const char *name, unsigned int hook_version,
if (size > INT_MAX) if (size > INT_MAX)
return -EFBIG; return -EFBIG;
buffer = alloca(size);
if (hook_version == 0) { if (hook_version == 0) {
size += strlen(hookname); size += strlen(hookname);
size++; size++;
@ -390,24 +389,27 @@ int run_script_argv(const char *name, unsigned int hook_version,
if (size > INT_MAX) if (size > INT_MAX)
return -EFBIG; return -EFBIG;
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;
} }
} else {
buffer = malloc(size);
if (!buffer)
return -ENOMEM;
if (hook_version == 0)
buf_pos = snprintf(buffer, size, "exec %s %s %s %s", script, name, section, hookname);
else
buf_pos = snprintf(buffer, size, "exec %s", script); buf_pos = snprintf(buffer, size, "exec %s", script);
if (buf_pos < 0 || (size_t)buf_pos >= size) { if (buf_pos < 0 || (size_t)buf_pos >= size) {
ERROR("Failed to create command line for script \"%s\"", script); ERROR("Failed to create command line for script \"%s\"", script);
return -1; goto on_error;
} }
if (hook_version == 1) {
ret = setenv("LXC_HOOK_TYPE", hookname, 1); ret = setenv("LXC_HOOK_TYPE", hookname, 1);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set environment variable: " SYSERROR("Failed to set environment variable: "
"LXC_HOOK_TYPE=%s", hookname); "LXC_HOOK_TYPE=%s", hookname);
return -1; goto on_error;
} }
TRACE("Set environment variable: LXC_HOOK_TYPE=%s", hookname); TRACE("Set environment variable: LXC_HOOK_TYPE=%s", hookname);
@ -415,50 +417,50 @@ int run_script_argv(const char *name, unsigned int hook_version,
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set environment variable: " SYSERROR("Failed to set environment variable: "
"LXC_HOOK_SECTION=%s", section); "LXC_HOOK_SECTION=%s", section);
return -1; goto on_error;
} }
TRACE("Set environment variable: LXC_HOOK_SECTION=%s", section); TRACE("Set environment variable: LXC_HOOK_SECTION=%s", section);
if (strcmp(section, "net") == 0) { if (strcmp(section, "net") == 0) {
char *parent; char *parent;
if (!argsin[0]) if (!argv || !argv[0])
return -EINVAL; goto on_error;
ret = setenv("LXC_NET_TYPE", argsin[0], 1); ret = setenv("LXC_NET_TYPE", argv[0], 1);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set environment variable: " SYSERROR("Failed to set environment variable: "
"LXC_NET_TYPE=%s", argsin[0]); "LXC_NET_TYPE=%s", argv[0]);
return -1; 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); ret = setenv("LXC_NET_PARENT", parent, 1);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set environment " SYSERROR("Failed to set environment "
"variable: LXC_NET_PARENT=%s", parent); "variable: LXC_NET_PARENT=%s", parent);
return -1; goto on_error;
} }
TRACE("Set environment variable: LXC_NET_PARENT=%s", parent); 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); ret = setenv("LXC_NET_PARENT", parent, 1);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set environment " SYSERROR("Failed to set environment "
"variable: LXC_NET_PARENT=%s", parent); "variable: LXC_NET_PARENT=%s", parent);
return -1; goto on_error;
} }
TRACE("Set environment variable: LXC_NET_PARENT=%s", parent); TRACE("Set environment variable: LXC_NET_PARENT=%s", parent);
} else if (strcmp(argsin[0], "veth")) { } else if (strcmp(argv[0], "veth")) {
char *peer = argsin[2] ? argsin[2] : ""; char *peer = argv[2] ? argv[2] : "";
ret = setenv("LXC_NET_PEER", peer, 1); ret = setenv("LXC_NET_PEER", peer, 1);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set environment " SYSERROR("Failed to set environment "
"variable: LXC_NET_PEER=%s", peer); "variable: LXC_NET_PEER=%s", peer);
return -1; goto on_error;
} }
TRACE("Set environment variable: LXC_NET_PEER=%s", peer); TRACE("Set environment variable: LXC_NET_PEER=%s", peer);
@ -466,25 +468,29 @@ int run_script_argv(const char *name, unsigned int hook_version,
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set environment " SYSERROR("Failed to set environment "
"variable: LXC_NET_PARENT=%s", parent); "variable: LXC_NET_PARENT=%s", parent);
return -1; goto on_error;
} }
TRACE("Set environment variable: LXC_NET_PARENT=%s", parent); 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; 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) { if (ret < 0 || (size_t)ret >= len) {
ERROR("Failed to create command line for script \"%s\"", script); ERROR("Failed to create command line for script \"%s\"", script);
return -1; goto on_error;
} }
buf_pos += ret; buf_pos += ret;
} }
return run_buffer(buffer); fret = run_buffer(buffer);
on_error:
free(buffer);
return fret;
} }
int run_script(const char *name, const char *section, const char *script, ...) int run_script(const char *name, const char *section, const char *script, ...)

View File

@ -215,16 +215,20 @@ int lxc_console_cb_con(int fd, uint32_t events, void *data,
if (r <= 0) { if (r <= 0) {
INFO("Console client on fd %d has exited", fd); INFO("Console client on fd %d has exited", fd);
lxc_mainloop_del_handler(descr, fd); lxc_mainloop_del_handler(descr, fd);
if (fd == console->peer) {
if (fd == console->master) {
console->master = -EBADF;
} else if (fd == console->peer) {
if (console->tty_state) { if (console->tty_state) {
lxc_console_signal_fini(console->tty_state); lxc_console_signal_fini(console->tty_state);
console->tty_state = NULL; console->tty_state = NULL;
} }
console->peer = -1; console->peer = -EBADF;
close(fd); } else {
return 0; ERROR("Handler received unexpected file descriptor");
} }
close(fd); close(fd);
return LXC_MAINLOOP_CLOSE; return LXC_MAINLOOP_CLOSE;
} }

View File

@ -628,7 +628,7 @@ void lxc_free_handler(struct lxc_handler *handler)
lxc_put_nsfds(handler); lxc_put_nsfds(handler);
if (handler->conf && handler->conf->reboot == 0) if (handler->conf && handler->conf->reboot == 0)
if (handler->conf->maincmd_fd) if (handler->conf->maincmd_fd >= 0)
close(handler->conf->maincmd_fd); close(handler->conf->maincmd_fd);
if (handler->state_socket_pair[0] >= 0) if (handler->state_socket_pair[0] >= 0)