Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix stat metrics accounting. #1354

Merged
merged 1 commit into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Source/common/SNTCommonEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ typedef NS_ENUM(NSInteger, SNTRuleCleanup) {
};

#ifdef __cplusplus

enum class FileAccessPolicyDecision {
kNoPolicy,
kDenied,
Expand All @@ -190,6 +191,19 @@ enum class FileAccessPolicyDecision {
kAllowedReadAccess,
kAllowedAuditOnly,
};

enum class StatChangeStep {
kNoChange = 0,
kMessageCreate,
kCodesignValidation,
};

enum class StatResult {
kOK = 0,
kStatError,
kDevnoInodeMismatch,
};

#endif

static const char *kSantaDPath =
Expand Down
6 changes: 5 additions & 1 deletion Source/santad/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -657,8 +657,8 @@ objc_library(
hdrs = ["EventProviders/EndpointSecurity/Message.h"],
deps = [
":EndpointSecurityClient",
":Metrics",
":WatchItemPolicy",
"//Source/common:SNTCommonEnums",
"//Source/santad/ProcessTree:process_tree",
],
)
Expand Down Expand Up @@ -719,6 +719,7 @@ objc_library(
srcs = ["Metrics.mm"],
hdrs = ["Metrics.h"],
deps = [
":EndpointSecurityMessage",
":SNTApplicationCoreMetrics",
"//Source/common:SNTCommonEnums",
"//Source/common:SNTLogging",
Expand Down Expand Up @@ -1184,7 +1185,10 @@ santa_unit_test(
name = "MetricsTest",
srcs = ["MetricsTest.mm"],
deps = [
":EndpointSecurityMessage",
":Metrics",
":MockEndpointSecurityAPI",
"//Source/common:SNTCommonEnums",
"//Source/common:SNTMetricSet",
"//Source/common:TestUtils",
"@OCMock",
Expand Down
19 changes: 9 additions & 10 deletions Source/santad/EventProviders/EndpointSecurity/Message.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@
#include <memory>
#include <string>

#include "Source/santad/Metrics.h"
#import "Source/common/SNTCommonEnums.h"
#include "Source/santad/ProcessTree/process_tree.h"

namespace santa::santad::event_providers::endpoint_security {

class EndpointSecurityAPI;
class MessagePeer;

class Message {
public:
Expand Down Expand Up @@ -54,12 +55,12 @@ class Message {

std::string ParentProcessName() const;

void UpdateStatState(santa::santad::StatChangeStep step) const;
void UpdateStatState(enum StatChangeStep step) const;

inline santa::santad::StatChangeStep StatChangeStep() const {
return stat_change_step_;
}
inline StatResult StatError() const { return stat_result_; }
inline StatChangeStep StatChangeStep() const { return stat_change_step_; }
inline StatResult StatResult() const { return stat_result_; }

friend class santa::santad::event_providers::endpoint_security::MessagePeer;

private:
std::shared_ptr<EndpointSecurityAPI> esapi_;
Expand All @@ -68,10 +69,8 @@ class Message {

std::string GetProcessName(pid_t pid) const;

mutable santa::santad::StatChangeStep stat_change_step_ =
santa::santad::StatChangeStep::kNoChange;
mutable santa::santad::StatResult stat_result_ =
santa::santad::StatResult::kOK;
mutable enum StatChangeStep stat_change_step_ = StatChangeStep::kNoChange;
mutable enum StatResult stat_result_ = StatResult::kOK;
};

} // namespace santa::santad::event_providers::endpoint_security
Expand Down
9 changes: 4 additions & 5 deletions Source/santad/EventProviders/EndpointSecurity/Message.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
Message::Message(std::shared_ptr<EndpointSecurityAPI> esapi, const es_message_t *es_msg)
: esapi_(std::move(esapi)), es_msg_(es_msg), process_token_(std::nullopt) {
esapi_->RetainMessage(es_msg);
UpdateStatState(santa::santad::StatChangeStep::kMessageCreate);
UpdateStatState(StatChangeStep::kMessageCreate);
}

Message::~Message() {
Expand Down Expand Up @@ -53,10 +53,10 @@
stat_result_ = other.stat_result_;
}

void Message::UpdateStatState(santa::santad::StatChangeStep step) const {
void Message::UpdateStatState(enum StatChangeStep step) const {
// Only update state for AUTH EXEC events and if no previous change was detected
if (es_msg_->event_type == ES_EVENT_TYPE_AUTH_EXEC &&
stat_change_step_ == santa::santad::StatChangeStep::kNoChange &&
stat_change_step_ == StatChangeStep::kNoChange &&
// Note: The following checks are required due to tests that only
// partially construct an es_message_t.
es_msg_->event.exec.target && es_msg_->event.exec.target->executable) {
Expand All @@ -67,8 +67,7 @@
if (ret != 0 || es_sb.st_ino != sb.st_ino || es_sb.st_dev != sb.st_dev) {
stat_change_step_ = step;
// Determine the specific condition that failed for tracking purposes
stat_result_ = (ret != 0) ? santa::santad::StatResult::kStatError
: santa::santad::StatResult::kDevnoInodeMismatch;
stat_result_ = (ret != 0) ? StatResult::kStatError : StatResult::kDevnoInodeMismatch;
}
}
}
Expand Down
17 changes: 6 additions & 11 deletions Source/santad/EventProviders/SNTEndpointSecurityClient.mm
Original file line number Diff line number Diff line change
Expand Up @@ -146,29 +146,24 @@ - (void)establishClientOrDie {
// sequence numbers are processed in order.
self->_metrics->UpdateEventStats(self->_processor, esMsg.operator->());

es_event_type_t eventType = esMsg->event_type;

if ([self handleContextMessage:esMsg]) {
int64_t processingEnd = clock_gettime_nsec_np(CLOCK_MONOTONIC);
self->_metrics->SetEventMetrics(self->_processor, eventType, EventDisposition::kProcessed,
processingEnd - processingStart, esMsg.StatChangeStep(),
esMsg.StatError());
self->_metrics->SetEventMetrics(self->_processor, EventDisposition::kProcessed,
processingEnd - processingStart, esMsg);
return;
}

if ([self shouldHandleMessage:esMsg]) {
[self handleMessage:std::move(esMsg)
recordEventMetrics:^(EventDisposition disposition) {
int64_t processingEnd = clock_gettime_nsec_np(CLOCK_MONOTONIC);
self->_metrics->SetEventMetrics(self->_processor, eventType, disposition,
processingEnd - processingStart, esMsg.StatChangeStep(),
esMsg.StatError());
self->_metrics->SetEventMetrics(self->_processor, disposition,
processingEnd - processingStart, esMsg);
}];
} else {
int64_t processingEnd = clock_gettime_nsec_np(CLOCK_MONOTONIC);
self->_metrics->SetEventMetrics(self->_processor, eventType, EventDisposition::kDropped,
processingEnd - processingStart, esMsg.StatChangeStep(),
esMsg.StatError());
self->_metrics->SetEventMetrics(self->_processor, EventDisposition::kDropped,
processingEnd - processingStart, esMsg);
}
});

Expand Down
18 changes: 3 additions & 15 deletions Source/santad/Metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#import "Source/common/SNTCommonEnums.h"
#import "Source/common/SNTMetricSet.h"
#include "Source/santad/EventProviders/EndpointSecurity/Message.h"

namespace santa::santad {

Expand All @@ -51,18 +52,6 @@ enum class FileAccessMetricStatus {
kBlockedUser,
};

enum class StatChangeStep {
kNoChange = 0,
kMessageCreate,
kCodesignValidation,
};

enum class StatResult {
kOK = 0,
kStatError,
kDevnoInodeMismatch,
};

using EventCountTuple = std::tuple<Processor, es_event_type_t, EventDisposition>;
using EventTimesTuple = std::tuple<Processor, es_event_type_t>;
using EventStatsTuple = std::tuple<Processor, es_event_type_t>;
Expand Down Expand Up @@ -96,9 +85,8 @@ class Metrics : public std::enable_shared_from_this<Metrics> {
// Used for tracking event sequence numbers to determine if drops occured
void UpdateEventStats(Processor processor, const es_message_t *msg);

void SetEventMetrics(Processor processor, es_event_type_t event_type,
EventDisposition disposition, int64_t nanos, StatChangeStep step,
StatResult stat_result);
void SetEventMetrics(Processor processor, EventDisposition event_disposition, int64_t nanos,
const santa::santad::event_providers::endpoint_security::Message &msg);

void SetRateLimitingMetrics(Processor processor, int64_t events_rate_limited_count);

Expand Down
17 changes: 11 additions & 6 deletions Source/santad/Metrics.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
/// limitations under the License.

#include "Source/santad/Metrics.h"

#include <EndpointSecurity/ESTypes.h>

#include <memory>
Expand Down Expand Up @@ -403,13 +404,17 @@
});
}

void Metrics::SetEventMetrics(Processor processor, es_event_type_t event_type,
EventDisposition event_disposition, int64_t nanos,
StatChangeStep step, StatResult stat_result) {
void Metrics::SetEventMetrics(
Processor processor, EventDisposition event_disposition, int64_t nanos,
const santa::santad::event_providers::endpoint_security::Message &msg) {
dispatch_sync(events_q_, ^{
event_counts_cache_[EventCountTuple{processor, event_type, event_disposition}]++;
event_times_cache_[EventTimesTuple{processor, event_type}] = nanos;
stat_change_cache_[EventStatChangeTuple{step, stat_result}]++;
event_counts_cache_[EventCountTuple{processor, msg->event_type, event_disposition}]++;
event_times_cache_[EventTimesTuple{processor, msg->event_type}] = nanos;

// Stat changes are only tracked for AUTH EXEC events
if (msg->event_type == ES_EVENT_TYPE_AUTH_EXEC) {
stat_change_cache_[EventStatChangeTuple{msg.StatChangeStep(), msg.StatResult()}]++;
}
});
}

Expand Down
Loading
Loading