Skip to content

SIGSEGV in ddtrace_inherit_span_properties (use-after-free) — v1.21.0 / PHP 8.2.31 #4007

Description

@dhinesh-karan

Environment

  • dd-trace-php: 1.21.0
  • PHP: 8.2.31 (FPM)
  • OS: Ubuntu 22.04 (EKS, kernel 6.12.66 amzn2023)
  • Architecture: x86_64 (c6a.4xlarge)
  • Enabled features: appsec, profiling, crashtracking
  • Framework: Laravel 10 (default auto-instrumentation, no custom tracer instrumentation or manual span creation)

Problem

PHP-FPM workers crash with SIGSEGV (signal 11) due to a use-after-free bug in the tracer's span inheritance logic. When ddtrace_open_span is called to create a new internal span, it invokes ddtrace_inherit_span_properties to copy properties from the parent span. However, the parent span's memory has already been freed and reallocated for other data (string storage), causing zend_gc_addref to dereference a corrupted pointer and segfault.

This results in a 502 error for the in-flight request. The crash happens intermittently (~2/week) on long-lived FPM workers (13–36 hours uptime) under normal traffic. It is not endpoint-specific and occurs with default auto-instrumentation only — no custom span creation.

Backtrace (from crashtracker core dump)

#0  __pthread_kill_implementation (signo=11) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=11) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (signo=11) at ./nptl/pthread_kill.c:89
#3  __GI_raise (sig=11) at ../sysdeps/posix/raise.c:26
#4  libdd_crashtracker::collector::signal_handler_manager::chain_signal_handler ()
#5  libdd_crashtracker::collector::crash_handler::handle_posix_sigaction ()
#6  <signal handler called>
#7  zend_gc_addref (p=0x6372732d7463656a) at zend_types.h:1210
#8  zval_addref_p (pz=0x7fd56145d830) at zend_types.h:1259
#9  ddtrace_inherit_span_properties (span=0x7fd561532f80, parent=0x7fd56145d7b0) at tracer/serializer.c:731
#10 ddtrace_open_span (type=DDTRACE_INTERNAL_SPAN) at tracer/span.c:304
#11 ddtrace_alloc_execute_data_span_ex (index=49058) at tracer/span.c:488
#12 ddtrace_alloc_execute_data_span at tracer/span.c:546
...
#19 zend_execute ()

Evidence of use-after-free

The pointer passed to zend_gc_addref at frame #7 is 0x6372732d7463656a, which decodes to ASCII "crs-tcej". This is clearly string data that has overwritten the parent span's zval after it was freed. The parent span object at 0x7fd56145d7b0 was deallocated and its memory reused, but ddtrace_inherit_span_properties still holds a stale reference to it.

Reproduction

  • Long-lived FPM workers (13–36h uptime before crash)
  • ~6 crashes in 30 days across different pods/nodes
  • Not endpoint-specific
  • No custom tracer instrumentation — default auto-instrumentation only

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions