From 4efbd78c7438aa5b869103ef9fe24f7035b984ba Mon Sep 17 00:00:00 2001 From: smitsohu Date: Wed, 12 Jan 2022 18:25:11 +0100 Subject: [PATCH] refactor closing of file descriptors --- src/firejail/dbus.c | 11 +++++----- src/firejail/firejail.h | 2 +- src/firejail/sbox.c | 7 ++----- src/firejail/util.c | 46 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/firejail/dbus.c b/src/firejail/dbus.c index e1475870cc2..12256b833d9 100644 --- a/src/firejail/dbus.c +++ b/src/firejail/dbus.c @@ -297,11 +297,12 @@ void dbus_proxy_start(void) { if (dbus_proxy_pid == -1) errExit("fork"); if (dbus_proxy_pid == 0) { - int i; - for (i = STDERR_FILENO + 1; i < FIREJAIL_MAX_FD; i++) { - if (i != status_pipe[1] && i != args_pipe[0]) - close(i); // close open files - } + // close open files + int keep_list[2]; + keep_list[0] = status_pipe[1]; + keep_list[1] = args_pipe[0]; + close_all(keep_list, ARRAY_SIZE(keep_list)); + if (arg_dbus_log_file != NULL) { int output_fd = creat(arg_dbus_log_file, 0666); if (output_fd < 0) diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 7529256d037..7314c535087 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -551,6 +551,7 @@ int remount_by_fd(int dst, unsigned long mountflags); int bind_mount_by_fd(int src, int dst); int bind_mount_path_to_fd(const char *srcname, int dst); int bind_mount_fd_to_path(int src, const char *destname); +void close_all(int *keep_list, size_t sz); int has_handler(pid_t pid, int signal); void enter_network_namespace(pid_t pid); int read_pid(const char *name, pid_t *pid); @@ -881,7 +882,6 @@ void build_appimage_cmdline(char **command_line, char **window_title, int argc, #define SBOX_CAPS_HIDEPID (1 << 7) // hidepid caps filter for running firemon #define SBOX_CAPS_NET_SERVICE (1 << 8) // caps filter for programs running network services #define SBOX_KEEP_FDS (1 << 9) // keep file descriptors open -#define FIREJAIL_MAX_FD 20 // getdtablesize() is overkill for a firejail process // run sbox int sbox_run(unsigned filter, int num, ...); diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c index e5e67c09d0d..7b5b61f2f72 100644 --- a/src/firejail/sbox.c +++ b/src/firejail/sbox.c @@ -72,11 +72,8 @@ static int __attribute__((noreturn)) sbox_do_exec_v(unsigned filtermask, char * } // close all other file descriptors - if ((filtermask & SBOX_KEEP_FDS) == 0) { - int i; - for (i = 3; i < FIREJAIL_MAX_FD; i++) - close(i); // close open files - } + if ((filtermask & SBOX_KEEP_FDS) == 0) + close_all(NULL, 0); umask(027); diff --git a/src/firejail/util.c b/src/firejail/util.c index dbbc1ea28ec..5b8fd0b0f8b 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c @@ -1398,6 +1398,52 @@ int bind_mount_path_to_fd(const char *srcname, int dst) { return rv; } +void close_all(int *keep_list, size_t sz) { + DIR *dir; + if (!(dir = opendir("/proc/self/fd"))) { + // sleep 2 seconds and try again + sleep(2); + if (!(dir = opendir("/proc/self/fd"))) { + fprintf(stderr, "Error: cannot open /proc/self/fd directory\n"); + exit(1); + } + } + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + if (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0) + continue; + + int fd = atoi(entry->d_name); + + // don't close standard streams + if (fd == STDIN_FILENO || + fd == STDOUT_FILENO || + fd == STDERR_FILENO) + continue; + + if (fd == dirfd(dir)) + continue; // just postponed + + // dont't close file descriptors in keep list + int keep = 0; + if (keep_list) { + size_t i; + for (i = 0; i < sz; i++) { + if (keep_list[i] == fd) { + keep = 1; + break; + } + } + } + if (keep) + continue; + + close(fd); + } + closedir(dir); +} + int has_handler(pid_t pid, int signal) { if (signal > 0 && signal <= SIGRTMAX) { char *fname;