Commit 6c8ea604 authored by Andrei Vagin's avatar Andrei Vagin

util: don't leak file descriprots to third-party tools

https://github.com/containers/container-selinux/issues/68
Cc: Adrian Reber <areber@redhat.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@gmail.com>
parent b548ed94
...@@ -382,7 +382,6 @@ int collect_binfmt_misc(void) ...@@ -382,7 +382,6 @@ int collect_binfmt_misc(void)
static int tmpfs_dump(struct mount_info *pm) static int tmpfs_dump(struct mount_info *pm)
{ {
int ret = -1, fd = -1, userns_pid = -1; int ret = -1, fd = -1, userns_pid = -1;
char tmpfs_path[PSFDS];
struct cr_img *img; struct cr_img *img;
int tmp_fds[3], ntmp_fds = 0, i; int tmp_fds[3], ntmp_fds = 0, i;
...@@ -417,12 +416,10 @@ static int tmpfs_dump(struct mount_info *pm) ...@@ -417,12 +416,10 @@ static int tmpfs_dump(struct mount_info *pm)
if (!img) if (!img)
goto out; goto out;
sprintf(tmpfs_path, "/proc/self/fd/%d", fd);
if (root_ns_mask & CLONE_NEWUSER) if (root_ns_mask & CLONE_NEWUSER)
userns_pid = root_item->pid->real; userns_pid = root_item->pid->real;
ret = cr_system_userns(-1, img_raw_fd(img), -1, "tar", (char *[]) ret = cr_system_userns(fd, img_raw_fd(img), -1, "tar", (char *[])
{ "tar", "--create", { "tar", "--create",
"--gzip", "--gzip",
"--no-unquote", "--no-unquote",
...@@ -432,7 +429,7 @@ static int tmpfs_dump(struct mount_info *pm) ...@@ -432,7 +429,7 @@ static int tmpfs_dump(struct mount_info *pm)
"--preserve-permissions", "--preserve-permissions",
"--sparse", "--sparse",
"--numeric-owner", "--numeric-owner",
"--directory", tmpfs_path, ".", NULL }, 0, userns_pid); "--directory", "/proc/self/fd/0", ".", NULL }, 0, userns_pid);
if (ret) if (ret)
pr_err("Can't dump tmpfs content\n"); pr_err("Can't dump tmpfs content\n");
......
...@@ -493,6 +493,37 @@ int cr_system(int in, int out, int err, char *cmd, char *const argv[], unsigned ...@@ -493,6 +493,37 @@ int cr_system(int in, int out, int err, char *cmd, char *const argv[], unsigned
return cr_system_userns(in, out, err, cmd, argv, flags, -1); return cr_system_userns(in, out, err, cmd, argv, flags, -1);
} }
static int close_fds(int minfd)
{
DIR *dir;
struct dirent *de;
int fd, ret, dfd;
dir = opendir("/proc/self/fd");
if (dir == NULL)
pr_perror("Can't open /proc/self/fd");
dfd = dirfd(dir);
while ((de = readdir(dir))) {
if (dir_dots(de))
continue;
ret = sscanf(de->d_name, "%d", &fd);
if (ret != 1) {
pr_err("Can't parse %s\n", de->d_name);
return -1;
}
if (dfd == fd)
continue;
if (fd < minfd)
continue;
close(fd);
}
closedir(dir);
return 0;
}
int cr_system_userns(int in, int out, int err, char *cmd, int cr_system_userns(int in, int out, int err, char *cmd,
char *const argv[], unsigned flags, int userns_pid) char *const argv[], unsigned flags, int userns_pid)
{ {
...@@ -556,6 +587,8 @@ int cr_system_userns(int in, int out, int err, char *cmd, ...@@ -556,6 +587,8 @@ int cr_system_userns(int in, int out, int err, char *cmd,
if (reopen_fd_as_nocheck(STDERR_FILENO, err)) if (reopen_fd_as_nocheck(STDERR_FILENO, err))
goto out_chld; goto out_chld;
close_fds(STDERR_FILENO + 1);
execvp(cmd, argv); execvp(cmd, argv);
pr_perror("exec(%s, ...) failed", cmd); pr_perror("exec(%s, ...) failed", cmd);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment