From 560e511b9c9b9877fd125060da4d056b3715f3b9 Mon Sep 17 00:00:00 2001
From: Carsten Patzke <carsten.patzke@desy.de>
Date: Thu, 9 Apr 2020 22:07:18 +0200
Subject: [PATCH] [Receiver] Fixed use after free bug

---
 receiver/src/main.cpp                         | 25 ++++++++++++-------
 .../receiver_data_server.h                    |  1 +
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/receiver/src/main.cpp b/receiver/src/main.cpp
index cadcd9695..e09fefd4d 100644
--- a/receiver/src/main.cpp
+++ b/receiver/src/main.cpp
@@ -20,13 +20,18 @@ asapo::Error ReadConfigFile(int argc, char* argv[]) {
     return factory.SetConfig(argv[1]);
 }
 
+void AddDataServers(const asapo::ReceiverConfig* config, asapo::SharedCache cache,
+                    std::vector<asapo::RdsNetServerPtr>& netServers) {
+    // Add TCP
+    netServers.emplace_back(new asapo::RdsTcpServer("0.0.0.0:" + std::to_string(config->dataserver.listen_port)));
+}
+
 std::vector<std::thread> StartDataServers(const asapo::ReceiverConfig* config, asapo::SharedCache cache,
                                           asapo::Error* error) {
     std::vector<asapo::RdsNetServerPtr> netServers;
     std::vector<std::thread> dataServerThreads;
 
-    // Add TCP
-    netServers.emplace_back(new asapo::RdsTcpServer("0.0.0.0:" + std::to_string(config->dataserver.listen_port)));
+    AddDataServers(config, cache, netServers);
 
     for (auto& server : netServers) {
         *error = server->Initialize();
@@ -37,13 +42,15 @@ std::vector<std::thread> StartDataServers(const asapo::ReceiverConfig* config, a
 
     dataServerThreads.reserve(netServers.size());
     for (auto& server : netServers) {
-        dataServerThreads.emplace_back(std::thread([config, cache, &server] {
-            asapo::ReceiverDataServer data_server{
-                std::move(server),
-                config->log_level,
-                cache,
-                config->dataserver};
-            data_server.Run();
+        // Allocate the server here in order to make sure all variables are still available
+        auto data_server = new asapo::ReceiverDataServer{
+            std::move(server),
+            config->log_level,
+            cache,
+            config->dataserver};
+        dataServerThreads.emplace_back(std::thread([data_server] {
+            // We use a std::unique_ptr here in order to clean up the data_server once Run() is done.
+            std::unique_ptr<asapo::ReceiverDataServer>(data_server)->Run();
         }));
     }
 
diff --git a/receiver/src/receiver_data_server/receiver_data_server.h b/receiver/src/receiver_data_server/receiver_data_server.h
index f26a49ac5..e2de13fd4 100644
--- a/receiver/src/receiver_data_server/receiver_data_server.h
+++ b/receiver/src/receiver_data_server/receiver_data_server.h
@@ -20,6 +20,7 @@ class ReceiverDataServer {
   public:
     explicit ReceiverDataServer(std::unique_ptr<RdsNetServer> net_server, LogLevel log_level, SharedCache data_cache,
                                 const ReceiverDataServerConfig& config);
+
     std::unique_ptr<RequestPool> request_pool__;
     std::unique_ptr<RdsNetServer> net__;
     const AbstractLogger* log__;
-- 
GitLab