Skip to content

/v1/console: prevent concurrent use of the same session by multiple requests#10681

Merged
jschmidt-icinga merged 1 commit into
masterfrom
api-console-missing-lock
Mar 12, 2026
Merged

/v1/console: prevent concurrent use of the same session by multiple requests#10681
jschmidt-icinga merged 1 commit into
masterfrom
api-console-missing-lock

Conversation

@julianbrost
Copy link
Copy Markdown
Member

@julianbrost julianbrost commented Jan 7, 2026

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.

This PR is a follow-up to #10675 adding more required locking.

Tests

I was able to somewhat reliably trigger that race condition using the following command (ab is ApacheBench):

ab -n 100000 -c 64 -A root:icinga -m POST -H 'Accept: application/json' 'https://localhost:5665/v1/console/execute-script?command=1&session=always-the-same'

Before (0f44133)

With the current master, I was able to observe Icinga 2 crashing with a SIGSEGV (typically after around ~10k to ~30k):

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007fcdeaf99752 in std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) ()
   from /lib/x86_64-linux-gnu/libstdc++.so.6
[Current thread is 1 (Thread 0x7fcde91576c0 (LWP 186))]
(gdb) set pagination off
(gdb) bt
#0  0x00007fcdeaf99752 in std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) ()
   from /lib/x86_64-linux-gnu/libstdc++.so.6
#1  0x000055e6996dc065 in std::_Rb_tree_iterator<std::pair<icinga::String const, icinga::String> > std::_Rb_tree<icinga::String, std::pair<icinga::String const, icinga::String>, std::_Select1st<std::pair<icinga::String const, icinga::String> >, std::less<icinga::String>, std::allocator<std::pair<icinga::String const, icinga::String> > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<icinga::String const&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<icinga::String const, icinga::String> >, std::piecewise_construct_t const&, std::tuple<icinga::String const&>&&, std::tuple<>&&) [clone .isra.0] ()
#2  0x000055e69975093e in std::map<icinga::String, icinga::String, std::less<icinga::String>, std::allocator<std::pair<icinga::String const, icinga::String> > >::operator[](icinga::String const&) ()
#3  0x000055e69970a982 in icinga::ConsoleHandler::ExecuteScriptHelper(icinga::HttpApiRequest const&, icinga::HttpApiResponse&, icinga::String const&, icinga::String const&, bool) ()
#4  0x000055e69970b32a in icinga::ConsoleHandler::HandleRequest(boost::intrusive_ptr<icinga::WaitGroup> const&, icinga::HttpApiRequest const&, icinga::HttpApiResponse&, boost::asio::basic_yield_context<boost::asio::executor>&) ()
#5  0x000055e6996f02cb in icinga::HttpHandler::ProcessRequest(boost::intrusive_ptr<icinga::WaitGroup> const&, icinga::HttpApiRequest&, icinga::HttpApiResponse&, boost::asio::basic_yield_context<boost::asio::executor>&) ()
#6  0x000055e6997163e0 in icinga::HttpServerConnection::ProcessMessages(boost::asio::basic_yield_context<boost::asio::executor>) ()
#7  0x000055e699717dbe in boost::coroutines::detail::pull_coroutine_object<boost::coroutines::push_coroutine<void>, void, boost::asio::detail::spawned_coroutine_thread::entry_point<boost::asio::detail::old_spawn_entry_point<boost::asio::io_context::strand, icinga::IoEngine::SpawnCoroutine<boost::asio::io_context::strand, icinga::HttpServerConnection::Start()::{lambda(boost::asio::basic_yield_context<boost::asio::executor>)#1}>(boost::asio::io_context::strand&, icinga::HttpServerConnection::Start()::{lambda(boost::asio::basic_yield_context<boost::asio::executor>)#1})::{lambda(boost::asio::basic_yield_context<boost::asio::executor>)#1}, void (*)()> >, boost::coroutines::basic_standard_stack_allocator<boost::coroutines::stack_traits> >::run() ()
#8  0x00007fcdeabb718f in make_fcontext () from /lib/x86_64-linux-gnu/libboost_context.so.1.83.0
#9  0x0000000000000000 in ?? ()

However, I also observed instances where Icinga 2 stopped responding to ab.

After (0d376b5)

With this PR, Icinga 2 now survives the ab-torture (even multiple runs, so more than 100k requests).

@julianbrost julianbrost added bug Something isn't working area/api REST API core/crash Shouldn't happen, requires attention consider backporting Should be considered for inclusion in a bugfix release labels Jan 7, 2026
@cla-bot cla-bot Bot added the cla/signed label Jan 7, 2026
@julianbrost julianbrost added this to the 2.16.0 milestone Mar 3, 2026
…equests

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.
@julianbrost julianbrost force-pushed the api-console-missing-lock branch from b671e80 to 0d376b5 Compare March 3, 2026 10:33
@julianbrost julianbrost marked this pull request as ready for review March 3, 2026 13:41
@julianbrost julianbrost added backport-to-support/2.15 PRs with this label will automatically be backported to the v2.15 support branch. and removed consider backporting Should be considered for inclusion in a bugfix release labels Mar 3, 2026
Copy link
Copy Markdown
Contributor

@jschmidt-icinga jschmidt-icinga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense.

@jschmidt-icinga jschmidt-icinga merged commit 32ca211 into master Mar 12, 2026
29 checks passed
@jschmidt-icinga jschmidt-icinga deleted the api-console-missing-lock branch March 12, 2026 11:22
@backbot-ci
Copy link
Copy Markdown

backbot-ci Bot commented Mar 12, 2026

Backport failed for support/2.15, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin support/2.15
git worktree add -d .worktree/backport-10681-to-support/2.15 origin/support/2.15
cd .worktree/backport-10681-to-support/2.15
git switch --create backport-10681-to-support/2.15
git cherry-pick -x 0d376b5d5a64599d2f641471ac08c6d1678fdbbf

@yhabteab yhabteab removed the backport-to-support/2.15 PRs with this label will automatically be backported to the v2.15 support branch. label Mar 12, 2026
@jschmidt-icinga jschmidt-icinga added the backport-to-support/2.15 PRs with this label will automatically be backported to the v2.15 support branch. label Mar 12, 2026
@backbot-ci
Copy link
Copy Markdown

backbot-ci Bot commented Mar 12, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api REST API backport-to-support/2.15 PRs with this label will automatically be backported to the v2.15 support branch. bug Something isn't working cla/signed core/crash Shouldn't happen, requires attention

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants