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

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new 62eef4e52af branch-4.1: [fix](cloud) Prevent FDB CloudUT ASAN 
getentropy crash #67316 (#68451)
62eef4e52af is described below

commit 62eef4e52af1e6c9da693ec9ab0ca87b648186b6
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Sep 24 19:32:19 2026 +0800

    branch-4.1: [fix](cloud) Prevent FDB CloudUT ASAN getentropy crash #67316 
(#68451)
    
    Cherry-picked from #67316
    
    Co-authored-by: Gavin Chou <[email protected]>
---
 cloud/test/CMakeLists.txt          |  37 ++++++++++++
 cloud/test/fdb_getentropy_compat.c | 113 +++++++++++++++++++++++++++++++++++++
 2 files changed, 150 insertions(+)

diff --git a/cloud/test/CMakeLists.txt b/cloud/test/CMakeLists.txt
index ca16bd873bc..4d768601044 100644
--- a/cloud/test/CMakeLists.txt
+++ b/cloud/test/CMakeLists.txt
@@ -83,6 +83,16 @@ add_executable(http_encode_key_test http_encode_key_test.cpp)
 
 add_executable(fdb_injection_test fdb_injection_test.cpp)
 
+# This object supplies a process-local getentropy implementation for an ASAN
+# build/runtime glibc mismatch in CloudUT. Keep it test-only and 
Linux-ASAN-only
+# so production binaries and non-affected test configurations are unchanged.
+# Cloud is a separate CMake project and does not link the BE 
glibc-compatibility
+# objects, so the implementation must be attached explicitly here.
+if (OS_LINUX AND CMAKE_BUILD_TYPE STREQUAL "ASAN")
+    add_library(fdb_getentropy_compat OBJECT fdb_getentropy_compat.c)
+    target_compile_options(fdb_getentropy_compat PRIVATE -fPIC)
+endif()
+
 add_executable(s3_accessor_test s3_accessor_test.cpp)
 
 add_executable(s3_accessor_client_test s3_accessor_client_test.cpp)
@@ -233,6 +243,33 @@ target_link_libraries(bvars_test
     ${FDB_LINKER_FLAGS}
     ${TEST_LINK_LIBS})
 
+# libfdb_c probes getentropy as a weak symbol while initializing its network.
+# In the affected environment, compiler-rt's interceptor makes that probe pass
+# but cannot forward the call to the older runtime libc. Add the compatibility
+# object only to executables that may initialize FDB; ENABLE_EXPORTS puts the
+# strong executable symbol in the dynamic symbol table so libfdb_c resolves to
+# it instead of the unusable interceptor.
+set(FDB_NETWORK_TEST_TARGETS
+    bvars_test
+    document_message_test
+    doris_txn_test
+    fdb_injection_test
+    mem_txn_kv_test
+    meta_service_test
+    recycler_test
+    rpc_kv_bvar_test
+    txn_kv_test
+    txn_lazy_commit_test
+    versioned_value_test)
+
+if (TARGET fdb_getentropy_compat)
+    foreach(FDB_NETWORK_TEST_TARGET ${FDB_NETWORK_TEST_TARGETS})
+        target_sources(${FDB_NETWORK_TEST_TARGET}
+            PRIVATE $<TARGET_OBJECTS:fdb_getentropy_compat>)
+        set_target_properties(${FDB_NETWORK_TEST_TARGET} PROPERTIES 
ENABLE_EXPORTS ON)
+    endforeach()
+endif()
+
 install(FILES
     ${BASE_DIR}/script/run_all_tests.sh
     ${BASE_DIR}/conf/fdb.cluster
diff --git a/cloud/test/fdb_getentropy_compat.c 
b/cloud/test/fdb_getentropy_compat.c
new file mode 100644
index 00000000000..458e904bae6
--- /dev/null
+++ b/cloud/test/fdb_getentropy_compat.c
@@ -0,0 +1,113 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#if !defined(SYS_getrandom) && defined(__NR_getrandom)
+#define SYS_getrandom __NR_getrandom
+#endif
+
+// Why this compatibility symbol is needed:
+//
+// CloudUT ASAN executables are built against glibc 2.27 and run against glibc
+// 2.17. The ASAN runtime exports a getentropy interceptor, so libfdb_c's weak
+// symbol check concludes that getentropy is available. At runtime, however,
+// the interceptor cannot resolve a next libc implementation (RTLD_NEXT is
+// null on glibc 2.17) and calling it jumps to address zero.
+//
+// This file is linked only into Linux ASAN test executables that initialize
+// the FDB network. Its strong, exported symbol gives libfdb_c a valid target
+// in those processes. Calling the kernel directly is important: forwarding to
+// a libc entropy function could enter the same interceptor path again.
+
+// Build headers may define SYS_getrandom even when an older worker kernel does
+// not implement it. Fall back to /dev/urandom only when the syscall reports
+// ENOSYS.
+static int fill_from_urandom(unsigned char* output, size_t length) {
+    int fd;
+    do {
+        fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
+    } while (fd < 0 && errno == EINTR);
+    if (fd < 0) {
+        return -1;
+    }
+
+    while (length > 0) {
+        const ssize_t bytes_read = read(fd, output, length);
+        if (bytes_read > 0) {
+            output += bytes_read;
+            length -= (size_t)bytes_read;
+            continue;
+        }
+        if (bytes_read < 0 && errno == EINTR) {
+            continue;
+        }
+
+        const int saved_errno = bytes_read == 0 ? EIO : errno;
+        close(fd);
+        errno = saved_errno;
+        return -1;
+    }
+
+    return close(fd);
+}
+
+int getentropy(void* buffer, size_t length) {
+    // Match the getentropy(3) contract. FDB requests small buffers, but 
keeping
+    // the standard 256-byte limit makes this a safe process-wide replacement.
+    if (length > 256) {
+        errno = EIO;
+        return -1;
+    }
+
+    unsigned char* output = (unsigned char*)buffer;
+
+#if defined(SYS_getrandom)
+    // Use syscall rather than libc getrandom/getentropy so this implementation
+    // cannot recurse through an ASAN interceptor.
+    while (length > 0) {
+        const long bytes_read = syscall(SYS_getrandom, output, length, 0);
+        if (bytes_read > 0) {
+            output += bytes_read;
+            length -= (size_t)bytes_read;
+            continue;
+        }
+        if (bytes_read < 0 && errno == EINTR) {
+            continue;
+        }
+        if (bytes_read < 0 && errno == ENOSYS) {
+            break;
+        }
+        if (bytes_read == 0) {
+            errno = EIO;
+        }
+        return -1;
+    }
+
+    if (length == 0) {
+        return 0;
+    }
+#endif
+
+    return fill_from_urandom(output, length);
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to