]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cmake/boost: build libboost_context with BOOST_USE_ASAN 69660/head
authorKefu Chai <k.chai@proxmox.com>
Tue, 23 Jun 2026 07:46:05 +0000 (15:46 +0800)
committerKefu Chai <k.chai@proxmox.com>
Tue, 23 Jun 2026 22:44:18 +0000 (06:44 +0800)
The ceph-api job failed under ASan: radosgw-admin aborted at startup with a
heap-buffer-overflow in boost.context's fiber resume().

  ==1155842==ERROR: AddressSanitizer: heap-buffer-overflow ... READ of size 8
    #0 boost::context::detail::fiber_activation_record::resume() fiber_ucontext.hpp:153
    #10 RGWSI_Notify::do_start(optional_yield, DoutPrefixProvider const*) svc_notify.cc:261
  0x... is located 8 bytes after 1048-byte region allocated by
    boost::context::detail::fiber_activation_record_initializer()

fiber_activation_record carries three extra members (fake_stack, stack_bottom,
stack_size) only when BOOST_USE_ASAN is defined.  Under WITH_ASAN we build
boost.context with context-impl=ucontext and give consumers BOOST_USE_ASAN and
BOOST_USE_UCONTEXT through Boost::context's INTERFACE_COMPILE_DEFINITIONS, but
we never pass BOOST_USE_ASAN to b2.  So libboost_context, which compiles
fiber_activation_record_initializer() and allocates the record, uses the
smaller no-ASan layout, while consumers that include the header (here rgw's
RGWSI_Notify::do_start via boost::asio::spawn) compile resume() with the larger
layout and read stack_bottom/stack_size past the allocation.

Pass define=BOOST_USE_ASAN to b2 so the library and its consumers agree on the
struct layout.

Signed-off-by: Kefu Chai <k.chai@proxmox.com>
CMakeLists.txt
cmake/modules/BuildBoost.cmake

index f2abb516b65d46ee986f0054df293db8b80368bf..cb422fd759ca09c7cd7f696fb174b13939e27ec2 100644 (file)
@@ -825,12 +825,7 @@ else()
     # Boost.Context is built ucontext-only here (context-impl=ucontext); define
     # the matching backend tree-wide so every Boost.Context/Coroutine2 consumer
     # agrees on it, instead of relying on per-target propagation that is easy to miss.
-    # Except riscv64: its ASan mis-handles ucontext, so it keeps fcontext.
-    if(CMAKE_SYSTEM_PROCESSOR MATCHES "riscv")
-      add_compile_definitions(BOOST_USE_ASAN)
-    else()
-      add_compile_definitions(BOOST_USE_ASAN BOOST_USE_UCONTEXT)
-    endif()
+    add_compile_definitions(BOOST_USE_ASAN BOOST_USE_UCONTEXT)
   endif()
 endif()
 include_directories(BEFORE SYSTEM ${Boost_INCLUDE_DIRS})
index 6f409dcdce1404c35497333ba27583016e6c3492..6a00c6be2c0f8ee7155f1f29d98f40e25cc77b66 100644 (file)
@@ -146,9 +146,11 @@ function(do_build_boost root_dir version)
   endif()
   set(b2_targets headers stage)
   set(b2_install_targets install)
-  # Except riscv64: its ASan mis-handles ucontext, so it keeps fcontext.
-  if(WITH_ASAN AND NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "riscv"))
+  if(WITH_ASAN)
     list(APPEND b2 context-impl=ucontext)
+    # build the library with the BOOST_USE_ASAN consumers get from Boost::context,
+    # so fiber_activation_record has one layout (else heap-buffer-overflow)
+    list(APPEND b2 define=BOOST_USE_ASAN)
     # `context-impl` is declared in libs/context/build/Jamfile.v2; the headers/stage
     # and install targets never load it, so b2 aborts with `unknown feature
     # "<context-impl>"`. Name the context project as a target so its Jamfile loads