From: Oguzhan Ozmen Date: Thu, 19 Feb 2026 01:42:54 +0000 (+0000) Subject: rgw/beast: use strand executor for timeout timer to prevent concurrent socket access X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=86ad0b891b040ab4c2e80e0d0577e9b1d080679a;p=ceph.git rgw/beast: use strand executor for timeout timer to prevent concurrent socket access The timeout_timer in AsioFrontend::on_accept() was constructed with context.get_executor(), which dispatches the timeout handler to the raw io_context. Since each connection's coroutine runs on a strand (via make_strand(context)), this allowed the timeout handler to execute concurrently with the coroutine on a different thread. When the timeout fires, timeout_handler calls socket.cancel() and socket.shutdown() racing with the coroutine's async_read_header(), async_write(), or async_read_some() on the same socket and buffer. This can corrupt the flat_static_buffer's internal pointers, leading to SIGSEGV in the Beast HTTP parser. Fix by constructing the timeout_timer with yield.get_executor(), which returns the coroutine's strand executor. This ensures the timeout handler is serialized with the coroutine, preventing concurrent access to the socket and buffer. Fixes: https://tracker.ceph.com/issues/75031 Signed-off-by: Oguzhan Ozmen --- diff --git a/src/rgw/rgw_asio_frontend.cc b/src/rgw/rgw_asio_frontend.cc index 4c0ab7f29528..19fe534b7a4d 100644 --- a/src/rgw/rgw_asio_frontend.cc +++ b/src/rgw/rgw_asio_frontend.cc @@ -1198,7 +1198,7 @@ void AsioFrontend::on_accept(Listener& l, tcp::socket stream) auto c = connections.add(*conn); // wrap the tcp stream in an ssl stream boost::asio::ssl::stream stream{conn->socket, *ssl_ctx}; - auto timeout = timeout_timer{context.get_executor(), request_timeout, conn}; + auto timeout = timeout_timer{yield.get_executor(), request_timeout, conn}; // do ssl handshake boost::system::error_code ec; timeout.start(); @@ -1231,7 +1231,7 @@ void AsioFrontend::on_accept(Listener& l, tcp::socket stream) [this, s=std::move(stream)] (boost::asio::yield_context yield) mutable { auto conn = boost::intrusive_ptr{new Connection(std::move(s))}; auto c = connections.add(*conn); - auto timeout = timeout_timer{context.get_executor(), request_timeout, conn}; + auto timeout = timeout_timer{yield.get_executor(), request_timeout, conn}; boost::system::error_code ec; handle_connection(context, env, conn->socket, timeout, header_limit, conn->buffer, false, pause_mutex, scheduler.get(),