diff --git a/.aide.metadata b/.aide.metadata deleted file mode 100644 index c6500fa..0000000 --- a/.aide.metadata +++ /dev/null @@ -1 +0,0 @@ -c699190eba9fcaa29ee362f57fb1a05dd74d947a SOURCES/aide-0.18.6.tar.gz diff --git a/.gitignore b/.gitignore index 58a533c..595440d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/aide-0.18.6.tar.gz +aide-0.18.6.tar.gz diff --git a/SOURCES/README.quickstart b/README.quickstart similarity index 100% rename from SOURCES/README.quickstart rename to README.quickstart diff --git a/SOURCES/aide-verbose.patch b/aide-verbose.patch similarity index 100% rename from SOURCES/aide-verbose.patch rename to aide-verbose.patch diff --git a/SOURCES/aide.conf b/aide.conf similarity index 100% rename from SOURCES/aide.conf rename to aide.conf diff --git a/SOURCES/aide.logrotate b/aide.logrotate similarity index 100% rename from SOURCES/aide.logrotate rename to aide.logrotate diff --git a/SPECS/aide.spec b/aide.spec similarity index 96% rename from SPECS/aide.spec rename to aide.spec index c70c379..4b2b63c 100644 --- a/SPECS/aide.spec +++ b/aide.spec @@ -26,7 +26,8 @@ BuildRequires: automake libtool Patch1: aide-verbose.patch Patch2: gnutls.patch -Patch3: aide-0.18-CVE-2025-54389-control-chars.patch +Patch3: escape-control-chars-CVE-2025-54389.patch +Patch4: lowercase-groupnames.patch %description @@ -42,6 +43,7 @@ cp -a %{S:2} . %patch -P 1 -p1 -b .verbose %patch -P 2 -p1 -b .gnutls %patch -P 3 -p1 -b .CVE-2025-54389 +%patch -P 4 -p1 -b .lowercase-groupnames %build autoreconf -ivf @@ -79,9 +81,15 @@ mkdir -p -m0700 %{buildroot}%{_localstatedir}/lib/aide %dir %attr(0700,root,root) %{_localstatedir}/log/aide %changelog -* Tue Aug 26 2025 Darren Archibald - 0.18.6-8.2 -- aide: improper output neutralization enables bypassing (CVE-2025-54389) -Resolves: rhbz#2388019 +* Tue Oct 14 2025 Attila Lakatos - 0.18.6-8.2 +- RHEL 10.1.Z ERRATUM +- Fix lowercase group name definition +Resolves: RHEL-119647 + +* Tue Aug 19 2025 Attila Lakatos - 0.18.6-8.1 +RHEL 10.1 ERRATUM +- CVE-2025-54389 aide: improper output neutralization enables bypassing +Resolves: RHEL-108928 * Wed Jan 29 2025 Radovan Sroka - 0.18.6-8 RHEL 10.0 ERRATUM diff --git a/SOURCES/aide-0.18-CVE-2025-54389-control-chars.patch b/escape-control-chars-CVE-2025-54389.patch similarity index 74% rename from SOURCES/aide-0.18-CVE-2025-54389-control-chars.patch rename to escape-control-chars-CVE-2025-54389.patch index 4985991..0daa36f 100644 --- a/SOURCES/aide-0.18-CVE-2025-54389-control-chars.patch +++ b/escape-control-chars-CVE-2025-54389.patch @@ -1,25 +1,8 @@ -From 2122024810bc9246ec4abc3b2d87e657a4e4a499 Mon Sep 17 00:00:00 2001 -From: Darren Archibald -Date: Tue, 26 Aug 2025 05:49:31 -0700 -Subject: [PATCH] escape control chars (CVE-2025-43289) - -Signed-off-by: Darren Archibald ---- - doc/aide.1 | 13 +++++++++++ - include/util.h | 3 +++ - src/aide.c | 3 ++- - src/gen_list.c | 14 ++++++++---- - src/log.c | 26 +++++++++++++++++---- - src/report_json.c | 57 +++++++++++++++++++++++++++++++++++++++++----- - src/report_plain.c | 56 ++++++++++++++++++++++++++++++--------------- - src/util.c | 34 +++++++++++++++++++++++++++ - 8 files changed, 172 insertions(+), 34 deletions(-) - -diff --git a/doc/aide.1 b/doc/aide.1 -index c5b996b..02af050 100644 ---- a/doc/aide.1 -+++ b/doc/aide.1 -@@ -130,12 +130,25 @@ SIGUSR1 toggles the log_level between current and debug level. +diff -U0 aide-0.18.6/ChangeLog.orig aide-0.18.6/ChangeLog +diff -up aide-0.18.6/doc/aide.1.orig aide-0.18.6/doc/aide.1 +--- aide-0.18.6/doc/aide.1.orig 2025-08-19 11:35:36.082823977 +0200 ++++ aide-0.18.6/doc/aide.1 2025-08-19 11:35:36.082823977 +0200 +@@ -130,12 +130,25 @@ SIGUSR1 toggles the log_level between cu .PP .SH NOTES @@ -45,10 +28,9 @@ index c5b996b..02af050 100644 .PP .SH FILES -diff --git a/include/util.h b/include/util.h -index 897ac64..c22c9d6 100644 ---- a/include/util.h -+++ b/include/util.h +diff -up aide-0.18.6/include/util.h.orig aide-0.18.6/include/util.h +--- aide-0.18.6/include/util.h.orig 2025-08-19 11:35:36.081823966 +0200 ++++ aide-0.18.6/include/util.h 2025-08-19 11:35:36.080823957 +0200 @@ -57,6 +57,9 @@ int cmpurl(url_t*, url_t*); int contains_unsafe(const char*); @@ -59,29 +41,30 @@ index 897ac64..c22c9d6 100644 void decode_string(char*); char* encode_string(const char*); -diff --git a/src/aide.c b/src/aide.c -index 5de0492..77928f0 100644 ---- a/src/aide.c -+++ b/src/aide.c -@@ -285,7 +285,8 @@ static void read_param(int argc,char**argv) +diff -up aide-0.18.6/src/aide.c.orig aide-0.18.6/src/aide.c +--- aide-0.18.6/src/aide.c.orig 2025-08-19 11:35:36.083823987 +0200 ++++ aide-0.18.6/src/aide.c 2025-08-19 11:35:36.083823987 +0200 +@@ -285,8 +285,8 @@ static void read_param(int argc,char**ar if((conf->limit_crx=pcre2_compile((PCRE2_SPTR) conf->limit, PCRE2_ZERO_TERMINATED, PCRE2_UTF|PCRE2_ANCHORED, &pcre2_errorcode, &pcre2_erroffset, NULL)) == NULL) { PCRE2_UCHAR pcre2_error[128]; pcre2_get_error_message(pcre2_errorcode, pcre2_error, 128); - INVALID_ARGUMENT("--limit", error in regular expression '%s' at %zu: %s, conf->limit, pcre2_erroffset, pcre2_error) +- + char * limit_safe = stresc(conf->limit); + INVALID_ARGUMENT("--limit", error in regular expression '%s' at %zu: %s, limit_safe, pcre2_erroffset, pcre2_error) - } conf->limit_md = pcre2_match_data_create_from_pattern(conf->limit_crx, NULL); -diff --git a/src/gen_list.c b/src/gen_list.c -index e1633d3..b34867e 100644 ---- a/src/gen_list.c -+++ b/src/gen_list.c -@@ -339,35 +339,39 @@ void print_match(char* filename, rx_rule *rule, match_result match, RESTRICTION_ + if (conf->limit_md == NULL) { +diff -up aide-0.18.6/src/gen_list.c.orig aide-0.18.6/src/gen_list.c +--- aide-0.18.6/src/gen_list.c.orig 2025-08-19 11:35:36.083823987 +0200 ++++ aide-0.18.6/src/gen_list.c 2025-08-19 11:35:36.083823987 +0200 +@@ -339,35 +339,40 @@ void print_match(char* filename, rx_rule char * str; char* attr_str; char file_type = get_restriction_char(restriction); + char *filename_safe = stresc(filename); ++ char *limit_safe = conf->limit?stresc(conf->limit):NULL; ++ switch (match) { case RESULT_SELECTIVE_MATCH: str = get_restriction_string(rule->restriction); @@ -113,19 +96,17 @@ index e1633d3..b34867e 100644 case RESULT_PARTIAL_LIMIT_MATCH: case RESULT_NO_LIMIT_MATCH: - fprintf(stdout, "[ ] %c '%s': outside of limit '%s'\n", file_type, filename, conf->limit); -+ str = stresc(conf->limit); -+ fprintf(stdout, "[ ] %c '%s': outside of limit '%s'\n", file_type, filename_safe, str); -+ free(str); ++ fprintf(stdout, "[ ] %c '%s': outside of limit '%s'\n", file_type, filename_safe, limit_safe); break; } + free(filename_safe); ++ free(limit_safe); } /* -diff --git a/src/log.c b/src/log.c -index 3f741a6..ce5417c 100644 ---- a/src/log.c -+++ b/src/log.c +diff -up aide-0.18.6/src/log.c.orig aide-0.18.6/src/log.c +--- aide-0.18.6/src/log.c.orig 2025-08-19 11:35:36.083823987 +0200 ++++ aide-0.18.6/src/log.c 2025-08-19 11:42:16.887261761 +0200 @@ -30,6 +30,7 @@ #include "log.h" @@ -139,54 +120,44 @@ index 3f741a6..ce5417c 100644 LOG_LEVEL level = cached_lines[i].level; if (level == LOG_LEVEL_ERROR || level <= log_level) { - fprintf(url, "%s: %s\n", log_level_array[level-1].log_string, cached_lines[i].message); -+ char * msg_safe = stresc(cached_lines[i].message); ++ char *msg_safe = stresc(cached_lines[i].message); + fprintf(url, "%s: %s\n", log_level_array[level-1].log_string, msg_safe); + free(msg_safe); } free(cached_lines[i].message); } -@@ -135,9 +138,24 @@ static void vlog_msg(LOG_LEVEL level,const char* format, va_list ap) { +@@ -135,9 +138,24 @@ static void vlog_msg(LOG_LEVEL level,con FILE* url = stderr; if (level == LOG_LEVEL_ERROR || level <= log_level) { - fprintf(url, "%s: ", log_level_array[level-1].log_string ); - vfprintf(url, format, ap); - fprintf(url, "\n"); -+ + va_list aq; + va_copy(aq, ap); -+ size_t n = vsnprintf(NULL, 0, format, aq) + 1; ++ int n = vsnprintf(NULL, 0, format, aq) + 1; + va_end(aq); + + int size = n * sizeof(char); + char *msg_unsafe = malloc(size); + if (msg_unsafe == NULL) { -+ fprintf(stderr, "%s: malloc: failed to allocate %d bytes of memory\n", log_level_array[LOG_LEVEL_ERROR-1].log_string, size); ++ fprintf(url, "%s: malloc failed to allocate %d bytes of memory\n", log_level_array[LOG_LEVEL_ERROR-1].log_string, size); + exit(MEMORY_ALLOCATION_FAILURE); + } + + vsnprintf(msg_unsafe, n, format, ap); + char *msg_safe = stresc(msg_unsafe); + free(msg_unsafe); -+ fprintf(url, "%s: %s\n", log_level_array[level-1].log_string, msg_safe); ++ fprintf(url, "%s: %s\n", log_level_array[level-1].log_string, msg_safe); + free(msg_safe); ++ } else if (log_level == LOG_LEVEL_UNSET) { cache_line(level, format, ap); } -diff --git a/src/report_json.c b/src/report_json.c -index 2fc77bc..47e7fe7 100644 ---- a/src/report_json.c -+++ b/src/report_json.c -@@ -29,6 +29,8 @@ - #include "report.h" - #include "seltree_struct.h" - #include "stdbool.h" -+#include "string.h" -+#include "stdio.h" - #include "url.h" - - #define JSON_FMT_ARRAY_BEGIN "%*c\"%s\": [\n" -@@ -57,12 +59,53 @@ static int _escape_json_string(const char *src, char *escaped_string) { +diff -up aide-0.18.6/src/report_json.c.orig aide-0.18.6/src/report_json.c +--- aide-0.18.6/src/report_json.c.orig 2025-08-19 11:35:36.084823997 +0200 ++++ aide-0.18.6/src/report_json.c 2025-08-19 11:35:36.083823987 +0200 +@@ -57,12 +57,53 @@ static int _escape_json_string(const cha int n = 0; for (i = 0; i < strlen(src); ++i) { @@ -233,7 +204,7 @@ index 2fc77bc..47e7fe7 100644 + break; + default: + if (src[i] >= 0 && (src[i] < 0x1f || src[i] == 0x7f)) { -+ if (escaped_string) { snprintf(&escaped_string[n], 7, "\\u%04d", src[i]); } ++ if (escaped_string) { snprintf(&escaped_string[n], 7, "\\u%04x", src[i]); } + n += 6; + } else { + if (escaped_string) { escaped_string[n] = src[i]; } @@ -245,24 +216,10 @@ index 2fc77bc..47e7fe7 100644 } if (escaped_string) { escaped_string[n] = '\0'; } n++; -@@ -302,9 +345,11 @@ static void print_report_diff_attrs_entries_json(report_t *report) { - report_printf(report, JSON_FMT_OBJECT_BEGIN, 2, ' ', "different_attributes"); - for(int i = 0; i < report->num_diff_attrs_entries; ++i) { - char *str = NULL; -+ char *escaped_filename = _get_escaped_json_string(report->diff_attrs_entries[i].entry); - report_printf(report, i+1num_diff_attrs_entries?JSON_FMT_STRING_COMMA:JSON_FMT_STRING_LAST , 4, ' ', -- report->diff_attrs_entries[i].entry, -+ escaped_filename, - str= diff_attributes(report->diff_attrs_entries[i].old_attrs, report->diff_attrs_entries[i].new_attrs)); -+ free(escaped_filename); - free(str); - } - report->num_diff_attrs_entries = 0; -diff --git a/src/report_plain.c b/src/report_plain.c -index c87fc72..7d8a746 100644 ---- a/src/report_plain.c -+++ b/src/report_plain.c -@@ -55,7 +55,9 @@ static char* _get_not_grouped_list_string(report_t *report) { +diff -up aide-0.18.6/src/report_plain.c.orig aide-0.18.6/src/report_plain.c +--- aide-0.18.6/src/report_plain.c.orig 2025-08-19 11:35:36.084823997 +0200 ++++ aide-0.18.6/src/report_plain.c 2025-08-19 11:35:36.083823987 +0200 +@@ -55,7 +55,9 @@ static char* _get_not_grouped_list_strin static void _print_config_option(report_t *report, config_option option, const char* value) { if (first) { first=false; } else { report_printf(report," | "); } @@ -273,7 +230,7 @@ index c87fc72..7d8a746 100644 } static void _print_report_option(report_t *report, config_option option, const char* value) { -@@ -63,37 +65,49 @@ static void _print_report_option(report_t *report, config_option option, const c +@@ -63,37 +65,49 @@ static void _print_report_option(report_ } static void _print_attribute(report_t *report, db_line* oline, db_line* nline, ATTRIBUTE attribute) { @@ -334,48 +291,62 @@ index c87fc72..7d8a746 100644 } static void _print_database_attributes(report_t *report, db_line* db) { -@@ -136,19 +150,21 @@ static void print_report_summary_plain(report_t *report) { +@@ -136,17 +150,29 @@ static void print_report_summary_plain(r } static void print_line_plain(report_t* report, seltree* node) { -+ char *filename_safe = stresc(((node->checked&NODE_REMOVED)?node->old_data:node->new_data)->filename); - if(report->summarize_changes) { +- if(report->summarize_changes) { ++ if(report->summarize_changes) { ++ char *filename = ((node->checked&NODE_REMOVED)?node->old_data:node->new_data)->filename; ++ char *filename_safe = stresc(filename); char* summary = get_summarize_changes_string(report, node); - report_printf(report, "\n%s: %s", summary, ((node->checked&NODE_REMOVED)?node->old_data:node->new_data)->filename); + report_printf(report, "\n%s: %s", summary, filename_safe); free(summary); summary=NULL; ++ free(filename_safe); } else { if (node->checked&NODE_ADDED) { - report_printf(report, _("\nadded: %s"),(node->new_data)->filename); -+ report_printf(report, _("\nadded: %s"),filename_safe); ++ char *filename = (node->new_data)->filename; ++ char *filename_safe = stresc(filename); ++ report_printf(report, _("\nadded: %s"), filename_safe); ++ free(filename_safe); } else if (node->checked&NODE_REMOVED) { - report_printf(report, _("\nremoved: %s"),(node->old_data)->filename); -+ report_printf(report, _("\nremoved: %s"),filename_safe); ++ char *filename = (node->old_data)->filename; ++ char *filename_safe = stresc(filename); ++ report_printf(report, _("\nremoved: %s"), filename_safe); ++ free(filename_safe); } else if (node->checked&NODE_CHANGED) { - report_printf(report, _("\nchanged: %s"),(node->new_data)->filename); -+ report_printf(report, _("\nchanged: %s"),filename_safe); ++ char *filename = (node->new_data)->filename; ++ char *filename_safe = stresc(filename); ++ report_printf(report, _("\nchanged: %s"), filename_safe); ++ free(filename_safe); } } -+ free(filename_safe); } - +@@ -154,11 +180,14 @@ static void print_line_plain(report_t* r static void print_report_dbline_attributes_plain(report_t *report, db_line* oline, db_line* nline, DB_ATTR_TYPE report_attrs) { -@@ -158,7 +174,9 @@ static void print_report_dbline_attributes_plain(report_t *report, db_line* olin + if (report_attrs) { + char *file_type = get_file_type_string((nline==NULL?oline:nline)->perm); ++ db_line* line = nline==NULL?oline:nline; + report_printf(report, "\n"); if (file_type) { report_printf(report, "%s: ", file_type); } - report_printf(report, "%s\n", (nline==NULL?oline:nline)->filename); -+ char *filename_safe = stresc((nline==NULL?oline:nline)->filename); ++ char *filename_safe = stresc(line->filename); + report_printf(report, "%s\n", filename_safe); + free(filename_safe); print_dbline_attrs(report, oline, nline, report_attrs, _print_attribute); } -@@ -195,9 +213,11 @@ static void print_report_details_plain(report_t *report, seltree* node) { +@@ -195,9 +224,11 @@ static void print_report_details_plain(r static void print_report_diff_attrs_entries_plain(report_t *report) { for(int i = 0; i < report->num_diff_attrs_entries; ++i) { char *str = NULL; -+ char *entry_safe = stresc(report->diff_attrs_entries[i].entry); ++ char *entry_safe = stresc(report->diff_attrs_entries[i].entry); report_printf(report, "Entry %s in databases has different attributes: %s\n", - report->diff_attrs_entries[i].entry, + entry_safe, @@ -384,11 +355,10 @@ index c87fc72..7d8a746 100644 free(str); } report->num_diff_attrs_entries = 0; -diff --git a/src/util.c b/src/util.c -index 87f6801..f5c5e60 100644 ---- a/src/util.c -+++ b/src/util.c -@@ -105,6 +105,40 @@ int cmpurl(url_t* u1,url_t* u2) +diff -up aide-0.18.6/src/util.c.orig aide-0.18.6/src/util.c +--- aide-0.18.6/src/util.c.orig 2025-08-19 11:35:36.084823997 +0200 ++++ aide-0.18.6/src/util.c 2025-08-19 11:35:36.082823977 +0200 +@@ -105,6 +105,41 @@ int cmpurl(url_t* u1,url_t* u2) return RETOK; } @@ -425,22 +395,8 @@ index 87f6801..f5c5e60 100644 +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) { -diff --git a/ChangeLog b/ChangeLog -index 69a6fd5..1ed4754 100644 ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,3 +1,7 @@ -+2025-08-07 Hannes von Haugwitz -+ * Escape control characters in report and log output (CVE-2025-54389), -+ thanks to Rajesh Pangare for reporting this issue -+ - 2023-08-01 Hannes von Haugwitz - * Release aide 0.18.6 - --- -2.31.1 - diff --git a/SOURCES/gnutls.patch b/gnutls.patch similarity index 100% rename from SOURCES/gnutls.patch rename to gnutls.patch diff --git a/lowercase-groupnames.patch b/lowercase-groupnames.patch new file mode 100644 index 0000000..4eb98ae --- /dev/null +++ b/lowercase-groupnames.patch @@ -0,0 +1,21 @@ +diff -up aide-0.18.6/src/conf_lex.l.orig aide-0.18.6/src/conf_lex.l +--- aide-0.18.6/src/conf_lex.l.orig 2025-10-14 08:06:03.148161714 +0200 ++++ aide-0.18.6/src/conf_lex.l 2025-10-14 08:06:52.742286876 +0200 +@@ -5,8 +5,6 @@ G [a-zA-Z0-9] + V [a-zA-Z_]+[a-zA-Z0-9_]* + E [\ ]*"="[\ ]* + +-O [a-z_] +- + %{ + + #define YYDEBUG 1 +@@ -483,7 +481,7 @@ LOG_LEVEL lex_log_level = LOG_LEVEL_CONF + return (CONFIGOPTION); + } + +-({O})+ { ++[a-z]+(_[a-z]+)+ { + log_msg(LOG_LEVEL_ERROR,"%s:%d: unknown config option: '%s' (line: '%s')", conf_filename, conf_linenumber, conftext, conf_linebuf); + exit(INVALID_CONFIGURELINE_ERROR); + } diff --git a/sources b/sources new file mode 100644 index 0000000..aab41a4 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (aide-0.18.6.tar.gz) = c0e7c366029a401bce4cf44762caecada4d4831bfc2f00ebab6cb818ba259fae5409fdfcc7386d2bc9ca91a8e8fe0eb78927205bc75513578b8a3ccd17183744