Skip to content

Commit

Permalink
Merge branch 'main' into brettlangdon/gitlab.flask
Browse files Browse the repository at this point in the history
  • Loading branch information
emmettbutler authored Sep 2, 2024
2 parents 7c6ef25 + e36b8ea commit 136b03a
Show file tree
Hide file tree
Showing 12 changed files with 312 additions and 230 deletions.
53 changes: 0 additions & 53 deletions .circleci/config.templ.yml
Original file line number Diff line number Diff line change
Expand Up @@ -631,48 +631,6 @@ jobs:
pattern: 'opentelemetry'
snapshot: true

integration_agent:
<<: *machine_executor
parallelism: 2
steps:
- attach_workspace:
at: .
- checkout
- setup_riot
- start_docker_services:
services: ddagent
- run:
environment:
RIOT_RUN_RECOMPILE_REQS: "<< pipeline.parameters.riot_run_latest >>"
command: |
ulimit -c unlimited
./scripts/run-test-suite 'integration-latest*' <<pipeline.parameters.coverage>> 1
- run:
command: |
mkdir -p /tmp/core_dumps
cp core.* /tmp/core_dumps || true
./scripts/bt
when: on_fail
- store_artifacts:
name: "Store core dumps"
path: /tmp/core_dumps

integration_testagent:
<<: *machine_executor
steps:
- run_test:
snapshot: true
pattern: 'integration-snapshot*'
trace_agent_url: ""

vendor:
<<: *contrib_job_small
docker:
- image: *ddtrace_dev_image
steps:
- run_test:
pattern: 'vendor'

botocore:
<<: *machine_executor
parallelism: 6
Expand All @@ -682,17 +640,6 @@ jobs:
snapshot: true
docker_services: "localstack"

ddtracerun:
<<: *contrib_job
parallelism: 8
docker:
- image: *ddtrace_dev_image
- image: *redis_image
steps:
- run_test:
pattern: 'ddtracerun'
trace_agent_url: ""

test_logging:
<<: *contrib_job
docker:
Expand Down
25 changes: 25 additions & 0 deletions .gitlab/tests/core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,28 @@ telemetry:
parallel: 4
variables:
SUITE_NAME: "telemetry"

integration-testagent:
extends: .test_base_riot_snapshot
variables:
SUITE_NAME: "integration-snapshot*"

integration-agent:
extends: .test_base_riot
variables:
SUITE_NAME: "integration-latest*"

vendor:
extends: .test_base_riot
variables:
SUITE_NAME: "vendor"

ddtracerun:
extends: .test_base_riot
services:
- !reference [.test_base_riot, services]
- name: registry.ddbuild.io/redis:7.0.7
alias: redis
variables:
SUITE_NAME: "ddtracerun"
TEST_REDIS_HOST: "redis"
225 changes: 138 additions & 87 deletions ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectSplit.cpp
Original file line number Diff line number Diff line change
@@ -1,114 +1,165 @@
#include "AspectSplit.h"
#include "Initializer/Initializer.h"
#include "TaintedOps/TaintedOps.h"

