Skip to content

Commit

Permalink
Refactor asm implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
estringana committed Nov 13, 2024
1 parent deaa0b8 commit 297a13f
Show file tree
Hide file tree
Showing 17 changed files with 138 additions and 107 deletions.
2 changes: 1 addition & 1 deletion appsec/src/extension/commands_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ dd_result dd_command_proc_resp_verd_span_data(

if (res == dd_should_block || res == dd_should_redirect ||
res == dd_should_record) {
dd_appsec_add_asm_event();
dd_trace_emit_asm_event();
_set_appsec_span_data(mpack_node_array_at(root, 1));
}

Expand Down
27 changes: 19 additions & 8 deletions appsec/src/extension/ddtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ static zend_string *_ddtrace_root_span_fname;
static zend_string *_meta_propname;
static zend_string *_metrics_propname;
static zend_string *_meta_struct_propname;
static zend_string *_propagated_tags_propname;
static THREAD_LOCAL_ON_ZTS bool _suppress_ddtrace_rshutdown;
static uint8_t *_ddtrace_runtime_id = NULL;

Expand All @@ -51,6 +50,8 @@ static zend_string *(*_ddtrace_ip_extraction_find)(zval *server);

static const char *nullable (*_ddtrace_remote_config_get_path)(void);

static void *(*nullable _ddtrace_emit_asm_event)(void);

static void dd_trace_load_symbols(void)
{
bool testing = get_global_DD_APPSEC_TESTING();
Expand Down Expand Up @@ -120,6 +121,14 @@ static void dd_trace_load_symbols(void)
"Failed to load ddtrace_remote_config_get_path: %s", dlerror());
}

_ddtrace_emit_asm_event =
dlsym(handle, "ddtrace_emit_asm_event");
if (_ddtrace_emit_asm_event == NULL) {
mlog(dd_log_error,
// NOLINTNEXTLINE(concurrency-mt-unsafe)
"Failed to load ddtrace_emit_asm_event: %s", dlerror());
}

dlclose(handle);
}

Expand All @@ -131,8 +140,6 @@ void dd_trace_startup()
_metrics_propname = zend_string_init_interned(LSTRARG("metrics"), 1);
_meta_struct_propname =
zend_string_init_interned(LSTRARG("meta_struct"), 1);
_propagated_tags_propname =
zend_string_init_interned(LSTRARG("propagated_tags"), 1);

if (get_global_DD_APPSEC_TESTING()) {
_register_testing_objects();
Expand Down Expand Up @@ -317,11 +324,6 @@ zval *nullable dd_trace_span_get_meta_struct(zend_object *nonnull zobj)
return _get_span_modifiable_array_property(zobj, _meta_struct_propname);
}

zval *nullable dd_trace_span_get_propagated_tags(zend_object *nonnull zobj)
{
return _get_span_modifiable_array_property(zobj, _propagated_tags_propname);
}

// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
zend_string *nullable dd_trace_get_formatted_runtime_id(bool persistent)
{
Expand Down Expand Up @@ -407,6 +409,15 @@ void dd_trace_span_add_propagated_tags(
_ddtrace_add_propagated_tag_on_span_zobj(key, value);
}

void dd_trace_emit_asm_event(void)
{
if (UNEXPECTED(_ddtrace_emit_asm_event == NULL)) {
return;
}

_ddtrace_emit_asm_event();
}

static PHP_FUNCTION(datadog_appsec_testing_ddtrace_rshutdown)
{
if (zend_parse_parameters_none() == FAILURE) {
Expand Down
2 changes: 2 additions & 0 deletions appsec/src/extension/ddtrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ bool dd_trace_span_add_tag_str(zend_object *nonnull zobj,
// Flush the tracer spans, can be used on RINIT
void dd_trace_close_all_spans_and_flush(void);

void dd_trace_emit_asm_event(void);

// Provides the array zval representing $root_span->meta, if any.
// It is ready for modification, with refcount == 1
zval *nullable dd_trace_span_get_meta(zend_object *nonnull);
Expand Down
70 changes: 24 additions & 46 deletions appsec/src/extension/tags.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ static THREAD_LOCAL_ON_ZTS bool _appsec_json_frags_inited;
static THREAD_LOCAL_ON_ZTS zend_llist _appsec_json_frags;
static THREAD_LOCAL_ON_ZTS zend_string *nullable _event_user_id;
static THREAD_LOCAL_ON_ZTS bool _blocked;
static THREAD_LOCAL_ON_ZTS bool _asm_event_propagated;
static THREAD_LOCAL_ON_ZTS bool _force_keep;

static void _init_relevant_headers(void);
Expand All @@ -123,9 +122,6 @@ void _set_runtime_family(zend_object *nonnull span);
static bool _set_appsec_enabled(zval *metrics_zv);
static void _register_functions(void);
static void _register_test_functions(void);
static void _add_new_zstr_to_meta(zend_array *meta_ht, zend_string *key,
zend_string *val, bool copy, bool override);
static zval *nullable _root_span_get_meta();

void dd_tags_startup()
{
Expand Down Expand Up @@ -296,7 +292,6 @@ void dd_tags_rinit()
_event_user_id = NULL;
_blocked = false;
_force_keep = false;
_asm_event_propagated = false;
}

void dd_tags_add_appsec_json_frag(zend_string *nonnull zstr)
Expand All @@ -319,26 +314,6 @@ void dd_tags_rshutdown()
}
}

void dd_appsec_add_asm_event()
{
if (_asm_event_propagated) {
return;
}
zval *nullable meta = _root_span_get_meta();
if (meta && Z_TYPE_P(meta) == IS_ARRAY) {
zend_array *meta_ht = Z_ARRVAL_P(meta);
// Indicate there is a ASM EVENT. This tag is used for any event
// threats, business logic events, IAST, etc
_add_new_zstr_to_meta(
meta_ht, _dd_tag_p_appsec_zstr, _1_zstr, true, false);
}

zval _1_zval;
ZVAL_STR(&_1_zval, _1_zstr);
dd_trace_span_add_propagated_tags(_dd_tag_p_appsec_zstr, &_1_zval);
_asm_event_propagated = true;
}

void dd_tags_add_tags(
zend_object *nonnull span, zend_array *nullable superglob_equiv)
{
Expand All @@ -358,6 +333,12 @@ void dd_tags_add_tags(
// tag _dd.runtime_family
_set_runtime_family(span);

if (_force_keep) {
dd_trace_set_priority_sampling_on_span_zobj(
span, PRIORITY_SAMPLING_USER_KEEP, DD_MECHANISM_MANUAL);
mlog(dd_log_debug, "Updated sampling priority to user_keep");
}

if (zend_llist_count(&_appsec_json_frags) == 0) {
if (!server) {
return;
Expand All @@ -369,21 +350,33 @@ void dd_tags_add_tags(
return;
}

zval true_zv;
ZVAL_STR_COPY(&true_zv, _true_zstr);

// tag _dd.p.appsec
bool res = dd_trace_span_add_tag(span, _dd_tag_p_appsec_zstr, &true_zv);
if (!res) {
mlog(dd_log_info, "Failed adding tag " DD_TAG_P_APPSEC " to root span");
return;
}

zval _1_zval;
ZVAL_STR(&_1_zval, _1_zstr);
dd_trace_span_add_propagated_tags(_dd_tag_p_appsec_zstr, &_1_zval);

zend_string *tag_value = _concat_json_fragments();

zval tag_value_zv;
ZVAL_STR(&tag_value_zv, tag_value);

// tag _dd.appsec.json
bool res = dd_trace_span_add_tag(span, _dd_tag_data_zstr, &tag_value_zv);
res = dd_trace_span_add_tag(span, _dd_tag_data_zstr, &tag_value_zv);
if (!res) {
mlog(dd_log_info, "Failed adding tag " DD_TAG_DATA " to root span");
return;
}

// tag appsec.event
zval true_zv;
ZVAL_STR_COPY(&true_zv, _true_zstr);
res = dd_trace_span_add_tag(span, _dd_tag_event_zstr, &true_zv);
if (!res) {
mlog(dd_log_info, "Failed adding tag " DD_TAG_EVENT " to root span");
Expand All @@ -400,19 +393,7 @@ void dd_tags_add_tags(

void dd_tags_add_blocked() { _blocked = true; }

void dd_tags_set_sampling_priority()
{
if (_force_keep) {
return;
}

zend_object *nullable span = dd_req_lifecycle_get_cur_span();
dd_trace_set_priority_sampling_on_span_zobj(
span, PRIORITY_SAMPLING_USER_KEEP, DD_MECHANISM_MANUAL);
mlog(dd_log_debug, "Updated sampling priority to user_keep");

_force_keep = true;
}
void dd_tags_set_sampling_priority() { _force_keep = true; }

static void _zend_string_release_indirect(void *s)
{
Expand Down Expand Up @@ -555,7 +536,6 @@ static void _add_new_zstr_to_meta(zend_array *meta_ht, zend_string *key,
zend_string_release(val);
}
}

static void _dd_http_method(zend_array *meta_ht)
{
if (zend_hash_exists(meta_ht, _dd_tag_http_method_zstr)) {
Expand Down Expand Up @@ -904,15 +884,13 @@ static zval *nullable _root_span_get_meta()
{
zend_object *nullable span = dd_req_lifecycle_get_cur_span();
if (!span) {
// TODO Uncomment this
// mlog(dd_log_warning, "No root span being tracked by appsec");
mlog(dd_log_warning, "No root span being tracked by appsec");
return NULL;
}

zval *nullable meta = dd_trace_span_get_meta(span);
if (!meta) {
// TODO Uncomment this
// mlog(dd_log_warning, "Failed to retrieve root span meta");
mlog(dd_log_warning, "Failed to retrieve root span meta");
}
return meta;
}
Expand Down
1 change: 0 additions & 1 deletion appsec/src/extension/tags.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ void dd_tags_startup(void);
void dd_tags_shutdown(void);
void dd_tags_rinit(void);
void dd_tags_rshutdown(void);
void dd_appsec_add_asm_event();
void dd_tags_add_tags(zend_object *nonnull span, zend_array *nullable superglob_equiv);
void dd_tags_add_blocked(void);

Expand Down
1 change: 1 addition & 0 deletions config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ if test "$PHP_DDTRACE" != "no"; then
ext/integrations/exec_integration.c \
ext/integrations/integrations.c \
ext/ip_extraction.c \
ext/ddappsec.c \
ext/live_debugger.c \
ext/logging.c \
ext/limiter/limiter.c \
Expand Down
1 change: 1 addition & 0 deletions config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ if (PHP_DDTRACE != 'no') {
DDTRACE_EXT_SOURCES += " handlers_internal.c";
DDTRACE_EXT_SOURCES += " handlers_pcntl.c";
DDTRACE_EXT_SOURCES += " ip_extraction.c";
DDTRACE_EXT_SOURCES += " ddappsec.c";
DDTRACE_EXT_SOURCES += " live_debugger.c";
DDTRACE_EXT_SOURCES += " logging.c";
DDTRACE_EXT_SOURCES += " memory_limit.c";
Expand Down
1 change: 1 addition & 0 deletions ddtrace.sym
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ ddtrace_user_req_add_listeners
ddtrace_ip_extraction_find
ddtrace_set_all_thread_vm_interrupt
ddtrace_remote_config_get_path
ddtrace_emit_asm_event
ddog_remote_config_reader_for_path
ddog_remote_config_read
ddog_remote_config_reader_drop
Expand Down
23 changes: 23 additions & 0 deletions ext/ddappsec.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "ddappsec.h"

#include "configuration.h"
#include "ddtrace.h"
#include "tracer_tag_propagation/tracer_tag_propagation.h"

ZEND_EXTERN_MODULE_GLOBALS(ddtrace);

static zend_string *_dd_tag_p_appsec_zstr;
static zend_string *_1_zstr;

void ddtrace_appsec_minit() {
_1_zstr = zend_string_init_interned(ZEND_STRL("1"), 1 /* permanent */);
_dd_tag_p_appsec_zstr = zend_string_init_interned(ZEND_STRL(DD_TAG_P_APPSEC), 1 /* permanent */);
}

DDTRACE_PUBLIC void ddtrace_emit_asm_event() {
DDTRACE_G(asm_event_emitted) = true;

zval _1_zval;
ZVAL_STR(&_1_zval, _1_zstr);
ddtrace_add_propagated_tag(_dd_tag_p_appsec_zstr, &_1_zval);
}
11 changes: 11 additions & 0 deletions ext/ddappsec.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef DD_APPSEC_H
#define DD_APPSEC_H

#include "ddtrace_export.h"

#define DD_TAG_P_APPSEC "_dd.p.appsec"

void ddtrace_appsec_minit();
DDTRACE_PUBLIC void ddtrace_emit_asm_event();

#endif // DD_APPSEC_H
3 changes: 3 additions & 0 deletions ext/ddtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#include "autoload_php_files.h"
#include "remote_config.h"
#include "serializer.h"
#include "ddappsec.h"
#include "sidecar.h"
#ifndef _WIN32
#include "signals.h"
Expand Down Expand Up @@ -1440,6 +1441,7 @@ static PHP_MINIT_FUNCTION(ddtrace) {

ddtrace_live_debugger_minit();
ddtrace_minit_remote_config();
ddtrace_appsec_minit();

return SUCCESS;
}
Expand Down Expand Up @@ -1532,6 +1534,7 @@ static void dd_initialize_request(void) {
DDTRACE_G(additional_global_tags) = zend_new_array(0);
DDTRACE_G(default_priority_sampling) = DDTRACE_PRIORITY_SAMPLING_UNKNOWN;
DDTRACE_G(propagated_priority_sampling) = DDTRACE_PRIORITY_SAMPLING_UNSET;
DDTRACE_G(asm_event_emitted) = false;
zend_hash_init(&DDTRACE_G(root_span_tags_preset), 8, unused, ZVAL_PTR_DTOR, 0);
zend_hash_init(&DDTRACE_G(propagated_root_span_tags), 8, unused, ZVAL_PTR_DTOR, 0);
zend_hash_init(&DDTRACE_G(tracestate_unknown_dd_keys), 8, unused, ZVAL_PTR_DTOR, 0);
Expand Down
2 changes: 2 additions & 0 deletions ext/ddtrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ ZEND_BEGIN_MODULE_GLOBALS(ddtrace)
HashTable telemetry_spans_created_per_integration;
ddog_SidecarActionsBuffer *telemetry_buffer;

bool asm_event_emitted;

#if PHP_VERSION_ID >= 80000
HashTable curl_headers;
// Multi-handle API: curl_multi_*()
Expand Down
Loading

0 comments on commit 297a13f

Please sign in to comment.