From 0d376b5d5a64599d2f641471ac08c6d1678fdbbf Mon Sep 17 00:00:00 2001 From: Julian Brost Date: Wed, 7 Jan 2026 12:43:16 +0100 Subject: [PATCH] /v1/console: prevent concurrent use of the same session by multiple requests If there are such requests, without this change, they would all be allowed and processed, resulting in unsafe concurrent (write) access to these data structures, which can ultimately crash the daemon or lead to other unintended behavior. --- lib/remote/consolehandler.cpp | 20 ++++++++++++++++++++ lib/remote/consolehandler.hpp | 2 ++ 2 files changed, 22 insertions(+) diff --git a/lib/remote/consolehandler.cpp b/lib/remote/consolehandler.cpp index 2b0e068ad30..9490d2420fa 100644 --- a/lib/remote/consolehandler.cpp +++ b/lib/remote/consolehandler.cpp @@ -31,6 +31,12 @@ static void ScriptFrameCleanupHandler() std::vector cleanup_keys; for (auto& kv : l_ApiScriptFrames) { + std::unique_lock frameLock(kv.second->Mutex, std::try_to_lock); + if (!frameLock) { + // If the frame is locked, it's in use, don't expire it this time. + continue; + } + if (kv.second->Seen < Utility::GetTime() - 1800) cleanup_keys.push_back(kv.first); } @@ -124,6 +130,13 @@ bool ConsoleHandler::ExecuteScriptHelper(const HttpApiRequest& request, HttpApiR EnsureFrameCleanupTimer(); auto lsf = GetOrCreateScriptFrame(session); + + std::unique_lock frameLock(lsf->Mutex, std::try_to_lock); + if (!frameLock) { + HttpUtility::SendJsonError(response, request.Params(), 409, "Session is currently in use by another request."); + return true; + } + lsf->Seen = Utility::GetTime(); if (!lsf->Locals) @@ -198,6 +211,13 @@ bool ConsoleHandler::AutocompleteScriptHelper(const HttpApiRequest& request, Htt EnsureFrameCleanupTimer(); auto lsf = GetOrCreateScriptFrame(session); + + std::unique_lock frameLock(lsf->Mutex, std::try_to_lock); + if (!frameLock) { + HttpUtility::SendJsonError(response, request.Params(), 409, "Session is currently in use by another request."); + return true; + } + lsf->Seen = Utility::GetTime(); if (!lsf->Locals) diff --git a/lib/remote/consolehandler.hpp b/lib/remote/consolehandler.hpp index e222e752110..17f8a71c1e0 100644 --- a/lib/remote/consolehandler.hpp +++ b/lib/remote/consolehandler.hpp @@ -6,12 +6,14 @@ #include "remote/httphandler.hpp" #include "base/scriptframe.hpp" +#include namespace icinga { struct ApiScriptFrame { + std::mutex Mutex; double Seen{0}; int NextLine{1}; std::map Lines;