From 4f41994c13741b8ffe0c0cc9f6474eabc1293d89 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Wed, 5 May 2021 11:26:12 -0700 Subject: [PATCH] [flang] Fix race condition in runtime The code that initializes the default units 5 & 6 had a race condition that would allow threads access to the unit map before it had been populated. Also add some missing calls to va_end() that will never be called (they're in program abort situations) but might elicit warnings if absent. Differential Revision: https://reviews.llvm.org/D101928 --- flang/runtime/io-error.cpp | 2 ++ flang/runtime/terminator.cpp | 1 + flang/runtime/unit.cpp | 10 +++++++--- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/flang/runtime/io-error.cpp b/flang/runtime/io-error.cpp index 9c4a5c7348df..bc835bad1dc1 100644 --- a/flang/runtime/io-error.cpp +++ b/flang/runtime/io-error.cpp @@ -36,12 +36,14 @@ void IoErrorHandler::SignalError(int iostatOrErrno, const char *msg, ...) { va_start(ap, msg); std::vsnprintf(buffer, sizeof buffer, msg, ap); ioMsg_ = SaveDefaultCharacter(buffer, std::strlen(buffer) + 1, *this); + va_end(ap); } } } else if (msg) { va_list ap; va_start(ap, msg); CrashArgs(msg, ap); + va_end(ap); } else if (const char *errstr{IostatErrorString(iostatOrErrno)}) { Crash(errstr); } else { diff --git a/flang/runtime/terminator.cpp b/flang/runtime/terminator.cpp index ed59b1d33ba2..24b61ea05034 100644 --- a/flang/runtime/terminator.cpp +++ b/flang/runtime/terminator.cpp @@ -16,6 +16,7 @@ namespace Fortran::runtime { va_list ap; va_start(ap, message); CrashArgs(message, ap); + va_end(ap); } static void (*crashHandler)(const char *, int, const char *, va_list &){ diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp index 78fa216b4099..646908f51d92 100644 --- a/flang/runtime/unit.cpp +++ b/flang/runtime/unit.cpp @@ -205,16 +205,20 @@ UnitMap &ExternalFileUnit::GetUnitMap() { } Terminator terminator{__FILE__, __LINE__}; IoErrorHandler handler{terminator}; - unitMap = New{terminator}().release(); - ExternalFileUnit &out{ExternalFileUnit::CreateNew(6, terminator)}; + UnitMap *newUnitMap{New{terminator}().release()}; + bool wasExtant{false}; + ExternalFileUnit &out{newUnitMap->LookUpOrCreate(6, terminator, wasExtant)}; + RUNTIME_CHECK(terminator, !wasExtant); out.Predefine(1); out.SetDirection(Direction::Output, handler); defaultOutput = &out; - ExternalFileUnit &in{ExternalFileUnit::CreateNew(5, terminator)}; + ExternalFileUnit &in{newUnitMap->LookUpOrCreate(5, terminator, wasExtant)}; + RUNTIME_CHECK(terminator, !wasExtant); in.Predefine(0); in.SetDirection(Direction::Input, handler); defaultInput = ∈ // TODO: Set UTF-8 mode from the environment + unitMap = newUnitMap; return *unitMap; }