#50575·milvus

[Bug]: libmilvus-storage.so is built with executable stack

Author: zhuwenxingCreated Jun 16, 2026Updated Sep 17, 2026
Labelskind/bugtriage/accepted

Environment

  • Milvus version: 2.7.0 / master image
  • Milvus image: harbor.milvus.io/manta/milvus:master-20260616-778f53f-profile
  • Deployment mode: cluster, but this issue is a build artifact issue and is not tied to deployment mode
  • MQ type: N/A, independent of MQ
  • SDK version: N/A
  • OS: Linux x86_64
  • CPU/Memory: N/A
  • GPU: N/A

Current Behavior

libmilvus-storage.so is built with an executable stack (GNU_STACK RWE). After the library is loaded by Milvus, the process has many anonymous executable stack mappings. This makes eBPF profiling harder to unwind/symbolize and causes large [unknown] areas in Pyroscope eBPF CPU profiles.

Observed ELF stack flags from the Milvus image:

RW   /milvus/bin/milvus
RW   /milvus/lib/libmilvus_core.so
RW   /milvus/lib/libknowhere.so
RWE  /milvus/lib/libmilvus-storage.so

Observed runtime mappings from a Milvus datanode process:

threads=168
rwxp_anon_maps=171
7f77bd640000-7f77bde40000 rwxp 00000000 00:00 0
7f77c3dd0000-7f77c45d0000 rwxp 00000000 00:00 0
7f77c6deb000-7f77c75eb000 rwxp 00000000 00:00 0
7f77c8df0000-7f77c95f0000 rwxp 00000000 00:00 0
7f77cba80000-7f77cc280000 rwxp 00000000 00:00 0

In eBPF CPU profiles collected during import, [unknown] accounted for a large part of samples. For example:

v2 full profile: [unknown] flat 141.03s / 274.29s = 51.42%
v3 import profile: [unknown] flat 145.48s / 303.32s = 47.96%

Native symbols such as ZSTD and Rust/Tantivy functions can be resolved, so this is not simply caused by stripped binaries or missing symbols.

Expected Behavior

libmilvus-storage.so should be built with a non-executable stack:

GNU_STACK RW

Loading Milvus storage should not make process thread stacks executable, and eBPF profiling should not get large [unknown] regions because of anonymous executable stack mappings.

Steps To Reproduce

  1. Build or use a Milvus image that contains the current libmilvus-storage.so.
  2. Check ELF stack flags:
readelf -W -l /milvus/lib/libmilvus-storage.so | grep GNU_STACK

Actual result:

GNU_STACK ... RWE ...
  1. Start a Milvus component that loads libmilvus-storage.so.
  2. Check anonymous executable mappings:
pid=$(pidof milvus)
awk '$2 ~ /^rwxp$/ && $6=="" {print}' /proc/$pid/maps | head

Actual result: many anonymous rwxp mappings are present.

Minimal Reproduction Script

N/A: this is a native build artifact issue. It can be reproduced by checking the ELF program header of libmilvus-storage.so with readelf.

Milvus Log

N/A: this issue does not produce Milvus error logs. It affects native binary metadata and eBPF profiling quality.

Anything else?

The likely source is the Rust bridge linked into libmilvus-storage.so.

In milvus-storage:

cpp/CMakeLists.txt
  -> adds src/format/bridge/rust
  -> links prsbridge into milvus-storage

cpp/src/format/bridge/rust/Cargo.toml
  -> crate-type = ["staticlib"]
  -> depends on sqlparser

The dependency chain is:

rust-bridge -> sqlparser -> recursive -> stacker -> psm

psm 0.1.28 builds platform assembly. On Linux x86_64 it compiles:

psm-0.1.28/src/arch/x86_64.s

That object does not contain .note.GNU-stack.

A local object-level check showed:

psm_x86_64.o:   .note.GNU-stack=ABSENT
zstd_huf.o:     .note.GNU-stack=['-']
blake3_avx2.o:  .note.GNU-stack=['-']

ring also has assembly, but its asm_base.h explicitly emits .note.GNU-stack, so it is less likely to be the source.

Suggested fix direction:

target_link_options(milvus-storage PRIVATE -Wl,-z,noexecstack)

This should be added to the milvus-storage target, preferably in the milvus-storage CMake itself or in the Milvus wrapper after add_subdirectory.

For diagnostics, a temporary linker warning can also confirm the source object:

target_link_options(milvus-storage PRIVATE -Wl,--warn-execstack)