Skip to content

Commit 342ff32

Browse files
authored
Merge pull request #3126 from DataDog/glopes/libddwaf-upd
Upgrade libddwaf
2 parents 47ce337 + 8ae6b14 commit 342ff32

44 files changed

Lines changed: 904 additions & 3271 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1528,4 +1528,4 @@ composer.lock: composer.json
15281528
$(call run_composer_with_retry,,)
15291529

15301530
.PHONY: dev dist_clean clean cores all clang_format_check clang_format_fix install sudo_install test_c test_c_mem test_extension_ci test_zai test_zai_asan test install_ini install_all \
1531-
.apk .rpm .deb .tar.gz sudo debug prod strict run-tests.php verify_pecl_file_definitions verify_package_xml cbindgen cbindgen_binary
1531+
.apk .rpm .deb .tar.gz sudo debug prod strict run-tests.php verify_pecl_file_definitions verify_package_xml cbindgen cbindgen_binary

appsec/.clang-tidy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
# readability-function-cognitive-complexity temporarily disabled until clang-tidy is fixed
33
# right now emalloc causes it to misbehave
4-
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'
4+
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,-hicpp-no-array-decay'
55
WarningsAsErrors: '*'
66
HeaderFilterRegex: ''
77
AnalyzeTemporaryDtors: false

appsec/src/helper/engine.cpp

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
//
44
// This product includes software developed at Datadog
55
// (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
6-
#include <algorithm>
76
#include <atomic>
87
#include <memory>
98
#include <spdlog/spdlog.h>
@@ -14,9 +13,39 @@
1413
#include "json_helper.hpp"
1514
#include "metrics.hpp"
1615
#include "parameter_view.hpp"
16+
#include "remote_config/changeset.hpp"
17+
#include "remote_config/listeners/config_aggregators/asm_aggregator.hpp"
1718
#include "std_logging.hpp"
1819
#include "subscriber/waf.hpp"
1920

21+
namespace {
22+
using dds::remote_config::asm_aggregator;
23+
using dds::remote_config::changeset;
24+
25+
changeset build_changeset(const rapidjson::Value &doc)
26+
{
27+
changeset changeset;
28+
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
29+
if (doc.HasMember(asm_aggregator::ASM_ADDED)) {
30+
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
31+
for (const auto &entry : doc[asm_aggregator::ASM_ADDED].GetObject()) {
32+
changeset.added.emplace(
33+
entry.name.GetString(), dds::json_to_parameter(entry.value));
34+
}
35+
}
36+
37+
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
38+
if (doc.HasMember(asm_aggregator::ASM_REMOVED)) {
39+
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
40+
const auto &removed = doc[asm_aggregator::ASM_REMOVED];
41+
for (const auto &entry : removed.GetArray()) {
42+
changeset.removed.emplace(entry.GetString());
43+
}
44+
}
45+
46+
return changeset;
47+
}
48+
} // namespace
2049
namespace dds {
2150

2251
void engine::subscribe(std::unique_ptr<subscriber> sub)
@@ -25,16 +54,18 @@ void engine::subscribe(std::unique_ptr<subscriber> sub)
2554
}
2655

