From 80090207defda9adfc922555b359b11acdad1401 Mon Sep 17 00:00:00 2001 From: Cedric Le Goater Date: Mon, 22 Mar 2010 11:08:34 +0100 Subject: [PATCH] lxc: forbid open fds upon startup This patch modifies the startup of a container to forbid opened fds, unless these are stdios. Signed-off-by: Cedric Le Goater --- src/lxc/lxc_init.c | 8 --- src/lxc/lxc_start.c | 6 +-- src/lxc/start.c | 67 ++++++++++++++++++++--- src/lxc/start.h | 1 + src/lxc/utils.c | 126 -------------------------------------------- src/lxc/utils.h | 2 - 6 files changed, 65 insertions(+), 145 deletions(-) diff --git a/src/lxc/lxc_init.c b/src/lxc/lxc_init.c index 0230d75fb..c540fc656 100644 --- a/src/lxc/lxc_init.c +++ b/src/lxc/lxc_init.c @@ -33,9 +33,7 @@ #define _GNU_SOURCE #include -#include #include -#include #include lxc_log_define(lxc_init, lxc); @@ -100,12 +98,6 @@ int main(int argc, char *argv[]) exit(err); } - err = lxc_close_all_inherited_fd(); - if (err) { - ERROR("unable to close inherited fds"); - goto out; - } - err = 0; for (;;) { int status; diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c index d1f42fe36..37f9fd8c2 100644 --- a/src/lxc/lxc_start.c +++ b/src/lxc/lxc_start.c @@ -163,9 +163,9 @@ int main(int argc, char *argv[]) return err; } - lxc_close_inherited_fd(0); - lxc_close_inherited_fd(1); - lxc_close_inherited_fd(2); + close(0); + close(1); + close(2); if (my_args.log_file) { open(my_args.log_file, O_WRONLY | O_CLOEXEC); diff --git a/src/lxc/start.c b/src/lxc/start.c index d57d027fa..48fffe35c 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -106,6 +106,64 @@ lxc_log_define(lxc_start, lxc); LXC_TTY_HANDLER(SIGINT); LXC_TTY_HANDLER(SIGQUIT); +static int match_fd(int fd) +{ + return (fd == 0 || fd == 1 || fd == 2); +} + +int lxc_check_inherited(void) +{ + struct dirent dirent, *direntp; + int fd, fddir; + DIR *dir; + int ret = 0; + + dir = opendir("/proc/self/fd"); + if (!dir) { + WARN("failed to open directory: %m"); + return -1; + } + + fddir = dirfd(dir); + + while (!readdir_r(dir, &dirent, &direntp)) { + char procpath[64]; + char path[PATH_MAX]; + + if (!direntp) + break; + + if (!strcmp(direntp->d_name, ".")) + continue; + + if (!strcmp(direntp->d_name, "..")) + continue; + + fd = atoi(direntp->d_name); + + if (fd == fddir || fd == lxc_log_fd) + continue; + + if (match_fd(fd)) + continue; + /* + * found inherited fd + */ + ret = -1; + + snprintf(procpath, sizeof(procpath), "/proc/self/fd/%d", fd); + + if (readlink(procpath, path, sizeof(path)) == -1) + ERROR("readlink(%s) failed : %m", procpath); + else + ERROR("inherited fd %d on %s", fd, path); + } + + if (closedir(dir)) + ERROR("failed to close directory"); + return ret; +} + static int setup_sigchld_fd(sigset_t *oldmask) { sigset_t mask; @@ -432,6 +490,9 @@ int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf) int err = -1; int status; + if (lxc_check_inherited()) + return -1; + handler = lxc_init(name, conf); if (!handler) { ERROR("failed to initialize the container"); @@ -444,12 +505,6 @@ int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf) goto out_fini; } - err = lxc_close_all_inherited_fd(); - if (err) { - ERROR("unable to close inherited fds"); - goto out_abort; - } - err = lxc_poll(name, handler); if (err) { ERROR("mainloop exited with an error"); diff --git a/src/lxc/start.h b/src/lxc/start.h index 3816d0cb9..c07e95649 100644 --- a/src/lxc/start.h +++ b/src/lxc/start.h @@ -45,6 +45,7 @@ extern int lxc_poll(const char *name, struct lxc_handler *handler); extern void lxc_abort(const char *name, struct lxc_handler *handler); extern void lxc_fini(const char *name, struct lxc_handler *handler); extern int lxc_set_state(const char *, struct lxc_handler *, lxc_state_t); +extern int lxc_check_inherited(void); #endif diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 1869c0cb7..5f3745c78 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -34,7 +34,6 @@ #include #include -#include "list.h" #include "log.h" lxc_log_define(lxc_utils, lxc); @@ -110,131 +109,6 @@ err: goto out_mmap; } -struct lxc_fd_entry { - int fd; - struct lxc_list list; -}; - -struct lxc_list lxc_fd_list; - -static int fd_list_add(int fd) -{ - struct lxc_fd_entry *entry; - - entry = malloc(sizeof(struct lxc_fd_entry)); - if (!entry) { - SYSERROR("malloc"); - return -1; - } - - entry->fd = fd; - entry->list.elem = entry; - lxc_list_add(&lxc_fd_list, &entry->list); - - return 0; -} - -static void fd_list_del(struct lxc_fd_entry *entry) -{ - lxc_list_del(&entry->list); - free(entry); -} - -static void __attribute__((constructor)) __lxc_fd_collect_inherited(void) -{ - struct dirent dirent, *direntp; - int fd, fddir; - DIR *dir; - - lxc_list_init(&lxc_fd_list); - - dir = opendir("/proc/self/fd"); - if (!dir) { - WARN("failed to open directory: %s", strerror(errno)); - return; - } - - fddir = dirfd(dir); - - while (!readdir_r(dir, &dirent, &direntp)) { - - if (!direntp) - break; - - if (!strcmp(direntp->d_name, ".")) - continue; - - if (!strcmp(direntp->d_name, "..")) - continue; - - fd = atoi(direntp->d_name); - - if (fd == fddir) - continue; - - if (fd_list_add(fd)) - WARN("failed to add fd '%d' to the list", fd); - } - - if (closedir(dir)) - WARN("failed to close directory"); -} - -int lxc_close_inherited_fd(int fd) -{ - struct lxc_fd_entry *entry; - struct lxc_list *iterator; - - lxc_list_for_each(iterator, &lxc_fd_list) { - - entry = iterator->elem; - - if (entry->fd != fd) - continue; - - fd_list_del(entry); - - break; - } - - DEBUG("closing fd '%d'", fd); - - return close(fd); -} - -int lxc_close_all_inherited_fd(void) -{ - struct lxc_fd_entry *entry; - struct lxc_list *iterator; - -again: - lxc_list_for_each(iterator, &lxc_fd_list) { - - entry = iterator->elem; - - /* do not close the stderr fd to keep open default - * error reporting path. - */ - if (entry->fd == 2 && isatty(entry->fd)) { - fd_list_del(entry); - continue; - } - - DEBUG("closing fd '%d'", entry->fd); - - if (close(entry->fd)) - WARN("failed to close fd '%d': %s", entry->fd, - strerror(errno)); - - fd_list_del(entry); - goto again; - } - - DEBUG("closed all inherited file descriptors"); - - return 0; -} - static int mount_fs(const char *source, const char *target, const char *type) { /* the umount may fail */ diff --git a/src/lxc/utils.h b/src/lxc/utils.h index c49c4ffa5..9fd5815b5 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -51,7 +51,5 @@ #endif extern int lxc_copy_file(const char *src, const char *dst); -extern int lxc_close_inherited_fd(int fd); -extern int lxc_close_all_inherited_fd(void); extern int lxc_setup_fs(void); extern int get_u16(ushort *val, const char *arg, int base); -- 2.47.2