From 936d82d3f1cc3e2fbb21fcc43acefb194b4de9dd 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. (cherry picked from commit 0d376b5d5a64599d2f641471ac08c6d1678fdbbf) --- 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 e432abe8cc8..70912c52f56 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); } @@ -126,6 +132,13 @@ bool ConsoleHandler::ExecuteScriptHelper(boost::beast::http::requestMutex, std::try_to_lock); + if (!frameLock) { + HttpUtility::SendJsonError(response, params, 409, "Session is currently in use by another request."); + return true; + } + lsf->Seen = Utility::GetTime(); if (!lsf->Locals) @@ -201,6 +214,13 @@ bool ConsoleHandler::AutocompleteScriptHelper(boost::beast::http::requestMutex, std::try_to_lock); + if (!frameLock) { + HttpUtility::SendJsonError(response, 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 ba93d000177..93a197c0301 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;