From a631510d4f669dbfa96fb6aa773d034e4d7ce4c2 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 22 Sep 2020 16:06:17 +0800 Subject: [PATCH] crimson/mon: do not set_value() again once the continuation consuming the stored value of the associated future, we cannot set_value() again. otherwise, ASan complains that we are accessing the memory on heap after it is freed. in this change, std::optional<> is used for holding promise, once the promise is fulfilled, `auth_done` is reset to prevent another call of `set_value()` or `set_exception()`. Signed-off-by: Kefu Chai --- src/crimson/mon/MonClient.cc | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/crimson/mon/MonClient.cc b/src/crimson/mon/MonClient.cc index 4c5bdda4b6ebf..6abae727ed74e 100644 --- a/src/crimson/mon/MonClient.cc +++ b/src/crimson/mon/MonClient.cc @@ -110,7 +110,7 @@ private: using clock_t = seastar::lowres_system_clock; clock_t::time_point auth_start; crimson::auth::method_t auth_method = 0; - seastar::promise auth_done; + std::optional> auth_done; // v1 and v2 const AuthRegistry& auth_registry; crimson::net::ConnectionRef conn; @@ -325,7 +325,8 @@ seastar::future Connection::authenticate_v2() { auth_start = seastar::lowres_system_clock::now(); return conn->send(make_message()).then([this] { - return auth_done.get_future(); + auth_done.emplace(); + return auth_done->get_future(); }); } @@ -397,7 +398,10 @@ Connection::handle_auth_done(uint64_t new_global_id, secret_t connection_secret; int r = auth->handle_response(0, p, &session_key, &connection_secret); conn->set_last_keepalive_ack(auth_start); - auth_done.set_value(auth_result_t::success); + if (auth_done) { + auth_done->set_value(auth_result_t::success); + auth_done.reset(); + } return {session_key, connection_secret, r}; } @@ -418,7 +422,8 @@ int Connection::handle_auth_bad_method(uint32_t old_auth_method, if (p == auth_supported.end()) { logger().error("server allowed_methods {} but i only support {}", allowed_methods, auth_supported); - auth_done.set_exception(std::system_error(make_error_code( + assert(auth_done); + auth_done->set_exception(std::system_error(make_error_code( crimson::net::error::negotiation_failure))); return -EACCES; } @@ -431,8 +436,10 @@ void Connection::close() { reply.set_value(Ref(nullptr)); reply = {}; - auth_done.set_value(auth_result_t::canceled); - auth_done = {}; + if (auth_done) { + auth_done->set_value(auth_result_t::canceled); + auth_done.reset(); + } if (conn && !std::exchange(closed, true)) { conn->mark_down(); } -- 2.39.5