Skip to content

Commit 8991876

Browse files
committed
Guard span baggage inheritance against malformed parent zval
ddtrace_inherit_span_properties copies the parent span's baggage property with ZVAL_COPY_DEREF, which runs GC_ADDREF unconditionally when the source is flagged refcounted. When the parent baggage zval carries the refcounted flag but a NULL counted pointer, GC_ADDREF dereferences NULL and the process takes a SIGSEGV during span creation. Skip the copy and fall back to the property's declared empty-array default when the source zval is in that broken state. Valid baggage is unaffected. Signed-off-by: Dani Jimenez <daniel.jimenez@airalo.com>
1 parent cd4e9ba commit 8991876

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

ext/serializer.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,14 @@ static void dd_set_entrypoint_root_span_props(struct superglob_equiv *data, ddtr
723723
}
724724
}
725725

726+
// Detects a zval that is flagged as refcounted but carries a NULL counted
727+
// pointer. Copying such a zval with ZVAL_COPY_DEREF dereferences NULL inside
728+
// GC_ADDREF and crashes the process.
729+
static zend_always_inline bool dd_zval_is_broken_refcounted(zval *zv) {
730+
ZVAL_DEREF(zv);
731+
return Z_REFCOUNTED_P(zv) && Z_COUNTED_P(zv) == NULL;
732+
}
733+
726734
void ddtrace_inherit_span_properties(ddtrace_span_data *span, ddtrace_span_data *parent) {
727735
zval *prop_service = &span->property_service;
728736
zval_ptr_dtor(prop_service);
@@ -733,7 +741,13 @@ void ddtrace_inherit_span_properties(ddtrace_span_data *span, ddtrace_span_data
733741

734742
zval *prop_baggage = &span->property_baggage, *prop_parent_baggage = &parent->property_baggage;
735743
zval_ptr_dtor(prop_baggage);
736-
ZVAL_COPY_DEREF(prop_baggage, prop_parent_baggage);
744+
if (UNEXPECTED(dd_zval_is_broken_refcounted(prop_parent_baggage))) {
745+
// Fall back to the property's declared default instead of dereferencing
746+
// a NULL refcounted pointer; baggage stays a valid array downstream.
747+
ZVAL_EMPTY_ARRAY(prop_baggage);
748+
} else {
749+
ZVAL_COPY_DEREF(prop_baggage, prop_parent_baggage);
750+
}
737751

738752
zend_array *parent_meta = ddtrace_property_array(&parent->property_meta);
739753

0 commit comments

Comments
 (0)