From d79c5cfba3eb6354f5c2391e8c53aebf4c906ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 14 Jun 2023 09:56:45 +0000 Subject: [PATCH] Close fd after fork() also on REST API Closing the file descriptors also on REST API after the fork. It excludes all the pipes. close_all_non_term_fd() accepts a vector of FDs to exclude --- include/proxysql_utils.h | 5 +++++ lib/ProxySQL_Admin.cpp | 19 +------------------ lib/proxysql_utils.cpp | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/include/proxysql_utils.h b/include/proxysql_utils.h index 2d75c4693..eb510357a 100644 --- a/include/proxysql_utils.h +++ b/include/proxysql_utils.h @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #ifndef ETIME // ETIME is not defined on FreeBSD @@ -205,4 +208,6 @@ std::string replace_str(const std::string& str, const std::string& match, const std::string generate_multi_rows_query(int rows, int params); + +void close_all_non_term_fd(std::vector excludeFDs); #endif diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index b5a0aca9b..5e46ffc16 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -189,23 +189,6 @@ static char * load_file (const char *filename) { */ -void close_all_non_term_fd() { - DIR *d; - struct dirent *dir; - d = opendir("/proc/self/fd"); - if (d) { - while ((dir = readdir(d)) != NULL) { - if (strlen(dir->d_name) && dir->d_name[0] != '.') { - int fd = std::stol(std::string(dir->d_name)); - if (fd > 2) { - close(fd); - } - } - } - closedir(d); - } -} - static int round_intv_to_time_interval(int& intv) { if (intv > 300) { intv = 600; @@ -13620,7 +13603,7 @@ unsigned long long ProxySQL_External_Scheduler::run_once() { exit(EXIT_FAILURE); } if (cpid == 0) { - close_all_non_term_fd(); + close_all_non_term_fd({}); char *newenviron[] = { NULL }; int rc; rc=execve(sr->filename, newargs, newenviron); diff --git a/lib/proxysql_utils.cpp b/lib/proxysql_utils.cpp index 1207a04ef..3f1eddf5e 100644 --- a/lib/proxysql_utils.cpp +++ b/lib/proxysql_utils.cpp @@ -239,6 +239,9 @@ int wexecvp( // Duplicate file argument to avoid manual duplication _argv.insert(_argv.begin(), file.c_str()); + // close all files , with the exception of the pipes + close_all_non_term_fd({ CHILD_READ_FD, CHILD_WRITE_FD, CHILD_WRITE_ERR, PARENT_READ_FD, PARENT_READ_ERR, PARENT_WRITE_FD}); + // Copy the pipe descriptors int dup_read_err = dup2(CHILD_READ_FD, STDIN_FILENO); int dup_write_err = dup2(CHILD_WRITE_FD, STDOUT_FILENO); @@ -257,6 +260,7 @@ int wexecvp( close(PARENT_READ_ERR); close(PARENT_WRITE_FD); + char** args = const_cast(_argv.data()); child_err = execvp(file.c_str(), args); @@ -397,3 +401,32 @@ std::string generate_multi_rows_query(int rows, int params) { } return s; } + +void close_all_non_term_fd(std::vector excludeFDs) { + DIR *d; + struct dirent *dir; + d = opendir("/proc/self/fd"); + if (d) { + while ((dir = readdir(d)) != NULL) { + if (strlen(dir->d_name) && dir->d_name[0] != '.') { + int fd = std::stol(std::string(dir->d_name)); + if (fd > 2) { + if (std::find(excludeFDs.begin(), excludeFDs.end(), fd) == excludeFDs.end()) { + close(fd); + } + } + } + } + closedir(d); + } else { + struct rlimit nlimit; + int rc = getrlimit(RLIMIT_NOFILE, &nlimit); + if (rc == 0) { + for (unsigned int fd = 3; fd < nlimit.rlim_cur; fd++) { + if (std::find(excludeFDs.begin(), excludeFDs.end(), fd) == excludeFDs.end()) { + close(fd); + } + } + } + } +}