mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-27 10:51:24 +00:00
Add fopen_cloexec function to emulate 'e' mode
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 <christian@iwakd.de> Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
parent
6e16552de7
commit
db27c8d70e
@ -245,7 +245,7 @@ const char *lxc_global_config_value(const char *option_name)
|
|||||||
if (values[i])
|
if (values[i])
|
||||||
return values[i];
|
return values[i];
|
||||||
|
|
||||||
fin = fopen(LXC_GLOBAL_CONF, "r");
|
fin = fopen_cloexec(LXC_GLOBAL_CONF, "r");
|
||||||
if (fin) {
|
if (fin) {
|
||||||
while (fgets(buf, 1024, fin)) {
|
while (fgets(buf, 1024, fin)) {
|
||||||
if (buf[0] == '#')
|
if (buf[0] == '#')
|
||||||
@ -391,7 +391,7 @@ int sha1sum_file(char *fnam, unsigned char *digest)
|
|||||||
|
|
||||||
if (!fnam)
|
if (!fnam)
|
||||||
return -1;
|
return -1;
|
||||||
if ((f = fopen(fnam, "r")) < 0) {
|
if ((f = fopen_cloexec(fnam, "r")) < 0) {
|
||||||
SYSERROR("Error opening template");
|
SYSERROR("Error opening template");
|
||||||
return -1;
|
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);
|
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;
|
||||||
|
}
|
||||||
|
@ -148,6 +148,9 @@ static inline int signalfd(int fd, const sigset_t *mask, int flags)
|
|||||||
}
|
}
|
||||||
#endif
|
#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.
|
* BUILD_BUG_ON - break compile if a condition is true.
|
||||||
|
Loading…
Reference in New Issue
Block a user