diff -up aide-0.16/src/db_disk.c.orig aide-0.16/src/db_disk.c --- aide-0.16/src/db_disk.c.orig 2025-08-21 09:58:21.271581589 +0200 +++ aide-0.16/src/db_disk.c 2025-08-21 10:01:26.310573141 +0200 @@ -139,7 +139,11 @@ void add_child (db_line * fil) int i; struct seltree *new_r; - error (255, "Adding child %s\n", fil->filename); + { + char *fname_safe = stresc(fil->filename); + error (255, "Adding child %s\n", fname_safe); + free(fname_safe); + } new_r = get_seltree_node (r, fil->filename); if (new_r != NULL) { @@ -182,9 +186,13 @@ static int get_file_status(char *filenam if(sres == -1){ char* er = strerror(errno); if (er == NULL) { - error(0,"get_file_status: lstat() failed for %s. strerror() failed for %i\n", filename, errno); + char *filename_safe = stresc(filename); + error(0,"get_file_status: lstat() failed for %s. strerror() failed for %i\n", filename_safe, errno); + free(filename_safe); } else { - error(0,"get_file_status: lstat() failed for %s: %s\n", filename, er); + char *filename_safe = stresc(filename); + error(0,"get_file_status: lstat() failed for %s: %s\n", filename_safe, er); + free(filename_safe); } } return sres; @@ -220,7 +228,11 @@ db_line *db_readline_disk () error (240, "%s attr=%llu\n", &fullname[conf->root_prefix_length], attr); if (fil != NULL) { - error (240, "%s attr=%llu\n", fil->filename, fil->attr); + { + char *fname_safe = stresc(fil->filename); + error (240, "%s attr=%llu\n", fname_safe, fil->attr); + free(fname_safe); + } return fil; } } @@ -269,7 +281,11 @@ recursion: error (240, "%s attr=%llu\n", &fullname[conf->root_prefix_length], attr); if (fil != NULL) { - error (240, "%s attr=%llu\n", fil->filename, fil->attr); + { + char *fname_safe = stresc(fil->filename); + error (240, "%s attr=%llu\n", fname_safe, fil->attr); + free(fname_safe); + } } else { /* Something went wrong during read process -> diff -up aide-0.16/src/gen_list.c.orig aide-0.16/src/gen_list.c --- aide-0.16/src/gen_list.c.orig 2025-08-21 09:58:21.273581610 +0200 +++ aide-0.16/src/gen_list.c 2025-08-21 10:04:29.190502666 +0200 @@ -37,6 +37,7 @@ #include "list.h" #include "gen_list.h" #include "seltree.h" +#include "util.h" #include "db.h" #include "db_config.h" #include "commandconf.h" @@ -993,16 +994,28 @@ int check_rxtree(char* filename,seltree* if(conf->limit!=NULL) { retval=pcre_exec(conf->limit_crx, NULL, filename, strlen(filename), 0, PCRE_PARTIAL_SOFT, NULL, 0); if (retval >= 0) { - error(220, "check_rxtree: %s does match limit: %s\n", filename, conf->limit); + char *fname_safe = stresc(filename); + char *limit_safe = conf->limit?stresc(conf->limit):NULL; + error(220, "check_rxtree: %s does match limit: %s\n", fname_safe, limit_safe?limit_safe:""); + free(fname_safe); + free(limit_safe); } else if (retval == PCRE_ERROR_PARTIAL) { - error(220, "check_rxtree: %s does PARTIAL match limit: %s\n", filename, conf->limit); + char *fname_safe = stresc(filename); + char *limit_safe = conf->limit?stresc(conf->limit):NULL; + error(220, "check_rxtree: %s does PARTIAL match limit: %s\n", fname_safe, limit_safe?limit_safe:""); if(S_ISDIR(perm) && get_seltree_node(tree,filename)==NULL){ - error(220, "check_rxtree: creating new seltree node for '%s'\n", filename); + error(220, "check_rxtree: creating new seltree node for '%s'\n", fname_safe); new_seltree_node(tree,filename,0,NULL); } + free(fname_safe); + free(limit_safe); return -1; } else { - error(220, "check_rxtree: %s does NOT match limit: %s\n", filename, conf->limit); + char *fname_safe = stresc(filename); + char *limit_safe = conf->limit?stresc(conf->limit):NULL; + error(220, "check_rxtree: %s does NOT match limit: %s\n", fname_safe, limit_safe?limit_safe:""); + free(fname_safe); + free(limit_safe); return -2; } } @@ -1039,13 +1052,25 @@ db_line* get_file_attrs(char* filename,D } else { if(fs->st_atime>cur_time){ - error(CLOCK_SKEW,_("%s atime in future\n"),filename); + { + char *fname_safe = stresc(filename); + error(CLOCK_SKEW,_("%s atime in future\n"),fname_safe); + free(fname_safe); + } } if(fs->st_mtime>cur_time){ - error(CLOCK_SKEW,_("%s mtime in future\n"),filename); + { + char *fname_safe = stresc(filename); + error(CLOCK_SKEW,_("%s mtime in future\n"),fname_safe); + free(fname_safe); + } } if(fs->st_ctime>cur_time){ - error(CLOCK_SKEW,_("%s ctime in future\n"),filename); + { + char *fname_safe = stresc(filename); + error(CLOCK_SKEW,_("%s ctime in future\n"),fname_safe); + free(fname_safe); + } } } @@ -1220,7 +1245,11 @@ void hsymlnk(db_line* line) { int sres; sres=AIDE_STAT_FUNC(line->fullpath,&fs); if (sres!=0 && sres!=EACCES) { - error(4,"Dead symlink detected at %s\n",line->fullpath); + { + char *fp_safe = stresc(line->fullpath); + error(4,"Dead symlink detected at %s\n",fp_safe); + free(fp_safe); + } } if(!(line->attr&DB_RDEV)) fs.st_rdev=0; diff -up aide-0.16/src/util.c.orig aide-0.16/src/util.c --- aide-0.16/src/util.c.orig 2025-08-21 09:58:21.272581600 +0200 +++ aide-0.16/src/util.c 2025-08-21 10:07:50.157894133 +0200 @@ -104,9 +104,11 @@ url_t* parse_url(char* val) r+=2; for(i=0;r[0]!='/'&&r[0]!='\0';r++,i++); if(r[0]=='\0'){ - error(0,"Invalid file-URL,no path after hostname: file:%s\n",t); + char *t_safe = stresc(t); + error(0,"Invalid file-URL,no path after hostname: file:%s\n",t_safe); + free(t_safe); free(hostname); - return NULL; + return NULL; } u->value=strdup(r); r[0]='\0'; @@ -118,9 +120,11 @@ url_t* parse_url(char* val) free(hostname); break; } else { - error(0,"Invalid file-URL, cannot use hostname other than localhost or %s: file:%s\n",hostname,u->value); - free(hostname); - return NULL; + char *value_safe = stresc(u->value); + error(0,"Invalid file-URL, cannot use hostname other than localhost or %s: file:%s\n",hostname,value_safe); + free(value_safe); + free(hostname); + return NULL; } break; @@ -150,6 +154,43 @@ url_t* parse_url(char* val) return u; } +static size_t escape_str(const char *unescaped_str, char *str, size_t s) { + size_t n = 0; + size_t i = 0; + char c; + while (i < s && (c = unescaped_str[i])) { + if ((c >= 0 && (c < 0x1f || c == 0x7f)) || + (c == '\\' && isdigit(unescaped_str[i+1]) + && isdigit(unescaped_str[i+2]) + && isdigit(unescaped_str[i+3]))) { + if (str) { snprintf(&str[n], 5, "\\%03o", c); } + n += 4; + } else { + if (str) { str[n] = c; } + n++; + } + i++; + } + if (str) { str[n] = '\0'; } + n++; + return n; +} + +char *strnesc(const char *unescaped_str, size_t s) { + int n = escape_str(unescaped_str, NULL, s); + char *str = malloc(n); + if (str == NULL) { + error(0, "malloc: failed to allocate %d bytes of memory\n", n); + exit(1); + } + escape_str(unescaped_str, str, s); + return str; +} + +char *stresc(const char *unescaped_str) { + return strnesc(unescaped_str, strlen(unescaped_str)); +} + /* Returns 1 if the string contains unsafe characters, 0 otherwise. */ int contains_unsafe (const char *s) {