We want to close all inherited fds in three cases - one, if a container
is daemonized. Two, if the user specifies -C on the lxc-start command
line. Three, in src/lxc/monitor.c. The presence of -C is passed in the
lxc_conf may not always exist.
One call to lxc_check_inherited was being done from lxc_start(), which
doesn't know whether we are daemonized. Move that call to its caller,
lxcapi_start(), which does know.
Pass an explicit closeall boolean as second argument to lxc_check_inherited.
If it is true, then all fds are closed. If it is false, then we check
the lxc_conf->close_all_fds.
With this, all tests pass, and the logic appears correct.
Note that when -C is not true, then we only warn about inherited fds,
but we do not abort the container start. This appears to have ben the case
since commit
92c7f6295518 in 2011. Unfortunately the referenced URL with
the justification is no longer valid. We may want to consider becoming
stricter about this again. (Note that the commit did say "for now")
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
.quiet = quiet
};
- if (lxc_check_inherited(conf, -1))
+ if (lxc_check_inherited(conf, false, -1))
return -1;
conf->is_execute = 1;
* while container is running...
*/
if (daemonize) {
- conf->close_all_fds = 1;
lxc_monitord_spawn(c->config_path);
pid_t pid = fork();
SYSERROR("Error chdir()ing to /.");
return false;
}
- lxc_check_inherited(conf, -1);
+ lxc_check_inherited(conf, true, -1);
close(0);
close(1);
close(2);
reboot:
conf->reboot = 0;
+
+ if (lxc_check_inherited(conf, daemonize, -1)) {
+ ERROR("Inherited fds found");
+ ret = 1;
+ goto out;
+ }
+
ret = lxc_start(c->name, argv, conf, c->config_path);
c->error_num = ret;
goto reboot;
}
+out:
if (c->pidfile) {
unlink(c->pidfile);
free(c->pidfile);
SYSERROR("failed to setsid");
exit(EXIT_FAILURE);
}
- lxc_check_inherited(NULL, pipefd[1]);
+ lxc_check_inherited(NULL, true, pipefd[1]);
close(0);
close(1);
close(2);
return (fd == 0 || fd == 1 || fd == 2);
}
-int lxc_check_inherited(struct lxc_conf *conf, int fd_to_ignore)
+/*
+ * Check for any fds we need to close
+ * * if fd_to_ignore != -1, then if we find that fd open we will ignore it.
+ * * By default we warn about open fds we find.
+ * * If closeall is true, we will close open fds.
+ * * If lxc-start was passed "-C", then conf->close_all_fds will be true,
+ * in which case we also close all open fds.
+ * * A daemonized container will always pass closeall=true.
+ */
+int lxc_check_inherited(struct lxc_conf *conf, bool closeall, int fd_to_ignore)
{
struct dirent dirent, *direntp;
int fd, fddir;
DIR *dir;
+ if (conf && conf->close_all_fds)
+ closeall = true;
+
restart:
dir = opendir("/proc/self/fd");
if (!dir) {
if (match_fd(fd))
continue;
- if (conf == NULL || conf->close_all_fds) {
+ if (closeall) {
close(fd);
closedir(dir);
INFO("closed inherited fd %d", fd);
.argv = argv,
};
- if (lxc_check_inherited(conf, -1))
- return -1;
-
conf->need_utmp_watch = 1;
return __lxc_start(name, conf, &start_ops, &start_arg, lxcpath);
}
#include <signal.h>
#include <sys/param.h>
+#include <stdbool.h>
#include "config.h"
#include "state.h"
extern struct lxc_handler *lxc_init(const char *name, struct lxc_conf *, const char *);
extern void lxc_fini(const char *name, struct lxc_handler *handler);
-extern int lxc_check_inherited(struct lxc_conf *conf, int fd_to_ignore);
+extern int lxc_check_inherited(struct lxc_conf *conf, bool closeall, int fd_to_ignore);
int __lxc_start(const char *, struct lxc_conf *, struct lxc_operations *,
void *, const char *);