Skip to content

Commit 09f23bd

Browse files
authored
Validate DD_TRACE_AGENT_URL (#3050)
This avoids panics in the sidecar and crashes in crashtracker initialization. Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
1 parent a958dad commit 09f23bd

File tree

7 files changed

+47
-3
lines changed

7 files changed

+47
-3
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components-rs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ tracing-subscriber = { version = "0.3", default-features = false, features = [
4343
serde_json = "1.0.113"
4444
regex = "1.10.5"
4545
regex-automata = "0.4.5"
46+
http = "0.2.11"
4647

4748
[build-dependencies]
4849
cbindgen = "0.27"

components-rs/ddtrace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ char *ddtrace_strip_invalid_utf8(const char *input, uintptr_t *len);
153153

154154
void ddtrace_drop_rust_string(char *input, uintptr_t len);
155155

156+
struct ddog_Endpoint *ddtrace_parse_agent_url(ddog_CharSlice url);
157+
156158
bool ddog_shall_log(enum ddog_Log category);
157159

158160
void ddog_set_error_log_level(bool once);

components-rs/lib.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@ pub mod telemetry;
1010
use std::borrow::Cow;
1111
use std::ffi::c_char;
1212
use std::ptr::null_mut;
13+
use http::Uri;
1314
use ddcommon::entity_id::{get_container_id, set_cgroup_file};
15+
use http::uri::Scheme;
1416
use uuid::Uuid;
1517

1618
pub use datadog_crashtracker_ffi::*;
1719
pub use datadog_sidecar_ffi::*;
20+
use ddcommon::{parse_uri, Endpoint};
1821
use ddcommon_ffi::slice::AsBytes;
1922
pub use ddcommon_ffi::*;
2023
pub use ddtelemetry_ffi::*;
@@ -65,3 +68,18 @@ pub unsafe extern "C" fn ddtrace_strip_invalid_utf8(input: *const c_char, len: *
6568
pub unsafe extern "C" fn ddtrace_drop_rust_string(input: *mut c_char, len: usize) {
6669
_ = String::from_raw_parts(input as *mut u8, len, len);
6770
}
71+
72+
#[no_mangle]
73+
pub unsafe extern "C" fn ddtrace_parse_agent_url(url: CharSlice) -> std::option::Option<Box<Endpoint>> {
74+
parse_uri(url.to_utf8_lossy().as_ref())
75+
.ok()
76+
.and_then(|url| if url.authority().is_none() { None } else { Some(url) })
77+
.map(|mut url| {
78+
if url.scheme().is_none() {
79+
let mut parts = url.into_parts();
80+
parts.scheme = Some(Scheme::HTTP);
81+
url = Uri::from_parts(parts).unwrap();
82+
}
83+
Box::new(Endpoint::from_url(url))
84+
})
85+
}

ext/sidecar.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static void ddtrace_set_resettable_sidecar_globals(void) {
3737
}
3838

3939
ddog_SidecarTransport *dd_sidecar_connection_factory(void) {
40-
// Should not happen
40+
// Should not happen, unless the agent url is malformed
4141
if (!ddtrace_endpoint) {
4242
return NULL;
4343
}
@@ -171,11 +171,15 @@ ddog_Endpoint *ddtrace_sidecar_agent_endpoint(void) {
171171
agent_endpoint = ddog_endpoint_from_api_key(dd_zend_string_to_CharSlice(get_global_DD_API_KEY()));
172172
} else {
173173
char *agent_url = ddtrace_agent_url();
174-
agent_endpoint = ddog_endpoint_from_url((ddog_CharSlice) {.ptr = agent_url, .len = strlen(agent_url)});
174+
agent_endpoint = ddtrace_parse_agent_url((ddog_CharSlice) {.ptr = agent_url, .len = strlen(agent_url)});
175+
if (!agent_endpoint) {
176+
LOG(ERROR, "Invalid DD_TRACE_AGENT_URL: %s. A proper agent URL must be unix:///path/to/agent.sock or http://hostname:port/.", agent_url);
177+
}
175178
free(agent_url);
176179
}
177180

178-
if (ZSTR_LEN(get_global_DD_TRACE_AGENT_TEST_SESSION_TOKEN())) {
181+
182+
if (agent_endpoint && ZSTR_LEN(get_global_DD_TRACE_AGENT_TEST_SESSION_TOKEN())) {
179183
ddog_endpoint_set_test_token(agent_endpoint, dd_zend_string_to_CharSlice(get_global_DD_TRACE_AGENT_TEST_SESSION_TOKEN()));
180184
}
181185

ext/signals.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ static void ddtrace_init_crashtracker() {
117117
socket_path.ptr = crashtracker_socket_path;
118118

119119
ddog_Endpoint *agent_endpoint = ddtrace_sidecar_agent_endpoint();
120+
if (!agent_endpoint) {
121+
return;
122+
}
120123

121124
ddog_crasht_Config config = {
122125
.endpoint = agent_endpoint,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
The sidecar properly handles invalid agent urls
3+
--SKIPIF--
4+
<?php include __DIR__ . '/../includes/skipif_no_dev_env.inc'; ?>
5+
<?php if (getenv('USE_ZEND_ALLOC') === '0' && !getenv("SKIP_ASAN")) die('skip: valgrind reports sendmsg(msg.msg_control) points to uninitialised byte(s), but it is unproblematic and outside our control in rust code'); ?>
6+
--ENV--
7+
DD_TRACE_AGENT_URL=/invalid
8+
DD_TRACE_SIDECAR_TRACE_SENDER=1
9+
DD_CRASHTRACKING_ENABLED=0
10+
--FILE--
11+
<?php
12+
13+
?>
14+
--EXPECTF--
15+
[ddtrace] [error] Invalid DD_TRACE_AGENT_URL: /invalid. A proper agent URL must be unix:///path/to/agent.sock or http://hostname:port/.

0 commit comments

Comments
 (0)