cgroups.plugin: fixes to cgroup path validation (#19490)
Ivan Shapovalov committed
Feb 3, 2025 at 13:19 UTC
1d2824f1a91ec21ac7bc53c67ff0e62ef7bf54cf
1 file changed
+24
-9
src/collectors/cgroups.plugin/cgroup-network.c
+24
-9
@@ -611,15 +611,30 @@ void call_the_helper(pid_t pid, const char *cgroup) {
611
nd_log(NDLS_COLLECTORS, NDLP_ERR, "cannot execute cgroup-network helper script: %s", command);
612
}
613
614
+int ishex(char c) {
615
+ return (c >= '0' && c <= '9') ||
616
+ (c >= 'a' && c <= 'f') ||
617
+ (c >= 'A' && c <= 'F');
618
+}
619
+
620
+int is_valid_hex_escape(const char *arg) {
621
+ fatal_assert(arg);
622
+
623
+ return (arg[0] == '\\') &&
624
+ (arg[1] == 'x') &&
625
+ ishex(arg[2]) &&
626
+ ishex(arg[3]);
627
+}
628
+
629
int is_valid_path_symbol(char c) {
630
switch(c) {
631
case '/': // path separators
617
- case '\\': // needed for virsh domains \x2d1\x2dname
632
case ' ': // space
633
case '-': // hyphen
634
case '_': // underscore
635
case '.': // dot
636
case ',': // comma
637
+ case '@': // systemd unit template specifier (/sys/fs/cgroup/machines.slice/systemd-nspawn@NAME.service)
638
return 1;
639
640
default:
@@ -635,20 +650,20 @@ int is_valid_path_symbol(char c) {
650
int verify_path(const char *path) {
651
struct stat sb;
652
638
- char c;
653
+ fatal_assert(path);
654
+
655
const char *s = path;
640
- while((c = *s++)) {
641
- if(!( isalnum(c) || is_valid_path_symbol(c) )) {
656
+ while(*s != '\0') {
657
+ if (isalnum(*s) || is_valid_path_symbol(*s))
658
+ s += 1;
659
+ else if (*s == '\\' && is_valid_hex_escape(s))
660
+ s += 4;
661
+ else {
662
nd_log(NDLS_COLLECTORS, NDLP_ERR, "invalid character in path '%s'", path);
663
return -1;
664
}
665
}
666
647
- if(strstr(path, "\\") && !strstr(path, "\\x")) {
648
- nd_log(NDLS_COLLECTORS, NDLP_ERR, "invalid escape sequence in path '%s'", path);
649
- return 1;
650
- }
651
-
667
if(strstr(path, "/../")) {
668
nd_log(NDLS_COLLECTORS, NDLP_ERR, "invalid parent path sequence detected in '%s'", path);
669
return 1;