-
Notifications
You must be signed in to change notification settings - Fork 297
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ProcessTree: add core process tree logic (1/4) (#1236)
* ProcessTree: add core process tree logic * make Step implicitly called by Handle* methods * lint * naming convention * widen pidversion to be generic * move os specific backfill to os specific impl * simplify ts checking * retain/release a whole vec of pids * document processtoken * lint * namespace * add process tree to project-wide unit test target * case change annotations * case change annotations * remove stray comment * default initialize seen_timestamps * fix missing initialization of refcnt and tombstoned * reshuffle pb namespace * pr review * move annotation registration to tree construction * use factory function for tree construction
- Loading branch information
Showing
12 changed files
with
1,096 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
load("@rules_cc//cc:defs.bzl", "cc_proto_library") | ||
load("//:helper.bzl", "santa_unit_test") | ||
|
||
package( | ||
default_visibility = ["//:santa_package_group"], | ||
) | ||
|
||
cc_library( | ||
name = "process", | ||
hdrs = ["process.h"], | ||
deps = [ | ||
"//Source/santad/ProcessTree/annotations:annotator", | ||
"@com_google_absl//absl/container:flat_hash_map", | ||
"@com_google_absl//absl/status:statusor", | ||
"@com_google_absl//absl/synchronization", | ||
], | ||
) | ||
|
||
objc_library( | ||
name = "process_tree", | ||
srcs = [ | ||
"process_tree.cc", | ||
"process_tree_macos.mm", | ||
], | ||
hdrs = ["process_tree.h"], | ||
sdk_dylibs = [ | ||
"bsm", | ||
], | ||
deps = [ | ||
":process", | ||
"//Source/santad/ProcessTree/annotations:annotator", | ||
"@com_google_absl//absl/container:flat_hash_map", | ||
"@com_google_absl//absl/container:flat_hash_set", | ||
"@com_google_absl//absl/status", | ||
"@com_google_absl//absl/synchronization", | ||
], | ||
) | ||
|
||
proto_library( | ||
name = "process_tree_proto", | ||
srcs = ["process_tree.proto"], | ||
) | ||
|
||
cc_proto_library( | ||
name = "process_tree_cc_proto", | ||
deps = [":process_tree_proto"], | ||
) | ||
|
||
objc_library( | ||
name = "process_tree_test_helpers", | ||
srcs = ["process_tree_test_helpers.mm"], | ||
hdrs = ["process_tree_test_helpers.h"], | ||
deps = [ | ||
":process_tree", | ||
"@com_google_absl//absl/synchronization", | ||
], | ||
) | ||
|
||
santa_unit_test( | ||
name = "process_tree_test", | ||
srcs = ["process_tree_test.mm"], | ||
deps = [ | ||
":process", | ||
":process_tree_test_helpers", | ||
"//Source/santad/ProcessTree/annotations:annotator", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package( | ||
default_visibility = ["//:santa_package_group"], | ||
) | ||
|
||
cc_library( | ||
name = "annotator", | ||
hdrs = ["Annotator.h"], | ||
deps = [ | ||
"//Source/santad/ProcessTree:process_tree_cc_proto", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/// Copyright 2023 Google LLC | ||
/// | ||
/// Licensed under the Apache License, Version 2.0 (the "License"); | ||
/// you may not use this file except in compliance with the License. | ||
/// You may obtain a copy of the License at | ||
/// | ||
/// https://www.apache.org/licenses/LICENSE-2.0 | ||
/// | ||
/// Unless required by applicable law or agreed to in writing, software | ||
/// distributed under the License is distributed on an "AS IS" BASIS, | ||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
/// See the License for the specific language governing permissions and | ||
/// limitations under the License. | ||
#ifndef SANTA__SANTAD_PROCESSTREE_ANNOTATIONS_BASE_H | ||
#define SANTA__SANTAD_PROCESSTREE_ANNOTATIONS_BASE_H | ||
|
||
#include <optional> | ||
|
||
#include "Source/santad/ProcessTree/process_tree.pb.h" | ||
|
||
namespace santa::santad::process_tree { | ||
|
||
class ProcessTree; | ||
class Process; | ||
|
||
class Annotator { | ||
public: | ||
virtual ~Annotator() = default; | ||
|
||
virtual void AnnotateFork(ProcessTree &tree, const Process &parent, | ||
const Process &child) = 0; | ||
virtual void AnnotateExec(ProcessTree &tree, const Process &orig_process, | ||
const Process &new_process) = 0; | ||
virtual std::optional<::santa::pb::v1::process_tree::Annotations> Proto() const = 0; | ||
}; | ||
|
||
} // namespace santa::santad::process_tree | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/// Copyright 2023 Google LLC | ||
/// | ||
/// Licensed under the Apache License, Version 2.0 (the "License"); | ||
/// you may not use this file except in compliance with the License. | ||
/// You may obtain a copy of the License at | ||
/// | ||
/// https://www.apache.org/licenses/LICENSE-2.0 | ||
/// | ||
/// Unless required by applicable law or agreed to in writing, software | ||
/// distributed under the License is distributed on an "AS IS" BASIS, | ||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
/// See the License for the specific language governing permissions and | ||
/// limitations under the License. | ||
#ifndef SANTA__SANTAD_PROCESSTREE_PROCESS_H | ||
#define SANTA__SANTAD_PROCESSTREE_PROCESS_H | ||
|
||
#include <unistd.h> | ||
|
||
#include <memory> | ||
#include <string> | ||
#include <typeindex> | ||
#include <vector> | ||
|
||
#include "Source/santad/ProcessTree/annotations/annotator.h" | ||
#include "absl/container/flat_hash_map.h" | ||
|
||
namespace santa::santad::process_tree { | ||
|
||
struct Pid { | ||
pid_t pid; | ||
uint64_t pidversion; | ||
|
||
friend bool operator==(const struct Pid &lhs, const struct Pid &rhs) { | ||
return lhs.pid == rhs.pid && lhs.pidversion == rhs.pidversion; | ||
} | ||
friend bool operator!=(const struct Pid &lhs, const struct Pid &rhs) { | ||
return !(lhs == rhs); | ||
} | ||
}; | ||
|
||
template <typename H> | ||
H AbslHashValue(H h, const struct Pid &p) { | ||
return H::combine(std::move(h), p.pid, p.pidversion); | ||
} | ||
|
||
struct Cred { | ||
uid_t uid; | ||
gid_t gid; | ||
|
||
friend bool operator==(const struct Cred &lhs, const struct Cred &rhs) { | ||
return lhs.uid == rhs.uid && lhs.gid == rhs.gid; | ||
} | ||
friend bool operator!=(const struct Cred &lhs, const struct Cred &rhs) { | ||
return !(lhs == rhs); | ||
} | ||
}; | ||
|
||
struct Program { | ||
std::string executable; | ||
std::vector<std::string> arguments; | ||
|
||
friend bool operator==(const struct Program &lhs, const struct Program &rhs) { | ||
return lhs.executable == rhs.executable && lhs.arguments == rhs.arguments; | ||
} | ||
friend bool operator!=(const struct Program &lhs, const struct Program &rhs) { | ||
return !(lhs == rhs); | ||
} | ||
}; | ||
|
||
// Fwd decls | ||
class ProcessTree; | ||
|
||
class Process { | ||
public: | ||
explicit Process(const Pid pid, const Cred cred, | ||
std::shared_ptr<const Program> program, | ||
std::shared_ptr<const Process> parent) | ||
: pid_(pid), | ||
effective_cred_(cred), | ||
program_(program), | ||
annotations_(), | ||
parent_(parent), | ||
refcnt_(0), | ||
tombstoned_(false) {} | ||
Process(const Process &) = default; | ||
Process& operator=(const Process &) = delete; | ||
Process(Process &&) = default; | ||
Process& operator=(Process &&) = delete; | ||
|
||
// Const "attributes" are public | ||
const struct Pid pid_; | ||
const struct Cred effective_cred_; | ||
const std::shared_ptr<const Program> program_; | ||
|
||
private: | ||
// This is not API. | ||
// The tree helper methods are the API, and we just happen to implement | ||
// annotation storage and the parent relation in memory on the process right | ||
// now. | ||
friend class ProcessTree; | ||
absl::flat_hash_map<std::type_index, std::shared_ptr<const Annotator>> | ||
annotations_; | ||
std::shared_ptr<const Process> parent_; | ||
// TODO(nickmg): atomic here breaks the build. | ||
int refcnt_; | ||
// If the process is tombstoned, the event removing it from the tree has been | ||
// processed, but refcnt>0 keeps it alive. | ||
bool tombstoned_; | ||
}; | ||
|
||
} // namespace santa::santad::process_tree | ||
|
||
#endif |
Oops, something went wrong.