From 6faba4c2df869e8302aa607555613cf768a811d1 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Sat, 10 Jan 2026 07:53:29 +0800 Subject: [PATCH] rgw: fix memory leak in RGWHTTPManager thread cleanup Fix memory leak detected by AddressSanitizer in unittest_http_manager. The test was failing with ASan enabled due to rgw_http_req_data objects not being properly cleaned up when the HTTP manager thread exits. ASan reported the following leaks: Direct leak of 17152 byte(s) in 32 object(s) allocated from: #0 operator new(unsigned long) #1 RGWHTTPManager::add_request(RGWHTTPClient*) /ceph/src/rgw/rgw_http_client.cc:946:33 #2 HTTPManager_SignalThread_Test::TestBody() /ceph/src/test/rgw/test_http_manager.cc:132:10 Indirect leak of 768 byte(s) in 32 object(s) allocated from: #0 operator new(unsigned long) #1 rgw_http_req_data::rgw_http_req_data() /ceph/src/rgw/rgw_http_client.cc:52:22 #2 RGWHTTPManager::add_request(RGWHTTPClient*) /ceph/src/rgw/rgw_http_client.cc:946:37 SUMMARY: AddressSanitizer: 17920 byte(s) leaked in 64 allocation(s). Root cause: The rgw_http_req_data class uses reference counting (inherits from RefCountedObject). When a request is unregistered, unregister_request() calls get() to increment the refcount, expecting a corresponding put() to be called later. In manage_pending_requests(), unregistered requests are properly handled with both _unlink_request() and put(). However, in the thread cleanup code (reqs_thread_entry exit path), only _unlink_request() was called without the matching put(), causing a reference count leak. The fix adds the missing put() call in the thread cleanup code to match the reference counting pattern used in manage_pending_requests(). Test results: - Before: 17,920 bytes leaked in 64 allocations - After: 0 leaks, unittest_http_manager passes with ASan Fixes: https://tracker.ceph.com/issues/74762 Signed-off-by: Kefu Chai --- src/rgw/rgw_http_client.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rgw/rgw_http_client.cc b/src/rgw/rgw_http_client.cc index 7e536281a3c..dc798943ee4 100644 --- a/src/rgw/rgw_http_client.cc +++ b/src/rgw/rgw_http_client.cc @@ -1181,6 +1181,7 @@ void *RGWHTTPManager::reqs_thread_entry() std::unique_lock rl{reqs_lock}; for (auto r : unregistered_reqs) { _unlink_request(r); + r->put(); } unregistered_reqs.clear(); -- 2.47.3