From 580ad606e29057a1faeaf0d3ec402f0a98edf998 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Wed, 14 Oct 2026 09:25:42 +0000 Subject: fix(driver)!: validate lli 23 before PATH execution Check the selected lli only when PATH mode uses -r. Reject missing, mismatched or unreadable versions before compiling or writing IR, and limit version detection to five seconds. Keep unused tools unchecked. Co-Authored-By: Claude Fable 5.1 --- tools/driver/main.cc | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/driver/main.cc b/tools/driver/main.cc index a4616bd..55d666f 100644 --- a/tools/driver/main.cc +++ b/tools/driver/main.cc @@ -7,6 +7,10 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" +#ifdef CPSC_RUN_PATH +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Regex.h" +#endif #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" #include "llvm/Support/raw_ostream.h" @@ -20,6 +24,46 @@ int compilationTerminated() { return 1; } +#ifdef CPSC_RUN_PATH +bool checkLliVersion(llvm::StringRef LliPath) { + llvm::SmallString<256> VersionPath; + if (auto EC = llvm::sys::fs::createTemporaryFile("cpsc-lli-version", "txt", VersionPath)) { + llvm::errs() << "cpsc: fatal error: cannot check lli version: " << EC.message() << "\n"; + return false; + } + llvm::FileRemover TemporaryVersion(VersionPath); + std::string ExecutionError; + int Result = llvm::sys::ExecuteAndWait(LliPath, {LliPath, "--version"}, + std::nullopt, {llvm::StringRef(""), llvm::StringRef(VersionPath), llvm::StringRef("")}, + 5, 0, &ExecutionError); + if (Result != 0) { + llvm::errs() << "cpsc: fatal error: cannot check lli version at '" << LliPath + << "' (status " << Result << ")"; + if (!ExecutionError.empty()) llvm::errs() << ": " << ExecutionError; + llvm::errs() << "\n"; + return false; + } + auto Version = llvm::MemoryBuffer::getFile(VersionPath); + if (!Version) { + llvm::errs() << "cpsc: fatal error: cannot read lli version: " + << Version.getError().message() << "\n"; + return false; + } + llvm::SmallVector Matches; + if (!llvm::Regex("LLVM version ([0-9]+)\\.").match((*Version)->getBuffer(), &Matches)) { + llvm::errs() << "cpsc: fatal error: cannot identify LLVM version of lli at '" + << LliPath << "'; LLVM 23 is required\n"; + return false; + } + if (Matches[1] != "23") { + llvm::errs() << "cpsc: fatal error: -r requires lli from LLVM 23; found LLVM " + << Matches[1] << " at '" << LliPath << "'\n"; + return false; + } + return true; +} +#endif + } // namespace int main(int argc, char **argv) { @@ -73,10 +117,11 @@ int main(int argc, char **argv) { #ifdef CPSC_RUN_PATH auto Lli = llvm::sys::findProgramByName("lli"); if (!Lli) { - llvm::errs() << "cpsc: fatal error: -r requires lli in PATH: " << Lli.getError().message() << "\n"; + llvm::errs() << "cpsc: fatal error: -r requires lli from LLVM 23 in PATH: " << Lli.getError().message() << "\n"; return compilationTerminated(); } LliPath = *Lli; + if (!checkLliVersion(LliPath)) return compilationTerminated(); #elif defined(CPSC_RUN_NONE) llvm::errs() << "cpsc: fatal error: -r is disabled in this build (CPSC_RUN_MODE=NONE)\n"; return compilationTerminated(); -- cgit v1.3.1-4-g156e