tools: fix container use-after-free

Fields daemonize and error_num were being called after the
lxc_container_put.

Signed-off-by: Felix Abecassis <fabecassis@nvidia.com>
This commit is contained in:
Felix Abecassis 2018-03-16 13:31:25 -07:00
parent 4edd0ba7fe
commit 020c90b702

View File

@ -138,16 +138,17 @@ int main(int argc, char *argv[])
{ {
struct lxc_container *c; struct lxc_container *c;
struct lxc_log log; struct lxc_log log;
int err = EXIT_FAILURE;
int ret; int ret;
bool bret; bool bret;
lxc_list_init(&defines); lxc_list_init(&defines);
if (lxc_caps_init()) if (lxc_caps_init())
exit(EXIT_FAILURE); exit(err);
if (lxc_arguments_parse(&my_args, argc, argv)) if (lxc_arguments_parse(&my_args, argc, argv))
exit(EXIT_FAILURE); exit(err);
log.name = my_args.name; log.name = my_args.name;
log.file = my_args.log_file; log.file = my_args.log_file;
@ -157,102 +158,89 @@ int main(int argc, char *argv[])
log.lxcpath = my_args.lxcpath[0]; log.lxcpath = my_args.lxcpath[0];
if (lxc_log_init(&log)) if (lxc_log_init(&log))
exit(EXIT_FAILURE); exit(err);
c = lxc_container_new(my_args.name, my_args.lxcpath[0]); c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
if (!c) { if (!c) {
fprintf(stderr, "Failed to create lxc_container\n"); fprintf(stderr, "Failed to create lxc_container\n");
exit(EXIT_FAILURE); exit(err);
} }
if (my_args.rcfile) { if (my_args.rcfile) {
c->clear_config(c); c->clear_config(c);
if (!c->load_config(c, my_args.rcfile)) { if (!c->load_config(c, my_args.rcfile)) {
fprintf(stderr, "Failed to load rcfile\n"); fprintf(stderr, "Failed to load rcfile\n");
lxc_container_put(c); goto out;
exit(EXIT_FAILURE);
} }
c->configfile = strdup(my_args.rcfile); c->configfile = strdup(my_args.rcfile);
if (!c->configfile) { if (!c->configfile) {
fprintf(stderr, "Out of memory setting new config filename\n"); fprintf(stderr, "Out of memory setting new config filename\n");
lxc_container_put(c); goto out;
exit(EXIT_FAILURE);
} }
} }
if (!c->lxc_conf) { if (!c->lxc_conf) {
fprintf(stderr, "Executing a container with no configuration file may crash the host\n"); fprintf(stderr, "Executing a container with no configuration file may crash the host\n");
lxc_container_put(c); goto out;
exit(EXIT_FAILURE);
} }
if (my_args.argc == 0) { if (my_args.argc == 0) {
if (!set_argv(c, &my_args)) { if (!set_argv(c, &my_args)) {
fprintf(stderr, "missing command to execute!\n"); fprintf(stderr, "missing command to execute!\n");
lxc_container_put(c); goto out;
exit(EXIT_FAILURE);
} }
} }
bret = lxc_config_define_load(&defines, c); bret = lxc_config_define_load(&defines, c);
if (!bret) { if (!bret)
lxc_container_put(c); goto out;
exit(EXIT_FAILURE);
}
if (my_args.uid) { if (my_args.uid) {
char buf[256]; char buf[256];
ret = snprintf(buf, 256, "%d", my_args.uid); ret = snprintf(buf, 256, "%d", my_args.uid);
if (ret < 0 || (size_t)ret >= 256) { if (ret < 0 || (size_t)ret >= 256)
lxc_container_put(c); goto out;
exit(EXIT_FAILURE);
}
bret = c->set_config_item(c, "lxc.init.uid", buf); bret = c->set_config_item(c, "lxc.init.uid", buf);
if (!bret) { if (!bret)
lxc_container_put(c); goto out;
exit(EXIT_FAILURE);
}
} }
if (my_args.gid) { if (my_args.gid) {
char buf[256]; char buf[256];
ret = snprintf(buf, 256, "%d", my_args.gid); ret = snprintf(buf, 256, "%d", my_args.gid);
if (ret < 0 || (size_t)ret >= 256) { if (ret < 0 || (size_t)ret >= 256)
lxc_container_put(c); goto out;
exit(EXIT_FAILURE);
}
bret = c->set_config_item(c, "lxc.init.gid", buf); bret = c->set_config_item(c, "lxc.init.gid", buf);
if (!bret) { if (!bret)
lxc_container_put(c); goto out;
exit(EXIT_FAILURE);
}
} }
if (!lxc_setup_shared_ns(&my_args, c)) { if (!lxc_setup_shared_ns(&my_args, c))
lxc_container_put(c); goto out;
exit(EXIT_FAILURE);
}
c->daemonize = my_args.daemonize == 1; c->daemonize = my_args.daemonize == 1;
bret = c->start(c, 1, my_args.argv); bret = c->start(c, 1, my_args.argv);
lxc_container_put(c);
if (!bret) { if (!bret) {
fprintf(stderr, "Failed run an application inside container\n"); fprintf(stderr, "Failed run an application inside container\n");
exit(EXIT_FAILURE); goto out;
} }
if (c->daemonize) if (c->daemonize) {
exit(EXIT_SUCCESS); err = EXIT_SUCCESS;
else { } else {
if (WIFEXITED(c->error_num)) { if (WIFEXITED(c->error_num)) {
exit(WEXITSTATUS(c->error_num)); err = WEXITSTATUS(c->error_num);
} else { } else {
/* Try to die with the same signal the task did. */ /* Try to die with the same signal the task did. */
kill(0, WTERMSIG(c->error_num)); kill(0, WTERMSIG(c->error_num));
exit(EXIT_FAILURE);
} }
} }
out:
lxc_container_put(c);
exit(err);
} }