From 0242f056665d3003b59d1fdef446e0a99a1b9f32 Mon Sep 17 00:00:00 2001 From: MarcZX10 <67475268+MarcZX10@users.noreply.github.com> Date: Sun, 25 Oct 2026 02:27:17 +0000 Subject: [PATCH 1/2] fix(libc): give ctime's unrepresentable-time text a buffer per thread ctime returns a thread-local buffer for every time it formats, but the text for a time localtime cannot represent was written to a function-local static shared by all threads. Two threads calling ctime on such a time raced on it: ThreadSanitizer reports a data race at Time.cpp:608, and the returned pointers were the same. The fallback buffer is now thread-local like the others. --- core/libs/prx/libc/src/Time.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/libs/prx/libc/src/Time.cpp b/core/libs/prx/libc/src/Time.cpp index 14a1b8bc68..1be3104e39 100644 --- a/core/libs/prx/libc/src/Time.cpp +++ b/core/libs/prx/libc/src/Time.cpp @@ -604,7 +604,7 @@ char* APS5_VABI asctime_nid_postfix(const GuestTm* timeptr) { char* APS5_VABI ctime_nid_postfix(const int64_t* timer) { if (const GuestTm* local = localtime_nid_postfix(timer)) return asctime_nid_postfix(local); - static char unknown[26]; + static thread_local char unknown[26]; std::memcpy(unknown, "??? ??? ?? ??:??:?? ????\n", sizeof(unknown)); errno = EINVAL; return unknown; From 1e5459443d51b6ca3bad8c4aa3a2b523e4e842ad Mon Sep 17 00:00:00 2001 From: MarcZX10 <67475268+MarcZX10@users.noreply.github.com> Date: Sun, 25 Oct 2026 02:27:32 +0000 Subject: [PATCH 2/2] test(libc): require a separate ctime buffer per thread for an unrepresentable time Two live threads and the caller each call ctime on a time localtime rejects and must receive three distinct buffers. The case fails on current main because they share one static buffer. --- core/libs/tests/GuestTimeConversion.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core/libs/tests/GuestTimeConversion.cpp b/core/libs/tests/GuestTimeConversion.cpp index abc96e55f2..d51d617b19 100644 --- a/core/libs/tests/GuestTimeConversion.cpp +++ b/core/libs/tests/GuestTimeConversion.cpp @@ -496,6 +496,21 @@ int main() { *__error_nid_postfix() = 0; Require(std::strcmp(ctime_nid_postfix(&underflow), "??? ??? ?? ??:??:?? ????\n") == 0 && *__error_nid_postfix() == 22, "ctime of an unrepresentable time did not report it"); + { + std::barrier finish(3); + std::array texts{}; + std::array readers; + for (std::size_t index = 0; index < readers.size(); ++index) { + readers[index] = std::thread([&, index] { + texts[index] = ctime_nid_postfix(&underflow); + finish.arrive_and_wait(); + }); + } + const char* own = ctime_nid_postfix(&underflow); + finish.arrive_and_wait(); + Require(texts[0] != texts[1] && texts[0] != own && texts[1] != own, "ctime of an unrepresentable time shared one buffer between threads"); + for (auto& reader : readers) reader.join(); + } constexpr std::int64_t latest = std::numeric_limits::max(); constexpr std::int64_t earliest = std::numeric_limits::min();