Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ext/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ enum ddtrace_sidecar_connection_mode {
CONFIG(INT, DD_TRACE_AGENT_CONNECT_TIMEOUT, DD_CFG_EXPSTR(DD_TRACE_AGENT_CONNECT_TIMEOUT_VAL), \
.ini_change = zai_config_system_ini_change) \
CONFIG(INT, DD_TRACE_DEBUG_PRNG_SEED, "-1", .ini_change = ddtrace_reseed_seed_change) \
CONFIG(BOOL, DD_TRACE_SECURE_RANDOM, "false") \
CONFIG(BOOL, DD_LOG_BACKTRACE, "false") \
CONFIG(BOOL, DD_CRASHTRACKING_ENABLED, DD_CRASHTRACKING_ENABLED_DEFAULT) \
CONFIG(BOOL, DD_TRACE_GENERATE_ROOT_SPAN, "true", .ini_change = ddtrace_span_alter_root_span_config) \
Expand Down
10 changes: 9 additions & 1 deletion ext/random.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,15 @@ uint64_t ddtrace_parse_hex_span_id(zval *zid) {
return ddtrace_parse_hex_span_id_str(Z_STRVAL_P(zid), Z_STRLEN_P(zid));
}

uint64_t ddtrace_generate_span_id(void) { return (uint64_t)genrand64_int64(); }
uint64_t ddtrace_generate_span_id(void) {
if (get_DD_TRACE_SECURE_RANDOM()) {
uint64_t id;
if (php_random_bytes_silent(&id, sizeof(id)) == SUCCESS) {
return id;
}
}
return (uint64_t)genrand64_int64();
}

uint64_t ddtrace_peek_span_id(void) {
ddtrace_span_properties *pspan = DDTRACE_G(active_stack) ? DDTRACE_G(active_stack)->active : NULL;
Expand Down
29 changes: 29 additions & 0 deletions tests/ext/secure_random_generates_nonzero_ids.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
DD_TRACE_SECURE_RANDOM generates valid non-zero span IDs
--ENV--
DD_TRACE_GENERATE_ROOT_SPAN=false
DD_TRACE_DEBUG=false
DD_TRACE_SECURE_RANDOM=true
--FILE--
<?php

DDTrace\start_span();
$id1 = DDTrace\active_span()->id;
DDTrace\close_span();

DDTrace\start_span();
$id2 = DDTrace\active_span()->id;
DDTrace\close_span();

// Both IDs must be non-empty numeric strings representing non-zero values.
var_dump(ctype_digit($id1) && $id1 !== '0');
var_dump(ctype_digit($id2) && $id2 !== '0');

// Two consecutive IDs drawn from a CSPRNG must differ.
var_dump($id1 !== $id2);

?>
--EXPECT--
bool(true)
bool(true)
bool(true)
38 changes: 38 additions & 0 deletions tests/ext/secure_random_ignores_prng_seed.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--TEST--
DD_TRACE_SECURE_RANDOM bypasses the deterministic PRNG seed
--ENV--
DD_TRACE_GENERATE_ROOT_SPAN=false
DD_TRACE_DEBUG=false
DD_TRACE_SECURE_RANDOM=true
DD_TRACE_DEBUG_PRNG_SEED=42
--FILE--
<?php

// With DD_TRACE_DEBUG_PRNG_SEED set and DD_TRACE_SECURE_RANDOM=false,
// the MT19937-64 produces a fixed sequence: every process run with the
// same seed yields the same IDs in the same order.
//
// With DD_TRACE_SECURE_RANDOM=true the MT is bypassed entirely, so the
// seed has no effect and consecutive IDs must differ (CSPRNG output).

DDTrace\start_span();
$id1 = DDTrace\active_span()->id;
DDTrace\close_span();

DDTrace\start_span();
$id2 = DDTrace\active_span()->id;
DDTrace\close_span();

// IDs must be valid non-zero numeric strings.
var_dump(ctype_digit($id1) && $id1 !== '0');
var_dump(ctype_digit($id2) && $id2 !== '0');

// CSPRNG output must not be equal across calls; this fails deterministically
// under the MT because seed 42 would produce the same first two values every run.
var_dump($id1 !== $id2);

?>
--EXPECT--
bool(true)
bool(true)
bool(true)
Loading