From 5e91db569ae0986e8cd738f49080d61b832e50b2 Mon Sep 17 00:00:00 2001 From: Leonardo Grasso Date: Thu, 9 Apr 2026 11:35:37 +0200 Subject: [PATCH] fix(userspace): replace gmtime/localtime with reentrant variants gmtime() and localtime() return pointers to a shared static buffer, making them unsafe in multi-threaded contexts. Replace all call sites with gmtime_r() and localtime_r() which use caller-provided buffers. Signed-off-by: Leonardo Grasso --- userspace/engine/formats.cpp | 4 +++- userspace/engine/logger.cpp | 10 ++++++---- userspace/falco/falco_outputs.cpp | 4 +++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/userspace/engine/formats.cpp b/userspace/engine/formats.cpp index c266e031..0fcf89f9 100644 --- a/userspace/engine/formats.cpp +++ b/userspace/engine/formats.cpp @@ -98,7 +98,9 @@ std::string falco_formats::format_event(sinsp_evt *evt, char time_ns[12]; // sizeof ".sssssssssZ" std::string iso8601evttime; - strftime(time_sec, sizeof(time_sec), "%FT%T", gmtime(&evttime)); + struct tm tm_buf; + gmtime_r(&evttime, &tm_buf); + strftime(time_sec, sizeof(time_sec), "%FT%T", &tm_buf); snprintf(time_ns, sizeof(time_ns), ".%09luZ", evt->get_ts() % 1000000000); iso8601evttime = time_sec; iso8601evttime += time_ns; diff --git a/userspace/engine/logger.cpp b/userspace/engine/logger.cpp index 103a7e60..ad20d3de 100644 --- a/userspace/engine/logger.cpp +++ b/userspace/engine/logger.cpp @@ -122,14 +122,16 @@ void falco_logger::log(falco_logger::level priority, const std::string&& msg) { std::time_t result = std::time(nullptr); if(falco_logger::time_format_iso_8601) { char buf[sizeof "YYYY-MM-DDTHH:MM:SS-0000"]; - const struct tm* gtm = std::gmtime(&result); - if(gtm != NULL && (strftime(buf, sizeof(buf), "%FT%T%z", gtm) != 0)) { + struct tm gtm; + if(gmtime_r(&result, >m) != NULL && + (strftime(buf, sizeof(buf), "%FT%T%z", >m) != 0)) { fprintf(stderr, "%s: %s", buf, copy.c_str()); } } else { - const struct tm* ltm = std::localtime(&result); + struct tm ltm; + localtime_r(&result, <m); char tstr[std::size("WWW MMM DD HH:mm:ss YYYY")]; - std::strftime(std::data(tstr), std::size(tstr), "%a %b %d %H:%M:%S %Y", ltm); + std::strftime(std::data(tstr), std::size(tstr), "%a %b %d %H:%M:%S %Y", <m); fprintf(stderr, "%s: %s", tstr, copy.c_str()); } } diff --git a/userspace/falco/falco_outputs.cpp b/userspace/falco/falco_outputs.cpp index aed55e19..8a4a3629 100644 --- a/userspace/falco/falco_outputs.cpp +++ b/userspace/falco/falco_outputs.cpp @@ -181,7 +181,9 @@ void falco_outputs::handle_msg(uint64_t ts, char time_ns[12]; // sizeof ".sssssssssZ" std::string iso8601evttime; - strftime(time_sec, sizeof(time_sec), "%FT%T", gmtime(&evttime)); + struct tm tm_buf; + gmtime_r(&evttime, &tm_buf); + strftime(time_sec, sizeof(time_sec), "%FT%T", &tm_buf); snprintf(time_ns, sizeof(time_ns), ".%09luZ", ts % 1000000000); iso8601evttime = time_sec; iso8601evttime += time_ns;