2756
void engine::update(
28-
engine_ruleset &ruleset, metrics::telemetry_submitter &submit_metric)
57+
const rapidjson::Document &doc, metrics::telemetry_submitter &submit_metric)
2958
{
3059
std::vector<std::unique_ptr<subscriber>> new_subscribers;
3160
auto old_common =
3261
std::atomic_load_explicit(&common_, std::memory_order_acquire);
3362
new_subscribers.reserve(old_common->subscribers.size());
34-
dds::parameter param = json_to_parameter(ruleset.get_document());
63+
changeset const changeset = build_changeset(doc);
3564
for (auto &sub : old_common->subscribers) {
3665
try {
37-
new_subscribers.emplace_back(sub->update(param, submit_metric));
66+
std::unique_ptr<subscriber> new_sub =
67+
sub->update(changeset, submit_metric);
68+
new_subscribers.emplace_back(std::move(new_sub));
3869
} catch (const std::exception &e) {
3970
SPDLOG_WARN("Failed to update subscriber {}: {}", sub->get_name(),
4071
e.what());
@@ -127,15 +158,24 @@ std::unique_ptr<engine> engine::from_settings(
127158
metrics::telemetry_submitter &msubmitter)
128159
{
129160
auto &&rules_path = eng_settings.rules_file_or_default();
130-
auto ruleset = engine_ruleset::from_path(rules_path);
161+
auto ruleset = read_file(rules_path);
162+
163+
rapidjson::Document doc;
164+
rapidjson::ParseResult const result =
165+
doc.Parse(ruleset.data(), ruleset.size());
166+
if ((result == nullptr) || !doc.IsObject()) {
167+
throw parsing_error("invalid json rule");
168+
}
169+
dds::parameter ruleset_param = json_to_parameter(doc);
170+
131171
std::unique_ptr<engine> engine_ptr{
132172
engine::create(eng_settings.trace_rate_limit)};
133173

134174
try {
135175
SPDLOG_DEBUG("Will load WAF rules from {}", rules_path);
136176
// may throw std::exception
137-
auto waf =
138-
waf::instance::from_settings(eng_settings, ruleset, msubmitter);
177+
auto waf = waf::instance::from_settings(
178+
eng_settings, std::move(ruleset_param), msubmitter);
139179
engine_ptr->subscribe(std::move(waf));
140180
} catch (...) {
141181
DD_STDLOG(DD_STDLOG_WAF_INIT_FAILED, rules_path);

appsec/src/helper/engine.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
#pragma once
77

88
#include "action.hpp"
9-
#include "config.hpp"
10-
#include "engine_ruleset.hpp"
119
#include "engine_settings.hpp"
1210
#include "metrics.hpp"
1311
#include "parameter.hpp"
@@ -103,8 +101,8 @@ class engine {
103101

104102
// Should not be called concurrently but safely publishes changes to common_
105103
// the rc client has a lock that ensures this
106-
virtual void update(
107-
engine_ruleset &ruleset, metrics::telemetry_submitter &submit_metric);
104+
virtual void update(const rapidjson::Document &doc,
105+
metrics::telemetry_submitter &submit_metric);
108106

109107
protected:
110108
explicit engine(uint32_t trace_rate_limit)

appsec/src/helper/engine_ruleset.cpp

Lines changed: 0 additions & 56 deletions
This file was deleted.

appsec/src/helper/engine_ruleset.hpp

Lines changed: 0 additions & 42 deletions
This file was deleted.

appsec/src/helper/json_helper.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,10 @@ void json_to_object(ddwaf_object *object, T &doc)
146146
}
147147
}
148148

149-
dds::parameter json_to_parameter(const rapidjson::Document &doc)
149+
dds::parameter json_to_parameter(const rapidjson::Value &value)
150150
{
151151
dds::parameter obj;
152-
json_to_object(obj, doc);
152+
json_to_object(obj, value);
153153
return obj;
154154
}
155155

@@ -249,7 +249,7 @@ void json_helper::merge_arrays(rapidjson::Value &destination,
249249
}
250250
}
251251

252-
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
252+
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters,misc-no-recursion)
253253
void json_helper::merge_objects(rapidjson::Value &destination,
254254
rapidjson::Value &source, rapidjson::Value::AllocatorType &allocator)
255255
{
@@ -260,7 +260,18 @@ void json_helper::merge_objects(rapidjson::Value &destination,
260260
throw invalid_type("source value not an object");
261261
}
262262
for (auto it = source.MemberBegin(); it != source.MemberEnd(); ++it) {
263-
destination.AddMember(it->name, it->value, allocator);
263+
if (destination.HasMember(it->name)) {
264+
auto &cur = destination[it->name];
265+
if (cur.IsArray() && it->value.IsArray()) {
266+
merge_arrays(cur, it->value, allocator);
267+
} else if (cur.IsObject() && it->value.IsObject()) {
268+
merge_objects(cur, it->value, allocator);
269+
} else {
270+
destination[it->name] = it->value;
271+
}
272+
} else {
273+
destination.AddMember(it->name, it->value, allocator);
274+
}
264275
}
265276
}
266277

appsec/src/helper/json_helper.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class string_buffer {
5050
};
5151

5252
std::string parameter_to_json(const dds::parameter_view &pv);
53-
dds::parameter json_to_parameter(const rapidjson::Document &doc);
53+
dds::parameter json_to_parameter(const rapidjson::Value &value);
5454
dds::parameter json_to_parameter(std::string_view json);
5555

5656
namespace json_helper {

appsec/src/helper/network/proto.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ struct request_shutdown {
270270
static constexpr request_id id = request_id::request_shutdown;
271271

272272
dds::parameter data;
273-
std::uint64_t api_sec_samp_key;
273+
std::uint64_t api_sec_samp_key{0};
274274

275275
request() = default;
276276
request(const request &) = delete;

appsec/src/helper/parameter.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "parameter.hpp"
77
#include "ddwaf.h"
88
#include "exception.hpp"
9+
#include <algorithm>
910

1011
namespace dds {
1112

@@ -130,6 +131,45 @@ bool parameter::add(std::string_view name, parameter &&entry) noexcept
130131
return true;
131132
}
132133

134+
// NOLINTNEXTLINE(misc-no-recursion)
135+
bool parameter::merge(parameter other)
136+
{
137+
if (other.type() != type()) {
138+
return false;
139+
}
140+
141+
if (type() == parameter_type::array) {
142+
for (size_t i = 0; i < other.size(); ++i) {
143+
ddwaf_object_array_add(this, other[i]);
144+
ddwaf_object_invalid(&other[i]);
145+
}
146+
return true;
147+
}
148+
if (type() == parameter_type::map) {
149+
for (size_t i = 0; i < other.size(); ++i) {
150+
auto &oentry = other[i];
151+
const std::string_view &key = oentry.key();
152+
153+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
154+
auto *start = static_cast<parameter *>(ddwaf_object::array);
155+
auto *end = start + this->nbEntries;
156+
auto *orig_entry = std::find_if(
157+
start, end, [&key](const auto &v) { return v.key() == key; });
158+
159+
if (orig_entry == end) { // not found
160+
ddwaf_object_map_addl_nc(
161+
this, key.data(), key.length(), &oentry);
162+
ddwaf_object_invalid(&oentry); // also nulls out key
163+
} else {
164+
// a merge is required
165+
orig_entry->merge(std::move(oentry));
166+
}
167+
}
168+
return true;
169+
}
170+
return false;
171+
}
172+
133173
parameter &parameter::operator[](size_t index) const
134174
{
135175
if (!is_container()) {

0 commit comments

Comments
 (0)