template<class StrType>
py::list
api_split_text(const StrType& text, const optional<StrType>& separator, const optional<int> maxsplit)
static std::optional<py::object>
handle_potential_re_split(const py::tuple& args,
const py::tuple& sliced_args,
const py::kwargs& kwargs,
const TaintRangeMapTypePtr& tx_map)
{
const auto split = text.attr("split");
const auto split_result = split(separator, maxsplit);
const py::module re = py::module::import("re");
const py::object re_pattern_type = re.attr("Pattern");
const py::object types_module = py::module::import("types");

const auto tx_map = Initializer::get_tainting_map();
if (not tx_map or tx_map->empty()) {
return split_result;
}
// re.split aspect, either with pattern as first arg or with re module
if (const py::object module_type = types_module.attr("ModuleType");
isinstance(args[0], re_pattern_type) ||
(isinstance(args[0], module_type) && std::string(py::str(args[0].attr("__name__"))) == "re" &&
(std::string(py::str(args[0].attr("__package__"))).empty() ||
std::string(py::str(args[0].attr("__package__"))) == "re"))) {

if (auto ranges = api_get_ranges(text); not ranges.empty()) {
set_ranges_on_splitted(text, ranges, split_result, tx_map, false);
const py::object split_func = args[0].attr("split");
// Create a py::slice object to slice the args from index 1 to the end
py::list result = split_func(*sliced_args, **kwargs);

if (const int offset = isinstance(args[0], re_pattern_type) ? -1 : 0;
args.size() >= (static_cast<size_t>(3) + offset) && is_tainted(args[2 + offset].ptr(), tx_map)) {
for (auto& i : result) {
if (!i.is_none() and len(i) > 0) {
copy_and_shift_ranges_from_strings(args[2 + offset], i, 0, len(i), tx_map);
}
}
}
return result;
}

return split_result;
return std::nullopt;
}

template<class StrType>
py::list
api_rsplit_text(const StrType& text, const optional<StrType>& separator, const optional<int> maxsplit)
static py::object
split_text_common(const py::object& orig_function,
const int flag_added_args,
const py::args& args,
const py::kwargs& kwargs,
const std::string& split_func)
{
const auto rsplit = text.attr("rsplit");
const auto split_result = rsplit(separator, maxsplit);
const auto tx_map = Initializer::get_tainting_map();
if (not tx_map or tx_map->empty()) {
return split_result;
PyObject* result_or_args = process_flag_added_args(orig_function.ptr(), flag_added_args, args.ptr(), kwargs.ptr());
py::tuple args_tuple;
if (PyTuple_Check(result_or_args)) {
args_tuple = py::reinterpret_borrow<py::tuple>(result_or_args);
} else {
return py::reinterpret_borrow<py::list>(result_or_args);
}

if (auto ranges = api_get_ranges(text); not ranges.empty()) {
set_ranges_on_splitted(text, ranges, split_result, tx_map, false);
const auto& text = args_tuple[0];

const py::tuple sliced_args = len(args) > 1 ? args[py::slice(1, len(args), 1)] : py::tuple(); // (,)
auto result_o = text.attr(split_func.c_str())(*sliced_args, **kwargs); // returns['', ''] WHY?

const auto tx_map = Initializer::get_tainting_map();
if (!tx_map || tx_map->empty()) {
return result_o;
}
return split_result;

TRY_CATCH_ASPECT("split_aspect", , {
if (split_func == "split") {
if (auto re_split_result = handle_potential_re_split(args_tuple, sliced_args, kwargs, tx_map);
re_split_result.has_value()) {
return *re_split_result;
}
}

auto [ranges, ranges_error] = get_ranges(text.ptr(), tx_map);
if (!ranges_error and !ranges.empty()) {
set_ranges_on_splitted(text, ranges, result_o, tx_map, false);
}
});
return result_o;
}

template<class StrType>
py::list
api_splitlines_text(const StrType& text, bool keepends)
py::object
api_splitlines_text(const py::object& orig_function,
const int flag_added_args,
const py::args& args,
const py::kwargs& kwargs)
{
const auto splitlines = text.attr("splitlines");
const auto split_result = splitlines(keepends);
const auto tx_map = Initializer::get_tainting_map();
if (not tx_map or tx_map->empty()) {
return split_result;
const auto result_or_args = py::reinterpret_borrow<py::object>(
process_flag_added_args(orig_function.ptr(), flag_added_args, args.ptr(), kwargs.ptr()));

py::tuple args_tuple;
if (py::isinstance<py::tuple>(result_or_args)) {
args_tuple = result_or_args.cast<py::tuple>();
} else {
return result_or_args.cast<py::list>();
}

if (auto ranges = api_get_ranges(text); not ranges.empty()) {
set_ranges_on_splitted(text, ranges, split_result, tx_map, keepends);
const auto& text = args_tuple[0];
const py::tuple sliced_args = len(args) > 1 ? args[py::slice(1, len(args), 1)] : py::tuple();
py::object result_o = text.attr("splitlines")(*sliced_args, **kwargs);

const auto tx_map = Initializer::get_tainting_map();
if (!tx_map || tx_map->empty()) {
return result_o;
}
return split_result;

TRY_CATCH_ASPECT("split_aspect", , {
auto [ranges, ranges_error] = get_ranges(text.ptr(), tx_map);
if (ranges_error || ranges.empty()) {
return result_o;
}

// Retrieve keepends and check that is a boolean. If not, return the original value
// because it could be a method of a different type.
bool keepends_is_other_type = false;
bool keepends = false;
if (kwargs.contains("keepends")) {
if (py::isinstance<py::bool_>(kwargs["keepends"])) {
keepends = kwargs["keepends"].cast<bool>();
} else {
keepends_is_other_type = true;
}
} else {
if (args.size() > 1) {
if (py::isinstance<py::bool_>(args[1])) {
keepends = args[1].cast<bool>();
} else {
keepends_is_other_type = true;
}
}
}

if (!keepends_is_other_type) {
set_ranges_on_splitted(text, ranges, result_o, tx_map, keepends);
}
});
return result_o;
}

void
pyexport_aspect_split(py::module& m)
{
m.def("_aspect_split",
&api_split_text<py::str>,
"text"_a,
"separator"_a = py::none(),
"maxsplit"_a = -1,
py::return_value_policy::move);
m.def("_aspect_split",
&api_split_text<py::bytes>,
"text"_a,
"separator"_a = py::none(),
"maxsplit"_a = -1,
py::return_value_policy::move);
m.def("_aspect_split",
&api_split_text<py::bytearray>,
"text"_a,
"separator"_a = py::none(),
"maxsplit"_a = -1,
py::return_value_policy::move);
m.def("_aspect_rsplit",
&api_rsplit_text<py::str>,
"text"_a,
"separator"_a = py::none(),
"maxsplit"_a = -1,
py::return_value_policy::move);
m.def("_aspect_rsplit",
&api_rsplit_text<py::bytes>,
"text"_a,
"separator"_a = py::none(),
"maxsplit"_a = -1,
py::return_value_policy::move);
m.def("_aspect_rsplit",
&api_rsplit_text<py::bytearray>,
"text"_a,
"separator"_a = py::none(),
"maxsplit"_a = -1,
py::return_value_policy::move);
// cppcheck-suppress assignBoolToPointer
m.def("_aspect_splitlines",
&api_splitlines_text<py::str>,
"text"_a,
"keepends"_a = false,
py::return_value_policy::move);
// cppcheck-suppress assignBoolToPointer
m.def("_aspect_splitlines",
&api_splitlines_text<py::bytes>,
"text"_a,
"keepends"_a = false,
py::return_value_policy::move);
// cppcheck-suppress assignBoolToPointer
m.def(
"_aspect_split",
[](const py::object& orig_function, const int flag_added_args, const py::args& args, const py::kwargs& kwargs) {
return split_text_common(orig_function, flag_added_args, args, kwargs, "split");
},
"orig_function"_a = py::none(),
"flag_added_args"_a = 0,
py::return_value_policy::move);

m.def(
"_aspect_rsplit",
[](const py::object& orig_function, const int flag_added_args, const py::args& args, const py::kwargs& kwargs) {
return split_text_common(orig_function, flag_added_args, args, kwargs, "rsplit");
},
"orig_function"_a = py::none(),
"flag_added_args"_a = 0,
py::return_value_policy::move);

m.def("_aspect_splitlines",
&api_splitlines_text<py::bytearray>,
"text"_a,
"keepends"_a = false,
&api_splitlines_text,
"orig_function"_a = py::none(),
"flag_added_args"_a = 0,
py::return_value_policy::move);
}
}
16 changes: 5 additions & 11 deletions ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectSplit.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,11 @@

#include "Helpers.h"

template<class StrType>
py::list
api_split_text(const StrType& text, const optional<StrType>& separator, optional<int> maxsplit);

template<class StrType>
py::list
api_rsplit_text(const StrType& text, const optional<StrType>& separator, optional<int> maxsplit);

template<class StrType>
py::list
api_splitlines_text(const StrType& text, bool keepends);
py::object
api_splitlines_text(const py::object& orig_function,
int flag_added_args,
const py::args& args,
const py::kwargs& kwargs);

void
pyexport_aspect_split(py::module& m);
3 changes: 1 addition & 2 deletions ddtrace/appsec/_iast/_taint_tracking/Aspects/Helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,8 @@ convert_escaped_text_to_taint_text(const StrType& taint_escaped_text, TaintRange
* @param tx_map: The taint map to apply the ranges.
* @param include_separator: If the separator should be included in the splitted parts.
*/
template<class StrType>
bool
set_ranges_on_splitted(const StrType& source_str,
set_ranges_on_splitted(const py::object& source_str,
const TaintRangeRefs& source_ranges,
const py::list& split_result,
const TaintRangeMapTypePtr& tx_map,
Expand Down
Loading

0 comments on commit 136b03a

Please sign in to comment.