Skip to content

Commit

Permalink
glopes wip
Browse files Browse the repository at this point in the history
  • Loading branch information
cataphract committed Sep 30, 2024
1 parent 2644c45 commit 90639bf
Show file tree
Hide file tree
Showing 125 changed files with 2,187 additions and 6,429 deletions.
2 changes: 1 addition & 1 deletion appsec/.clang-tidy
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
# readability-function-cognitive-complexity temporarily disabled until clang-tidy is fixed
# right now emalloc causes it to misbehave
Checks: '*,-bugprone-reserved-identifier,-hicpp-signed-bitwise,-llvmlibc-restrict-system-libc-headers,-altera-unroll-loops,-hicpp-named-parameter,-cert-dcl37-c,-cert-dcl51-cpp,-read,-cppcoreguidelines-init-variables,-cppcoreguidelines-avoid-non-const-global-variables,-altera-id-dependent-backward-branch,-performance-no-int-to-ptr,-altera-struct-pack-align,-google-readability-casting,-modernize-use-trailing-return-type,-llvmlibc-implementation-in-namespace,-llvmlibc-callee-namespace,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-fuchsia-default-arguments-declarations,-fuchsia-overloaded-operator,-cppcoreguidelines-pro-type-union-access,-fuchsia-default-arguments-calls,-cppcoreguidelines-non-private-member-variables-in-classes,-misc-non-private-member-variables-in-classes,-google-readability-todo,-llvm-header-guard,-readability-function-cognitive-complexity,-readability-identifier-length,-modernize-macro-to-enum,-misc-include-cleaner,-bugprone-empty-catch,-cppcoreguidelines-avoid-do-while'
Checks: '*,-bugprone-reserved-identifier,-hicpp-signed-bitwise,-llvmlibc-restrict-system-libc-headers,-altera-unroll-loops,-hicpp-named-parameter,-cert-dcl37-c,-cert-dcl51-cpp,-read,-cppcoreguidelines-init-variables,-cppcoreguidelines-avoid-non-const-global-variables,-altera-id-dependent-backward-branch,-performance-no-int-to-ptr,-altera-struct-pack-align,-google-readability-casting,-modernize-use-trailing-return-type,-llvmlibc-implementation-in-namespace,-llvmlibc-callee-namespace,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-fuchsia-default-arguments-declarations,-fuchsia-overloaded-operator,-cppcoreguidelines-pro-type-union-access,-fuchsia-default-arguments-calls,-cppcoreguidelines-non-private-member-variables-in-classes,-misc-non-private-member-variables-in-classes,-google-readability-todo,-llvm-header-guard,-readability-function-cognitive-complexity,-readability-identifier-length,-modernize-macro-to-enum,-bugprone-empty-catch,-cppcoreguidelines-avoid-do-while'
WarningsAsErrors: '*'
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
Expand Down
4 changes: 3 additions & 1 deletion appsec/cmake/helper.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ set_target_properties(helper_objects PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED YES
POSITION_INDEPENDENT_CODE 1)
target_include_directories(helper_objects PUBLIC ${HELPER_INCLUDE_DIR})
target_include_directories(helper_objects INTERFACE ${HELPER_INCLUDE_DIR})
target_compile_definitions(helper_objects PUBLIC SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_TRACE)
target_compile_options(helper_objects PRIVATE -ftls-model=global-dynamic)
target_link_libraries(helper_objects PUBLIC libddwaf_objects pthread spdlog cpp-base64 msgpack_c RapidJSON::rapidjson Boost::system zlibstatic)
Expand All @@ -35,6 +35,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Bind symbols lookup of symbols defined in the library to the library itself
# also avoids relocation problems with libc++.a on linux/aarch64
target_link_options(ddappsec-helper PRIVATE -Wl,-Bsymbolic)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
target_link_options(ddappsec-helper PRIVATE -undefined dynamic_lookup)
endif()
set_target_properties(ddappsec-helper PROPERTIES
CXX_VISIBILITY_PRESET hidden
Expand Down
3 changes: 2 additions & 1 deletion appsec/src/extension/backtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ php_backtrace_frame_to_datadog_backtrace_frame( // NOLINTNEXTLINE(bugprone-easil
if (file) {
// In order to be able to test full path encoded everywhere lets set
// only the file name without path
char *file_name = memrchr(Z_STRVAL_P(file), '/', Z_STRLEN_P(file));
const char *file_name =
zend_memrchr(Z_STRVAL_P(file), '/', Z_STRLEN_P(file));
if (file_name) {
zend_string *new_file = zend_string_init(file_name + 1,
Z_STRLEN_P(file) - (file_name + 1 - Z_STRVAL_P(file)), 0);
Expand Down
91 changes: 4 additions & 87 deletions appsec/src/extension/commands/client_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,68 +17,20 @@
#include "../version.h"
#include "client_init.h"

static const unsigned int DEFAULT_AGENT_PORT = 8126;
static const char *DEFAULT_AGENT_HOST = "127.0.0.1";
static const unsigned int MAX_TCP_PORT_ALLOWED = UINT16_MAX;

static dd_result _pack_command(mpack_writer_t *nonnull w, void *nullable ctx);
static dd_result _process_response(mpack_node_t root, void *nullable ctx);
static void _process_meta_and_metrics(
mpack_node_t root, struct req_info *nonnull ctx);
static void _pack_agent_details(mpack_writer_t *nonnull w);

static const dd_command_spec _spec = {
.name = "client_init",
.name_len = sizeof("client_init") - 1,
.num_args = 7,
.num_args = 6,
.outgoing_cb = _pack_command,
.incoming_cb = _process_response,
.config_features_cb = dd_command_process_config_features_unexpected,
};

static void _pack_agent_details(mpack_writer_t *nonnull w)
{
zend_string *agent_host = get_global_DD_AGENT_HOST();
zend_string *agent_url = get_global_DD_TRACE_AGENT_URL();
unsigned int port = get_global_DD_TRACE_AGENT_PORT();
char *host = NULL;
php_url *parsed_url = NULL;

if (agent_host && ZSTR_LEN(agent_host) > 0) {
host = ZSTR_VAL(agent_host);
} else if (agent_url && ZSTR_LEN(agent_url) > 0) {
parsed_url = php_url_parse(ZSTR_VAL(agent_url));
if (parsed_url) {
#if PHP_VERSION_ID < 70300
if (parsed_url->host && strlen(parsed_url->host) > 0) {
host = parsed_url->host;
}
#else
if (parsed_url->host && ZSTR_LEN(parsed_url->host) > 0) {
host = ZSTR_VAL(parsed_url->host);
}
#endif
port = parsed_url->port;
}
}

if (!host) {
host = (char *)DEFAULT_AGENT_HOST;
}
if (port <= 0 || port > MAX_TCP_PORT_ALLOWED) {
port = DEFAULT_AGENT_PORT;
}

dd_mpack_write_lstr(w, "host");
dd_mpack_write_nullable_cstr(w, host);
dd_mpack_write_lstr(w, "port");
mpack_write_uint(w, port);

if (parsed_url) {
php_url_free(parsed_url);
}
}

dd_result dd_client_init(dd_conn *nonnull conn, struct req_info *nonnull ctx)
{
return dd_command_exec_cred(conn, &_spec, ctx);
Expand All @@ -97,39 +49,6 @@ static dd_result _pack_command(
mpack_write_bool(w, DDAPPSEC_G(active));
}

// Service details
// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
mpack_start_map(w, 6);

dd_mpack_write_lstr(w, "service");
dd_mpack_write_nullable_cstr(w, ZSTR_VAL(get_DD_SERVICE()));

dd_mpack_write_lstr(w, "extra_services");
zval extra_services;
ZVAL_ARR(&extra_services, get_global_DD_EXTRA_SERVICES());
dd_mpack_write_zval(w, &extra_services);

dd_mpack_write_lstr(w, "env");
dd_mpack_write_nullable_cstr(w, ZSTR_VAL(get_DD_ENV()));

dd_mpack_write_lstr(w, "tracer_version");
dd_mpack_write_nullable_cstr(w, dd_trace_version());

dd_mpack_write_lstr(w, "app_version");
dd_mpack_write_nullable_cstr(w, ZSTR_VAL(get_DD_VERSION()));

// We send this empty for now. The helper will check for empty and if so it
// will generate it
dd_mpack_write_lstr(w, "runtime_id");
zend_string *runtime_id = dd_trace_get_formatted_runtime_id(false);
if (runtime_id == NULL) {
dd_mpack_write_nullable_cstr(w, "");
} else {
dd_mpack_write_nullable_zstr(w, runtime_id);
zend_string_free(runtime_id);
}
mpack_finish_map(w);

// Engine settings
// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
mpack_start_map(w, 6);
Expand Down Expand Up @@ -180,15 +99,13 @@ static dd_result _pack_command(

// Remote config settings
// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
mpack_start_map(w, 4);
mpack_start_map(w, 2);

dd_mpack_write_lstr(w, "enabled");
mpack_write_bool(w, get_DD_REMOTE_CONFIG_ENABLED());

_pack_agent_details(w);

dd_mpack_write_lstr(w, "poll_interval");
mpack_write_u32(w, get_DD_REMOTE_CONFIG_POLL_INTERVAL());
dd_mpack_write_lstr(w, "shmem_path");
dd_mpack_write_nullable_cstr(w, dd_trace_remote_config_get_path());

mpack_finish_map(w);

Expand Down
22 changes: 13 additions & 9 deletions appsec/src/extension/commands/config_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,36 @@
#include <php.h>

#include "../commands_helpers.h"
#include "../ddtrace.h"
#include "../msgpack_helpers.h"
#include "config_sync.h"
#include <mpack.h>

static dd_result _request_pack(
mpack_writer_t *nonnull w, void *nullable ATTR_UNUSED ctx);
static dd_result _request_pack(mpack_writer_t *nonnull w, void *nonnull ctx);
dd_result dd_command_process_config_sync(
mpack_node_t root, ATTR_UNUSED void *unspecnull ctx);

static const dd_command_spec _spec = {
.name = "config_sync",
.name_len = sizeof("config_sync") - 1,
.num_args = 0, // a single map
.num_args = 1,
.outgoing_cb = _request_pack,
.incoming_cb = dd_command_process_config_sync,
.config_features_cb = dd_command_process_config_features,
};

dd_result dd_config_sync(dd_conn *nonnull conn)
dd_result dd_config_sync(
dd_conn *nonnull conn, const struct config_sync_data *nonnull data)
{
return dd_command_exec(conn, &_spec, NULL);
return dd_command_exec(conn, &_spec, (void *)data);
}

static dd_result _request_pack(
mpack_writer_t *nonnull w, void *nullable ATTR_UNUSED ctx)
static dd_result _request_pack(mpack_writer_t *nonnull w, void *nonnull ctx_)
{
UNUSED(ctx);
UNUSED(w);
const struct config_sync_data *nonnull data =
(struct config_sync_data *)ctx_;

dd_mpack_write_nullable_cstr(w, data->rem_cfg_path);

return dd_success;
}
Expand Down
7 changes: 6 additions & 1 deletion appsec/src/extension/commands/config_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,9 @@

#include "../network.h"

dd_result dd_config_sync(dd_conn *nonnull conn);
struct config_sync_data {
char *nullable rem_cfg_path;
};

dd_result dd_config_sync(
dd_conn *nonnull conn, const struct config_sync_data *nonnull data);
35 changes: 34 additions & 1 deletion appsec/src/extension/ddappsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "user_tracking.h"

#include <json/json.h>
#include <zend_string.h>

#if ZTS
static atomic_int _thread_count;
Expand Down Expand Up @@ -100,7 +101,7 @@ static zend_extension ddappsec_extension_entry = {
PHP_DDAPPSEC_EXTNAME,
PHP_DDAPPSEC_VERSION,
"Datadog",
"https://github.com/DataDog/dd-appsec-php",
"https://github.com/DataDog/dd-trace-php",
"Copyright Datadog",
ddappsec_startup,
NULL,
Expand Down Expand Up @@ -253,6 +254,21 @@ void dd_appsec_rinit_once()
pthread_once(&_rinit_once_control, _rinit_once);
}

static void _warn_on_empty_service_or_env()
{
if (!get_global_DD_APPSEC_TESTING() && get_DD_REMOTE_CONFIG_ENABLED() &&
DDAPPSEC_G(enabled) != APPSEC_FULLY_DISABLED &&
(zend_string_equals_literal(get_DD_ENV(), "") ||
zend_string_equals_literal(get_DD_SERVICE(), ""))) {
mlog(dd_log_warning,
"AppSec is not disabled and Datadog service or env is empty. "
"Please set DD_SERVICE and DD_ENV rather than setting the "
"corresponding properties on the root span. Otherwise, remote "
"configuration for AppSec will use service=unnamed-php-service and "
"env=none");
}
}

// NOLINTNEXTLINE
static PHP_RINIT_FUNCTION(ddappsec)
{
Expand All @@ -265,6 +281,7 @@ static PHP_RINIT_FUNCTION(ddappsec)
dd_appsec_rinit_once();
zai_config_rinit();
_check_enabled();
_warn_on_empty_service_or_env();

if (DDAPPSEC_G(enabled) == APPSEC_FULLY_DISABLED) {
return SUCCESS;
Expand Down Expand Up @@ -378,6 +395,22 @@ static void _check_enabled()
};
}

__attribute__((visibility("default"))) void dd_appsec_rc_conf(
bool *nonnull appsec_features, bool *nonnull appsec_conf) // NOLINT
{
bool prev_enabled = DDAPPSEC_G(enabled);
bool prev_active = DDAPPSEC_G(active);
bool prev_to_be_configured = DDAPPSEC_G(to_be_configured);
_check_enabled();
DDAPPSEC_G(enabled) = prev_enabled;
DDAPPSEC_G(active) = prev_active;
DDAPPSEC_G(to_be_configured) = prev_to_be_configured;

*appsec_features = DDAPPSEC_G(enabled) == APPSEC_ENABLED_VIA_REMCFG;
// only enable ASM / ASM_DD / ASM_DATA if no rules file is specified
*appsec_conf = get_global_DD_APPSEC_RULES()->len == 0;
}

static PHP_FUNCTION(datadog_appsec_is_enabled)
{
if (zend_parse_parameters_none() == FAILURE) {
Expand Down
3 changes: 3 additions & 0 deletions appsec/src/extension/ddappsec.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ extern __thread void *unspecnull ATTR_TLS_LOCAL_DYNAMIC TSRMLS_CACHE;
void dd_appsec_rinit_once(void);
int dd_appsec_rshutdown(bool ignore_verdict);

__attribute__((visibility("default"))) void dd_appsec_rc_conf(
bool *nonnull appsec_features, bool *nonnull appsec_conf); // NOLINT

// Add a NO_CACHE version.
// Use tsrm_get_ls_cache() instead of thread-local _tsrmls_ls_cache
#ifdef ZTS
Expand Down
1 change: 1 addition & 0 deletions appsec/src/extension/ddappsec.version
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
global:
get_module;
dd_appsec_maybe_enable_helper;
dd_appsec_rc_conf;
local: *;
};
20 changes: 20 additions & 0 deletions appsec/src/extension/ddtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ static bool (*nullable _ddtrace_user_req_add_listeners)(

static zend_string *(*_ddtrace_ip_extraction_find)(zval *server);

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

static void dd_trace_load_symbols(void)
{
bool testing = get_global_DD_APPSEC_TESTING();
Expand Down Expand Up @@ -98,6 +100,14 @@ static void dd_trace_load_symbols(void)
dlerror()); // NOLINT(concurrency-mt-unsafe)
}

_ddtrace_remote_config_get_path =
dlsym(handle, "ddtrace_remote_config_get_path");
if (_ddtrace_remote_config_get_path == NULL && !testing) {
mlog(dd_log_error,
// NOLINTNEXTLINE(concurrency-mt-unsafe)
"Failed to load ddtrace_remote_config_get_path: %s", dlerror());
}

dlclose(handle);
}

Expand Down Expand Up @@ -358,6 +368,16 @@ zend_string *nullable dd_ip_extraction_find(zval *nonnull server)
return _ddtrace_ip_extraction_find(server);
}

const char *nullable dd_trace_remote_config_get_path()
{
if (!_ddtrace_remote_config_get_path) {
return NULL;
}
__auto_type path = _ddtrace_remote_config_get_path();
mlog(dd_log_trace, "Remote config path: %s", path ? path : "(unset)");
return path;
}

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 @@ -79,3 +79,5 @@ bool dd_trace_user_req_add_listeners(
ddtrace_user_req_listeners *nonnull listeners);

zend_string *nullable dd_ip_extraction_find(zval *nonnull server);

const char *nullable dd_trace_remote_config_get_path(void);
3 changes: 2 additions & 1 deletion appsec/src/extension/helper_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ dd_conn *nullable dd_helper_mgr_cur_conn(void)
}

// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
bool dd_on_runtime_path_update(zval *nullable old_val, zval *nonnull new_val, zend_string *nonnull new_str)
bool dd_on_runtime_path_update(zval *nullable old_val, zval *nonnull new_val,
zend_string *nullable new_str)
{
UNUSED(old_val);
UNUSED(new_str);
Expand Down
7 changes: 4 additions & 3 deletions appsec/src/extension/helper_process.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ void dd_helper_gshutdown(void);
void dd_helper_rshutdown(void);

typedef dd_result (*client_init_func)(dd_conn *nonnull, void *unspecnull ctx);
dd_conn *nullable dd_helper_mgr_acquire_conn(client_init_func nonnull, void *unspecnull ctx);
dd_conn *nullable dd_helper_mgr_acquire_conn(
client_init_func nonnull, void *unspecnull ctx);
dd_conn *nullable dd_helper_mgr_cur_conn(void);
void dd_helper_close_conn(void);

bool dd_on_runtime_path_update(
zval *nullable old_value, zval *nonnull new_value, zend_string *nonnull new_str);
bool dd_on_runtime_path_update(zval *nullable old_value,
zval *nonnull new_value, zend_string *nullable new_str);

#endif // DD_HELPER_MGR_H
5 changes: 3 additions & 2 deletions appsec/src/extension/msgpack_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,10 @@ static bool parse_element(
case mpack_type_int:
ZVAL_LONG(output, mpack_tag_int_value(&tag));
break;
case mpack_type_uint:
ZVAL_LONG(output, mpack_tag_int_value(&tag));
case mpack_type_uint: {
ZVAL_LONG(output, (long)mpack_tag_uint_value(&tag));
break;
}

case mpack_type_str: {
uint32_t length = mpack_tag_str_length(&tag);
Expand Down
Loading

0 comments on commit 90639bf

Please sign in to comment.