]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Fix segfault due to concurrent socket use at timeout 50131/head
authorYixin Jin <yjin77@yahoo.ca>
Wed, 15 Feb 2023 17:08:19 +0000 (17:08 +0000)
committerYixin Jin <yjin77@yahoo.ca>
Wed, 15 Feb 2023 17:32:29 +0000 (17:32 +0000)
This commit fixes a potential segfault risk when
rgw timeout handler works on the socket in one
thread while it is concurrently used by another.
The details of the fix are:

1. Instead of calling socket close(), which resets
descriptor_data in boost::asio socket and risks
segfault due to concurrent use of the socket,
the timeout handler now calls cancel() to abort
all pending ops followed by shutdown() to disable
the underlying transport. The eventual closure of
the socket will be done in the socket destructor.

2. Expose the actual boost::asio socket via get_socket()
from Connection so that the timeout handler can call
cancel() and shutdown() on it, although the socket data
member is already accessible. It allows future expansion
that wants to hide the socket even though it renders the
existing close() less useful.

Fixes: https://tracker.ceph.com/issues/58670
Signed-off-by: Yixin Jin <yjin77@yahoo.ca>
src/rgw/rgw_asio_frontend.cc
src/rgw/rgw_asio_frontend_timer.h

index 000a0bc6a9f163be633f1d28532a6f9682d6820b..c444090192e368aa5857a5e1be85c211bfb6e73f 100644 (file)
@@ -338,6 +338,8 @@ struct Connection : boost::intrusive::list_base_hook<>,
   void close(boost::system::error_code& ec) {
     socket.close(ec);
   }
+
+  tcp_socket& get_socket() { return socket; }
 };
 
 class ConnectionList {
index b7d6a63b46f114fb5debdd042138ef5be1b646fe..bc58790d62986fada91578cb450068aa092162fb 100644 (file)
@@ -20,7 +20,8 @@ struct timeout_handler {
   void operator()(boost::system::error_code ec) {
     if (!ec) { // wait was not canceled
       boost::system::error_code ec_ignored;
-      stream->close(ec_ignored);
+      stream->get_socket().cancel();
+      stream->get_socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec_ignored);
     }
   }
 };