From b671e800503266de09ca5dd2254bc424755882a4 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 6f97cb532..53d3965b8 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); } @@ -123,6 +129,13 @@ bool ConsoleHandler::ExecuteScriptHelper(const HttpRequest& request, HttpRespons 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) @@ -197,6 +210,13 @@ bool ConsoleHandler::AutocompleteScriptHelper(const HttpRequest& request, HttpRe 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 30fb98f2e..43006128f 100644 --- a/lib/remote/consolehandler.hpp +++ b/lib/remote/consolehandler.hpp @@ -5,12 +5,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;