Quoting Christian Seiler (christ...@iwakd.de):
> Newer glibc versions (that we can't require) allow for an additional
> letter 'e' in the fopen mode that will cause the file to be opened with
> the O_CLOEXEC flag, so that it will be closed if the program exec()s
> away. This is important because if liblxc is used in a multithreaded
> program, another thread might want to run a program. This options
> prevents the leakage of file descriptors from LXC. This patch adds an
> emulation for that that uses the open(2) syscall and fdopen(3). At some
> later point in time, it may be dropped against fopen(..., "...e").
> 
> This commit also converts all fopen() calls in utils.c (where the
> function is added) to fopen_cloexec(). Subsequently, other calls to
> fopen() and open() should also be adapted.
> 
> Signed-off-by: Christian Seiler <christ...@iwakd.de>

Acked-by: Serge E. Hallyn <serge.hal...@ubuntu.com>

Though the special case for calling open() without a mode arg seems
unnecessary since when called without O_CREAT, mode is supposed to be
ignored.

> ---
>  src/lxc/utils.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++++--
>  src/lxc/utils.h |    3 +++
>  2 files changed, 51 insertions(+), 2 deletions(-)
> 
> diff --git a/src/lxc/utils.c b/src/lxc/utils.c
> index 36d80b9..b188c47 100644
> --- a/src/lxc/utils.c
> +++ b/src/lxc/utils.c
> @@ -245,7 +245,7 @@ const char *lxc_global_config_value(const char 
> *option_name)
>       if (values[i])
>               return values[i];
>  
> -     fin = fopen(LXC_GLOBAL_CONF, "r");
> +     fin = fopen_cloexec(LXC_GLOBAL_CONF, "r");
>       if (fin) {
>               while (fgets(buf, 1024, fin)) {
>                       if (buf[0] == '#')
> @@ -391,7 +391,7 @@ int sha1sum_file(char *fnam, unsigned char *digest)
>  
>       if (!fnam)
>               return -1;
> -     if ((f = fopen(fnam, "r")) < 0) {
> +     if ((f = fopen_cloexec(fnam, "r")) < 0) {
>               SYSERROR("Error opening template");
>               return -1;
>       }
> @@ -477,3 +477,49 @@ const char** lxc_va_arg_list_to_argv_const(va_list ap, 
> size_t skip)
>  {
>       return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0);
>  }
> +
> +FILE *fopen_cloexec(const char *path, const char *mode)
> +{
> +     int open_mode = 0;
> +     int step = 0;
> +     int fd;
> +     int saved_errno = 0;
> +     FILE *ret;
> +
> +     if (!strncmp(mode, "r+", 2)) {
> +             open_mode = O_RDWR;
> +             step = 2;
> +     } else if (!strncmp(mode, "r", 1)) {
> +             open_mode = O_RDONLY;
> +             step = 1;
> +     } else if (!strncmp(mode, "w+", 2)) {
> +             open_mode = O_RDWR | O_TRUNC | O_CREAT;
> +             step = 2;
> +     } else if (!strncmp(mode, "w", 1)) {
> +             open_mode = O_WRONLY | O_TRUNC | O_CREAT;
> +             step = 1;
> +     } else if (!strncmp(mode, "a+", 2)) {
> +             open_mode = O_RDWR | O_CREAT | O_APPEND;
> +             step = 2;
> +     } else if (!strncmp(mode, "a", 1)) {
> +             open_mode = O_WRONLY | O_CREAT | O_APPEND;
> +             step = 1;
> +     }
> +     for (; mode[step]; step++)
> +             if (mode[step] == 'x')
> +                     open_mode |= O_EXCL;
> +     open_mode |= O_CLOEXEC;
> +
> +     fd = (open_mode & O_CREAT) ?
> +             open(path, open_mode, 0666) :
> +             open(path, open_mode);
> +     if (fd < 0)
> +             return NULL;
> +
> +     ret = fdopen(fd, mode);
> +     saved_errno = errno;
> +     if (!ret)
> +             close(fd);
> +     errno = saved_errno;
> +     return ret;
> +}
> diff --git a/src/lxc/utils.h b/src/lxc/utils.h
> index 0ad9505..b79be44 100644
> --- a/src/lxc/utils.h
> +++ b/src/lxc/utils.h
> @@ -148,6 +148,9 @@ static inline int signalfd(int fd, const sigset_t *mask, 
> int flags)
>  }
>  #endif
>  
> +/* open a file with O_CLOEXEC */
> +FILE *fopen_cloexec(const char *path, const char *mode);
> +
>  
>  /**
>   * BUILD_BUG_ON - break compile if a condition is true.
> -- 
> 1.7.10.4
> 
> 
> ------------------------------------------------------------------------------
> Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more!
> Discover the easy way to master current and previous Microsoft technologies
> and advance your career. Get an incredible 1,500+ hours of step-by-step
> tutorial videos with LearnDevNow. Subscribe today and save!
> http://pubads.g.doubleclick.net/gampad/clk?id=58041391&iu=/4140/ostg.clktrk
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel

------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. Consolidate legacy IT systems to a single system of record for IT
2. Standardize and globalize service processes across IT
3. Implement zero-touch automation to replace manual, redundant tasks
http://pubads.g.doubleclick.net/gampad/clk?id=51271111&iu=/4140/ostg.clktrk
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to