@cryptotaxi247 / netdata-1 / commits / a99412789

use fixed path to cgroup-network-helper.sh; strictier path checking; fixes #3269

Costa Tsaousis (ktsaou) committed Jan 13, 2018 at 04:59 UTC a994127896503647cc96a2bbe58faed5fa51dbc8
2 files changed +37 -40
plugins.d/cgroup-network-helper.sh
-6
@@ -69,12 +69,6 @@ debug() {
69 [ $(( ${BASH_VERSINFO[0]} )) -lt 4 ] && \
70 fatal "BASH version 4 or later is required (this is ${BASH_VERSION})."
71
72 -# -----------------------------------------------------------------------------
73 -# defaults to allow running this script by hand
74 -
75 -[ -z "${NETDATA_PLUGINS_DIR}" ] && NETDATA_PLUGINS_DIR="$(dirname "${0}")"
76 -[ -z "${NETDATA_CONFIG_DIR}" ] && NETDATA_CONFIG_DIR="$(dirname "${0}")/../../../../etc/netdata"
77 -
72 # -----------------------------------------------------------------------------
73 # parse the arguments
74
src/cgroup-network.c
+37 -34
@@ -9,17 +9,11 @@
9 #endif
10
11 char *host_prefix = "";
12 -char *pluginsdir = "";
13 -char *configdir = "";
12
13 char environment_variable2[FILENAME_MAX + 50] = "";
16 -char environment_variable3[FILENAME_MAX + 50] = "";
17 -char environment_variable4[FILENAME_MAX + 50] = "";
14 char *environment[] = {
15 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin",
16 environment_variable2,
21 - environment_variable3,
22 - environment_variable4,
17 NULL
18 };
19
@@ -452,9 +446,9 @@ void call_the_helper(pid_t pid, const char *cgroup) {
446
447 char buffer[CGROUP_NETWORK_INTERFACE_MAX_LINE + 1];
448 if(cgroup)
455 - snprintfz(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, "exec %s/cgroup-network-helper.sh --cgroup '%s'", pluginsdir, cgroup);
449 + snprintfz(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, "exec " PLUGINS_DIR "/cgroup-network-helper.sh --cgroup '%s'", cgroup);
450 else
457 - snprintfz(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, "exec %s/cgroup-network-helper.sh --pid %d", pluginsdir, pid);
451 + snprintfz(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, "exec " PLUGINS_DIR "/cgroup-network-helper.sh --pid %d", pid);
452
453 info("running: %s", buffer);
454
@@ -484,18 +478,49 @@ void call_the_helper(pid_t pid, const char *cgroup) {
478 error("cannot execute cgroup-network helper script: %s", buffer);
479 }
480
481 +int is_valid_path_symbol(char c) {
482 + switch(c) {
483 + case '/': // path separators
484 + case '\\': // needed for virsh domains \x2d1\x2dname
485 + case ' ': // space
486 + case '-': // hyphen
487 + case '_': // underscore
488 + case '.': // dot
489 + case ',': // comma
490 + return 1;
491 +
492 + default:
493 + return 0;
494 + }
495 +}
496 +
497 +// we will pass this path a shell script running as root
498 +// so, we need to make sure the path will be valid
499 +// and will not include anything that could allow
500 +// the caller use shell expansion for gaining escalated
501 +// privileges.
502 int verify_path(const char *path) {
503 struct stat sb;
504
505 char c;
506 const char *s = path;
507 while((c = *s++)) {
493 - if(c == '$' || c == '`' || c == '<' || c == '>') {
508 + if(!( isalnum(c) || is_valid_path_symbol(c) )) {
509 error("invalid character in path '%s'", path);
510 return -1;
511 }
512 }
513
514 + if(strstr(path, "\\") && !strstr(path, "\\x")) {
515 + error("invalid escape sequence in path '%s'", path);
516 + return 1;
517 + }
518 +
519 + if(strstr(path, "/../")) {
520 + error("invalid parent path sequence detected in '%s'", path);
521 + return 1;
522 + }
523 +
524 if(path[0] != '/') {
525 error("only absolute path names are supported - invalid path '%s'", path);
526 return -1;
@@ -572,35 +597,13 @@ int main(int argc, char **argv) {
597 host_prefix = "";
598
599 if(host_prefix[0] != '\0' && verify_path(host_prefix) == -1)
575 - fatal("cannot find path NETDATA_HOST_PREFIX '%s'", host_prefix);
576 -
577 - // ------------------------------------------------------------------------
578 - // make sure NETDATA_CONFIG_DIR is safe
579 -
580 - configdir = getenv("NETDATA_CONFIG_DIR");
581 - if(!configdir || !*configdir) {
582 - configdir = "";
583 - }
584 - else if(verify_path(configdir) == -1)
585 - fatal("cannot find path NETDATA_CONFIG_DIR '%s'", configdir);
586 -
587 - // ------------------------------------------------------------------------
588 - // make sure NETDATA_PLUGINS_DIR is safe
589 -
590 - pluginsdir = getenv("NETDATA_PLUGINS_DIR");
591 - if(!pluginsdir || !*pluginsdir) {
592 - char *me = strdupz(argv[0]);
593 - pluginsdir = dirname(me);
594 - }
595 - else if(verify_path(pluginsdir) == -1)
596 - fatal("cannot find path NETDATA_PLUGINS_DIR '%s'", pluginsdir);
600 + fatal("invalid NETDATA_HOST_PREFIX '%s'", host_prefix);
601
602 // ------------------------------------------------------------------------
603 // build a safe environment for our script
604
605 + // the first environment variable is a fixed PATH=
606 snprintfz(environment_variable2, sizeof(environment_variable2) - 1, "NETDATA_HOST_PREFIX=%s", host_prefix);
602 - snprintfz(environment_variable3, sizeof(environment_variable3) - 1, "NETDATA_PLUGINS_DIR=%s", pluginsdir);
603 - snprintfz(environment_variable4, sizeof(environment_variable4) - 1, "NETDATA_CONFIG_DIR=%s", configdir);
607
608 // ------------------------------------------------------------------------
609
@@ -626,7 +629,7 @@ int main(int argc, char **argv) {
629 else if(!strcmp(argv[1], "--cgroup")) {
630 char *cgroup = argv[2];
631 if(verify_path(cgroup) == -1)
629 - fatal("cgroup '%s' does not exist.", cgroup);
632 + fatal("cgroup '%s' does not exist or is not valid.", cgroup);
633
634 pid = read_pid_from_cgroup(cgroup);
635 call_the_helper(pid, cgroup);