From 888b84666c96ffc43595bbdb3ab27982bd748b4c Mon Sep 17 00:00:00 2001 From: Hiroshi Hatake Date: Fri, 21 Aug 2026 15:28:33 +0900 Subject: [PATCH 1/2] in_winevtlog: Plug a crash path Signed-off-by: Hiroshi Hatake --- plugins/in_winevtlog/pack.c | 73 ++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/plugins/in_winevtlog/pack.c b/plugins/in_winevtlog/pack.c index 3a64e2f25e9..6d08567a1bb 100644 --- a/plugins/in_winevtlog/pack.c +++ b/plugins/in_winevtlog/pack.c @@ -302,38 +302,69 @@ static int pack_systemtime(struct winevtlog_config *ctx, SYSTEMTIME *st) _locale_t locale; DYNAMIC_TIME_ZONE_INFORMATION dtzi; SYSTEMTIME st_local; + struct tm tm; + + if (st == NULL) { + return -1; + } _tzset(); GetDynamicTimeZoneInformation(&dtzi); + if (!SystemTimeToTzSpecificLocalTimeEx(&dtzi, st, &st_local)) { + flb_plg_debug(ctx->ins, + "failed to convert SYSTEMTIME to local time: error=%u", + GetLastError()); + return -1; + } + + /* SYSTEMTIME values come straight from event data, so they can hold + * out-of-range fields. The MSVC secure CRT invokes the invalid + * parameter handler when _strftime_l() receives an out-of-range + * struct tm, which terminates the whole process with + * STATUS_STACK_BUFFER_OVERRUN (0xc0000409, FAST_FAIL_INVALID_ARG). + * Validate every field before formatting. + */ + if (st_local.wYear < 1601 || st_local.wYear > 30827 || + st_local.wMonth < 1 || st_local.wMonth > 12 || + st_local.wDay < 1 || st_local.wDay > 31 || + st_local.wHour > 23 || st_local.wMinute > 59 || + st_local.wSecond > 59 || st_local.wDayOfWeek > 6) { + flb_plg_debug(ctx->ins, + "dropping out-of-range SYSTEMTIME value: " + "%u-%u-%u %u:%u:%u (dow=%u)", + st_local.wYear, st_local.wMonth, st_local.wDay, + st_local.wHour, st_local.wMinute, st_local.wSecond, + st_local.wDayOfWeek); + return -1; + } + locale = _get_current_locale(); if (locale == NULL) { return -1; } - if (st != NULL) { - SystemTimeToTzSpecificLocalTimeEx(&dtzi, st, &st_local); - - struct tm tm = {st_local.wSecond, - st_local.wMinute, - st_local.wHour, - st_local.wDay, - st_local.wMonth-1, - st_local.wYear-1900, - st_local.wDayOfWeek, 0, -1}; - len = _strftime_l(buf, 64, FORMAT_ISO8601, &tm, locale); - if (len == 0) { - flb_errno(); - _free_locale(locale); - return -1; - } - _free_locale(locale); - flb_log_event_encoder_append_body_string(ctx->log_encoder, buf, len); - } - else { + memset(&tm, 0, sizeof(tm)); + tm.tm_sec = st_local.wSecond; + tm.tm_min = st_local.wMinute; + tm.tm_hour = st_local.wHour; + tm.tm_mday = st_local.wDay; + tm.tm_mon = st_local.wMonth - 1; + tm.tm_year = st_local.wYear - 1900; + tm.tm_wday = st_local.wDayOfWeek; + tm.tm_yday = 0; + tm.tm_isdst = -1; + + len = _strftime_l(buf, 64, FORMAT_ISO8601, &tm, locale); + if (len == 0) { + flb_errno(); + _free_locale(locale); return -1; } + _free_locale(locale); + + flb_log_event_encoder_append_body_string(ctx->log_encoder, buf, len); return 0; } @@ -402,7 +433,7 @@ static int pack_filetime(struct winevtlog_config *ctx, ULONGLONG filetime) offset_hours, offset_minutes); - if (len <= 0) { + if ((int) len <= 0) { return -1; } From 06dc91614209f3d5e941f32d7871d531a65d12dd Mon Sep 17 00:00:00 2001 From: Hiroshi Hatake Date: Fri, 21 Aug 2026 15:45:30 +0900 Subject: [PATCH 2/2] in_winevtlog: Address review comments Signed-off-by: Hiroshi Hatake --- plugins/in_winevtlog/pack.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/in_winevtlog/pack.c b/plugins/in_winevtlog/pack.c index 6d08567a1bb..18f22aba580 100644 --- a/plugins/in_winevtlog/pack.c +++ b/plugins/in_winevtlog/pack.c @@ -310,7 +310,12 @@ static int pack_systemtime(struct winevtlog_config *ctx, SYSTEMTIME *st) _tzset(); - GetDynamicTimeZoneInformation(&dtzi); + if (GetDynamicTimeZoneInformation(&dtzi) == TIME_ZONE_ID_INVALID) { + flb_plg_debug(ctx->ins, + "failed to get dynamic timezone information: error=%u", + GetLastError()); + return -1; + } if (!SystemTimeToTzSpecificLocalTimeEx(&dtzi, st, &st_local)) { flb_plg_debug(ctx->ins, @@ -324,9 +329,10 @@ static int pack_systemtime(struct winevtlog_config *ctx, SYSTEMTIME *st) * parameter handler when _strftime_l() receives an out-of-range * struct tm, which terminates the whole process with * STATUS_STACK_BUFFER_OVERRUN (0xc0000409, FAST_FAIL_INVALID_ARG). - * Validate every field before formatting. + * Validate every field before formatting. The UCRT only accepts + * tm_year values up to 8099, so cap the year at 9999. */ - if (st_local.wYear < 1601 || st_local.wYear > 30827 || + if (st_local.wYear < 1601 || st_local.wYear > 9999 || st_local.wMonth < 1 || st_local.wMonth > 12 || st_local.wDay < 1 || st_local.wDay > 31 || st_local.wHour > 23 || st_local.wMinute > 59 ||