]> git.proxmox.com Git - mirror_lxc.git/commitdiff
lxc: forbid open fds upon startup
authorCedric Le Goater <clg@fr.ibm.com>
Mon, 22 Mar 2010 10:08:34 +0000 (11:08 +0100)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Mon, 22 Mar 2010 10:08:34 +0000 (11:08 +0100)
This patch modifies the startup of a container to forbid opened
fds, unless these are stdios.

Signed-off-by: Cedric Le Goater <clg@fr.ibm.com>
src/lxc/lxc_init.c
src/lxc/lxc_start.c
src/lxc/start.c
src/lxc/start.h
src/lxc/utils.c
src/lxc/utils.h

index 0230d75fb4aae862866156b4f0b3835ec211e88f..c540fc656bebaa82118a50d9fe77d914c13cff77 100644 (file)
@@ -33,9 +33,7 @@
 #define _GNU_SOURCE
 #include <getopt.h>
 
-#include <lxc/lxc.h>
 #include <lxc/log.h>
-#include <lxc/utils.h>
 #include <lxc/error.h>
 
 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;
index d1f42fe366686ee24ce9c0f9c9a7f9531ab15ff7..37f9fd8c2f3b8e24dbaf24b34d028cb0c264c544 100644 (file)
@@ -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);
index d57d027fa9ffddcfbe026cdaf50c69258c9578ab..48fffe35ca3df43b3268718efa450ba13048f5d7 100644 (file)
@@ -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");
index 3816d0cb9b500566480fc1194c2ce300a9561e66..c07e956490fcc550aa0f31d15a078450a8ac3e32 100644 (file)
@@ -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
 
index 1869c0cb7692d01d208c47f1bb785c4e462b5703..5f3745c7884f3bce7834ada3a76a6a4f5b74b8a9 100644 (file)
@@ -34,7 +34,6 @@
 #include <dirent.h>
 #include <fcntl.h>
 
-#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 */
index c49c4ffa5cbef7ec1f728164448afcd562b8a431..9fd5815b5c7bb184fb807dd0297c05b18c7b80c9 100644 (file)
@@ -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);