This is an automated email from the ASF dual-hosted git repository.

prozsa pushed a commit to branch branch-4.5.0
in repository https://gitbox.apache.org/repos/asf/impala.git

commit fa07a4bd7c8e679a7458297d058419e4be9c25e2
Author: jasonmfehr <jf...@cloudera.com>
AuthorDate: Wed Feb 5 09:06:19 2025 -0800

    IMPALA-13736: Fix Use-After-Free in ExecutorGroup.RemoveExecutor
    
    The RemoveExecutor() function within the ExecutorGroup class has a
    potential use-after-free bug. Since the function takes an object
    reference as input, the iterator that erases the backend could erase
    the object references by the function input.
    
    This change fixes the issue by storing the necessary data from the
    provided input object and then referencing that stored data after the
    erase has occurred.
    
    Change-Id: If14a3c89ee631ebb05efc9a47745f7e63ab98690
    Reviewed-on: http://gerrit.cloudera.org:8080/22453
    Reviewed-by: Impala Public Jenkins <impala-public-jenk...@cloudera.com>
    Tested-by: Impala Public Jenkins <impala-public-jenk...@cloudera.com>
---
 be/src/scheduling/executor-group-test.cc |  8 ++++++++
 be/src/scheduling/executor-group.cc      | 14 +++++++++++---
 be/src/scheduling/executor-group.h       |  2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/be/src/scheduling/executor-group-test.cc 
b/be/src/scheduling/executor-group-test.cc
index 96a744136..e2f926c48 100644
--- a/be/src/scheduling/executor-group-test.cc
+++ b/be/src/scheduling/executor-group-test.cc
@@ -81,6 +81,14 @@ TEST(ExecutorGroupTest, RemoveExecutor) {
   ASSERT_TRUE(group1.LookUpExecutorIp("host_1", &backend_ip));
   EXPECT_EQ("10.0.0.1", backend_ip);
   ASSERT_FALSE(group1.LookUpExecutorIp("host_2", &backend_ip));
+
+  // When the last executor for a host is be removed from the group, that host 
is also
+  // removed from the group. Asserts that process completes successfully even 
when the
+  // RemoveExecutor function is provided the same object that will be erased.
+  const BackendDescriptorPB* actual_exec1 = 
group1.LookUpBackendDesc(executor1.address());
+  ASSERT_NE(nullptr, actual_exec1);
+  group1.RemoveExecutor(*actual_exec1);
+  ASSERT_EQ(0, group1.NumExecutors());
 }
 
 /// Test removing one of multiple backends on the same host (IMPALA-3944).
diff --git a/be/src/scheduling/executor-group.cc 
b/be/src/scheduling/executor-group.cc
index ba2b597ee..b99eeed86 100644
--- a/be/src/scheduling/executor-group.cc
+++ b/be/src/scheduling/executor-group.cc
@@ -151,14 +151,22 @@ void ExecutorGroup::RemoveExecutor(const 
BackendDescriptorPB& be_desc) {
                 << be_desc.krpc_address();
     return;
   }
+
+  // Copy the data necessary to update the internal state variables since the 
erase call
+  // has the potential to destroy the object referenced by be_desc.
+  const std::string be_hostname = be_desc.address().hostname();
+  const std::string be_ip_address = be_desc.ip_address();
+  const int64_t be_admin_mem_limit = be_desc.admit_mem_limit();
+
   be_descs.erase(remove_it);
-  if (per_executor_admit_mem_limit_ == be_desc.admit_mem_limit()) {
+
+  if (per_executor_admit_mem_limit_ == be_admin_mem_limit) {
     CalculatePerExecutorMemLimitForAdmission();
   }
   if (be_descs.empty()) {
     executor_map_.erase(be_descs_it);
-    executor_ip_map_.erase(be_desc.address().hostname());
-    executor_ip_hash_ring_.RemoveNode(be_desc.ip_address());
+    executor_ip_map_.erase(be_hostname);
+    executor_ip_hash_ring_.RemoveNode(be_ip_address);
   }
 }
 
diff --git a/be/src/scheduling/executor-group.h 
b/be/src/scheduling/executor-group.h
index 208120d09..1e390e020 100644
--- a/be/src/scheduling/executor-group.h
+++ b/be/src/scheduling/executor-group.h
@@ -146,7 +146,7 @@ class ExecutorGroup {
   ExecutorIpAddressMap executor_ip_map_;
 
   /// All executors are kept in a hash ring to allow a consistent mapping from 
filenames
-  /// to executors.
+  /// to executors. Must be updated whenever executor_map_ changes.
   HashRing executor_ip_hash_ring_;
 
   /// The minimum memory limit in bytes for admission across all backends. 
Used by

Reply via email to