Skip to content

Commit

Permalink
[plugin/procfs] PS-7784: Fix misc ProcFS issues
Browse files Browse the repository at this point in the history
PS-7784 Status variable `procfs_access_violations` has same value as `procfs_queries`

Fix typo
Replace queries->access_violations for procfs_access_violations

--------------------------------------------------------------------------

PS-7785 Default value for `procfs_files_spec` contains non-existing
entries

Fix typo
Lost semicolon

--------------------------------------------------------------------------

PS-7788 Wildcard globbing in `procfs_files_spec` does not work

1) The length of the string as an array is `sizeof(PROC_NAME) - 1`

2) Also condition `last_sep_before_star == std::string::npos`
will never work and its body searches for files in the current
directory.
Corrected that in the absence of a pattern, the search logic
for the pattern would be reused, where pattern is the file name

--------------------------------------------------------------------------

PS-7790 ProcFS access boundary to `/proc` and `/sys` can be bypassed with `..`

Use `realpath()` to expands all symbolic links and resolves
references to /./, /../ and make sure that path start from /proc/ or /sys/
  • Loading branch information
avbelov23 authored and dlenev committed Aug 28, 2024
1 parent dc55100 commit 36f9f9d
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 14 deletions.
31 changes: 17 additions & 14 deletions plugin/procfs/procfs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
access patterns in glob(7) style:  /sys/block/sd[a-z]/stat;/proc/version*
The default value for procfs_files_spec is : /proc/cpuinfo;/proc/irq//;
/proc/loadavg/proc/net/dev;/proc/net/sockstat;/proc/net/sockstat_rhe4;
/proc/loadavg;/proc/net/dev;/proc/net/sockstat;/proc/net/sockstat_rhe4;
/proc/net/tcpstat;/proc/self/net/netstat;/proc/self/stat;/proc/self/io;
/proc/self/numa_maps/proc/softirqs;/proc/spl/kstat/zfs/arcstats;/proc/stat;
/proc/sys/fs/file-nr;/proc/version;/proc/vmstat
Expand Down Expand Up @@ -118,7 +118,8 @@ static const constexpr ulong MAX_PATTERN_DEPTH = 10;
static const char *DEFAULT_FILES_SPEC =
"/proc/cpuinfo;"
"/proc/irq/*/*;"
"/proc/loadavg/proc/net/dev;"
"/proc/loadavg;"
"/proc/net/dev;"
"/proc/net/sockstat;"
"/proc/net/sockstat_rhe4;"
"/proc/net/tcpstat;"
Expand All @@ -131,6 +132,10 @@ static const char *DEFAULT_FILES_SPEC =
"/proc/sys/fs/file-nr;"
"/proc/version;"
"/proc/vmstat";
static const constexpr char SYS_NAME[] = "/sys/";
static const constexpr int SYS_NAME_LEN = sizeof(SYS_NAME) - 1;
static const constexpr char PROC_NAME[] = "/proc/";
static const constexpr int PROC_NAME_LEN = sizeof(PROC_NAME) - 1;

static char *files_spec = nullptr;
static char *buffer = nullptr;
Expand Down Expand Up @@ -161,7 +166,7 @@ static std::atomic<uint64_t> files_read(0);
static std::atomic<uint64_t> bytes_read(0);

static SHOW_VAR status_variables[] = {
{"procfs_access_violations", (char *)&queries, SHOW_LONGLONG,
{"procfs_access_violations", (char *)&access_violations, SHOW_LONGLONG,
SHOW_SCOPE_GLOBAL},
{"procfs_queries", (char *)&queries, SHOW_LONGLONG, SHOW_SCOPE_GLOBAL},
{"procfs_files_read", (char *)&files_read, SHOW_LONGLONG,
Expand Down Expand Up @@ -249,11 +254,6 @@ static bool get_in_condition_argument(Item *cond,
static void limited_glob_files(const std::string &path,
const std::string &pattern, int max_results,
std::vector<std::string> &files_found) {
static const constexpr char SYS_NAME[] = "/sys/";
static const constexpr int SYS_NAME_LEN = sizeof(SYS_NAME);
static const constexpr char PROC_NAME[] = "/proc/";
static const constexpr int PROC_NAME_LEN = sizeof(PROC_NAME);

if (max_results <= 0) return;

DIR *dir = opendir(path.c_str());
Expand Down Expand Up @@ -298,10 +298,7 @@ static void limited_glob(const std::string &query, int max_results,
std::string::size_type first_sep_after_star =
query.find_first_of("/", first_star);

if (last_sep_before_star == std::string::npos) {
path = std::string(".");
pattern = query;
} else if (first_sep_after_star == std::string::npos) {
if (first_sep_after_star == std::string::npos) {
path = std::string(query.begin(), query.begin() + last_sep_before_star);
pattern =
std::string(query.begin() + last_sep_before_star + 1, query.end());
Expand Down Expand Up @@ -349,10 +346,16 @@ static void fill_files_list(std::vector<std::string> &files) {
while (list) {
std::string path;
std::getline(list, path, ';');
if (path.rfind("/proc", 0) != 0 && path.rfind("/sys", 0) != 0) continue;

if (path.find_first_of("*?[") == std::string::npos) {
files.push_back(path);
std::vector<char> real_file_path(PATH_MAX);

if (realpath(path.c_str(), real_file_path.data())) {
if (strncmp(SYS_NAME, real_file_path.data(), SYS_NAME_LEN) == 0 ||
strncmp(PROC_NAME, real_file_path.data(), PROC_NAME_LEN) == 0)
files.push_back(path);
}

continue;
}

Expand Down
12 changes: 12 additions & 0 deletions plugin/procfs/tests/mtr/procfs_basic.result
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,17 @@ INSTALL PLUGIN procfs SONAME 'procfs.so';
SELECT COUNT(*) FROM information_schema.procfs WHERE file = '/proc/version';
COUNT(*)
1
SHOW STATUS LIKE 'procfs_access_violations';
Variable_name Value
procfs_access_violations 0
SELECT COUNT(*) FROM information_schema.procfs WHERE file = '/proc/loadavg';
COUNT(*)
1
SELECT COUNT(*) FROM information_schema.procfs WHERE file = '/proc/net/dev';
COUNT(*)
1
SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCFS WHERE FILE LIKE '/proc/irq/0/%';
COUNT(*)
7
UNINSTALL PLUGIN procfs;
DROP USER mysqltest_1@localhost;
7 changes: 7 additions & 0 deletions plugin/procfs/tests/mtr/procfs_basic.test
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ INSTALL PLUGIN procfs SONAME 'procfs.so';

SELECT COUNT(*) FROM information_schema.procfs WHERE file = '/proc/version';

SHOW STATUS LIKE 'procfs_access_violations';

SELECT COUNT(*) FROM information_schema.procfs WHERE file = '/proc/loadavg';
SELECT COUNT(*) FROM information_schema.procfs WHERE file = '/proc/net/dev';

SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCFS WHERE FILE LIKE '/proc/irq/0/%';

--connection default
--disconnect conn1

Expand Down

0 comments on commit 36f9f9d

Please sign in to comment.