Skip to content
This repository was archived by the owner on Feb 5, 2025. It is now read-only.

Commit 73ae919

Browse files
committed
Add ancestry annotator
1 parent 737525b commit 73ae919

18 files changed

Lines changed: 451 additions & 16 deletions

File tree

Source/common/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
12
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
23
load("//:helper.bzl", "santa_unit_test")
34

Source/common/santa.proto

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@ message FileDescriptor {
129129
// Process information
130130
message ProcessInfo {
131131
// Process ID of the process
132-
optional ProcessID id = 1;
132+
optional santa.pb.v1.ProcessID id = 1;
133133

134134
// Process ID of the parent process
135-
optional ProcessID parent_id = 2;
135+
optional santa.pb.v1.ProcessID parent_id = 2;
136136

137137
// Process ID of the process responsible for this one
138-
optional ProcessID responsible_id = 3;
138+
optional santa.pb.v1.ProcessID responsible_id = 3;
139139

140140
// Original parent ID, remains stable in the event a process is reparented
141141
optional int32 original_parent_pid = 4;
@@ -181,10 +181,10 @@ message ProcessInfo {
181181
// Light variant of ProcessInfo message to help minimize on-disk/on-wire sizes
182182
message ProcessInfoLight {
183183
// Process ID of the process
184-
optional ProcessID id = 1;
184+
optional santa.pb.v1.ProcessID id = 1;
185185

186186
// Process ID of the parent process
187-
optional ProcessID parent_id = 2;
187+
optional santa.pb.v1.ProcessID parent_id = 2;
188188

189189
// Original parent ID, remains stable in the event a process is reparented
190190
optional int32 original_parent_pid = 3;

Source/santad/BUILD

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ objc_library(
802802
"//Source/common:Unit",
803803
"//Source/santad/ProcessTree:process_tree",
804804
"//Source/santad/ProcessTree/annotations:originator",
805+
"//Source/santad/ProcessTree/annotations:ancestry",
805806
"@MOLXPCConnection",
806807
],
807808
)
@@ -840,7 +841,6 @@ macos_bundle(
840841
],
841842
entitlements = select({
842843
"//:adhoc_build": "com.google.santa.daemon.systemextension-adhoc.entitlements",
843-
# Non-adhoc builds get their entitlements from the provisioning profile.
844844
"//conditions:default": None,
845845
}),
846846
infoplists = ["Info.plist"],
@@ -1451,6 +1451,7 @@ test_suite(
14511451
"//Source/santad/Logs/EndpointSecurity/Writers/FSSpool:fsspool_test",
14521452
"//Source/santad/ProcessTree:process_tree_test",
14531453
"//Source/santad/ProcessTree/annotations:originator_test",
1454+
"//Source/santad/ProcessTree/annotations:ancestry_test",
14541455
],
14551456
visibility = ["//:santa_package_group"],
14561457
)

Source/santad/Logs/EndpointSecurity/Writers/FSSpool/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
12
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
23
load("//:helper.bzl", "santa_unit_test")
34

Source/santad/ProcessTree/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
12
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
23
load("//:helper.bzl", "santa_unit_test")
34

Source/santad/ProcessTree/annotations/BUILD

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@ cc_library(
2525
],
2626
)
2727

28+
cc_library(
29+
name = "ancestry",
30+
srcs = ["ancestry.cc"],
31+
hdrs = ["ancestry.h"],
32+
deps = [
33+
":annotator",
34+
"//Source/santad/ProcessTree:process",
35+
"//Source/santad/ProcessTree:process_tree",
36+
"//Source/santad/ProcessTree:process_tree_cc_proto",
37+
"@com_google_absl//absl/container:flat_hash_map",
38+
],
39+
)
40+
2841
santa_unit_test(
2942
name = "originator_test",
3043
srcs = ["originator_test.mm"],
@@ -35,3 +48,14 @@ santa_unit_test(
3548
"//Source/santad/ProcessTree:process_tree_test_helpers",
3649
],
3750
)
51+
52+
santa_unit_test(
53+
name = "ancestry_test",
54+
srcs = ["ancestry_test.mm"],
55+
deps = [
56+
":ancestry",
57+
"//Source/santad/ProcessTree:process",
58+
"//Source/santad/ProcessTree:process_tree_cc_proto",
59+
"//Source/santad/ProcessTree:process_tree_test_helpers",
60+
],
61+
)
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/// Copyright 2023 Google LLC
2+
///
3+
/// Licensed under the Apache License, Version 2.0 (the "License");
4+
/// you may not use this file except in compliance with the License.
5+
/// You may obtain a copy of the License at
6+
///
7+
/// https://www.apache.org/licenses/LICENSE-2.0
8+
///
9+
/// Unless required by applicable law or agreed to in writing, software
10+
/// distributed under the License is distributed on an "AS IS" BASIS,
11+
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
/// See the License for the specific language governing permissions and
13+
/// limitations under the License.
14+
#include "Source/santad/ProcessTree/annotations/ancestry.h"
15+
16+
#include "Source/santad/ProcessTree/process.h"
17+
#include "Source/santad/ProcessTree/process_tree.h"
18+
#include "Source/santad/ProcessTree/process_tree.pb.h"
19+
#include "absl/container/flat_hash_map.h"
20+
21+
namespace ptpb = ::santa::pb::v1::process_tree;
22+
23+
namespace santa::santad::process_tree {
24+
25+
::santa::pb::v1::process_tree::Annotations::Ancestry
26+
AncestryAnnotator::getAncestry() const {
27+
::santa::pb::v1::process_tree::Annotations::Ancestry ancestry;
28+
ancestry.CopyFrom(ancestry_);
29+
return ancestry;
30+
}
31+
32+
void AncestryAnnotator::AddEntryToAncestry(
33+
ptpb::Annotations::Ancestry &ancestry, int pid, uint64_t secondary_id) {
34+
ptpb::AncestryProcessID *ancestor = ancestry.add_ancestor();
35+
ancestor->set_pid(pid);
36+
ancestor->set_secondary_id(secondary_id);
37+
}
38+
39+
void AncestryAnnotator::CopyAncestorsToAncestry(
40+
ptpb::Annotations::Ancestry &ancestry,
41+
std::vector<std::shared_ptr<const Process>> ancestors) {
42+
// Add ancestors starting from the root process
43+
for (auto it = ancestors.rbegin(); it != ancestors.rend(); it++) {
44+
AddEntryToAncestry(ancestry, (*it)->pid_.pid, (*it)->creation_timestamp);
45+
}
46+
}
47+
48+
void AncestryAnnotator::AnnotateFork(ProcessTree &tree, const Process &parent,
49+
const Process &child) {
50+
ptpb::Annotations::Ancestry ancestry;
51+
// If parent process has ancestry annotation, copy and add parent.
52+
if (auto parent_annotation = tree.GetAnnotation<AncestryAnnotator>(parent)) {
53+
ancestry.CopyFrom((*parent_annotation)->getAncestry());
54+
AddEntryToAncestry(ancestry, parent.pid_.pid, parent.creation_timestamp);
55+
// Otherwise, get all ancestors of the child and add them.
56+
} else {
57+
std::vector<std::shared_ptr<const Process>> ancestors =
58+
tree.GetAncestors(child);
59+
CopyAncestorsToAncestry(ancestry, ancestors);
60+
}
61+
tree.AnnotateProcess(child, std::make_shared<AncestryAnnotator>(ancestry));
62+
}
63+
64+
void AncestryAnnotator::AnnotateExec(ProcessTree &tree,
65+
const Process &orig_process,
66+
const Process &new_process) {
67+
ptpb::Annotations::Ancestry ancestry;
68+
// If original process has ancestry annotation, copy entries.
69+
if (auto orig_process_annotation =
70+
tree.GetAnnotation<AncestryAnnotator>(orig_process)) {
71+
ancestry.CopyFrom((*orig_process_annotation)->getAncestry());
72+
// Otherwise, compute all ancestors of the new process and add them.
73+
} else {
74+
std::vector<std::shared_ptr<const Process>> ancestors =
75+
tree.GetAncestors(new_process);
76+
CopyAncestorsToAncestry(ancestry, ancestors);
77+
}
78+
tree.AnnotateProcess(new_process,
79+
std::make_shared<AncestryAnnotator>(ancestry));
80+
}
81+
82+
std::optional<ptpb::Annotations> AncestryAnnotator::Proto() const {
83+
auto annotation = ptpb::Annotations();
84+
auto *ancestry_ptr = annotation.mutable_ancestry();
85+
ancestry_ptr->CopyFrom(AncestryAnnotator::getAncestry());
86+
return annotation;
87+
}
88+
89+
} // namespace santa::santad::process_tree
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/// Copyright 2023 Google LLC
2+
///
3+
/// Licensed under the Apache License, Version 2.0 (the "License");
4+
/// you may not use this file except in compliance with the License.
5+
/// You may obtain a copy of the License at
6+
///
7+
/// https://www.apache.org/licenses/LICENSE-2.0
8+
///
9+
/// Unless required by applicable law or agreed to in writing, software
10+
/// distributed under the License is distributed on an "AS IS" BASIS,
11+
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
/// See the License for the specific language governing permissions and
13+
/// limitations under the License.
14+
#ifndef SANTA__SANTAD_PROCESSTREE_ANNOTATIONS_ANCESTRY_H
15+
#define SANTA__SANTAD_PROCESSTREE_ANNOTATIONS_ANCESTRY_H
16+
17+
#include <optional>
18+
19+
#include "Source/santad/ProcessTree/annotations/annotator.h"
20+
#include "Source/santad/ProcessTree/process.h"
21+
#include "Source/santad/ProcessTree/process_tree.pb.h"
22+
23+
namespace santa::santad::process_tree {
24+
25+
class AncestryAnnotator : public Annotator {
26+
public:
27+
// clang-format off
28+
AncestryAnnotator() {}
29+
explicit AncestryAnnotator(
30+
::santa::pb::v1::process_tree::Annotations::Ancestry ancestry)
31+
: ancestry_(ancestry) {};
32+
// clang-format on
33+
void AnnotateFork(ProcessTree &tree, const Process &parent,
34+
const Process &child) override;
35+
void AnnotateExec(ProcessTree &tree, const Process &orig_process,
36+
const Process &new_process) override;
37+
std::optional<::santa::pb::v1::process_tree::Annotations> Proto()
38+
const override;
39+
::santa::pb::v1::process_tree::Annotations::Ancestry getAncestry() const;
40+
41+
private:
42+
void AddEntryToAncestry(
43+
::santa::pb::v1::process_tree::Annotations::Ancestry &ancestry, int pid,
44+
uint64_t secondary_id);
45+
void CopyAncestorsToAncestry(
46+
::santa::pb::v1::process_tree::Annotations::Ancestry &ancestry,
47+
std::vector<std::shared_ptr<const Process>> ancestors);
48+
::santa::pb::v1::process_tree::Annotations::Ancestry ancestry_;
49+
};
50+
51+
} // namespace santa::santad::process_tree
52+
53+
#endif

0 commit comments

Comments
 (0)