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

Perf: Translocate cache, reserve proto repeated fields #1027

Merged
merged 2 commits into from
Jan 30, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions Source/santad/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,9 @@ objc_library(
":EndpointSecurityEnrichedTypes",
":EndpointSecurityMessage",
":SNTDecisionCache",
"//Source/common:SantaCache",
"//Source/common:SantaVnode",
"//Source/common:SantaVnodeHash",
],
)

Expand Down
37 changes: 23 additions & 14 deletions Source/santad/Logs/EndpointSecurity/Serializers/Protobuf.mm
Original file line number Diff line number Diff line change
Expand Up @@ -447,28 +447,37 @@ static inline void EncodeCertificateInfo(::pbv1::CertificateInfo *pb_cert_info,
}

uint32_t arg_count = esapi_->ExecArgCount(&msg.es_msg().event.exec);
for (uint32_t i = 0; i < arg_count; i++) {
es_string_token_t tok = esapi_->ExecArg(&msg.es_msg().event.exec, i);
pb_exec->add_args(tok.data, tok.length);
if (arg_count > 0) {
pb_exec->mutable_args()->Reserve(arg_count);
for (uint32_t i = 0; i < arg_count; i++) {
es_string_token_t tok = esapi_->ExecArg(&msg.es_msg().event.exec, i);
pb_exec->add_args(tok.data, tok.length);
}
}

uint32_t env_count = esapi_->ExecEnvCount(&msg.es_msg().event.exec);
for (uint32_t i = 0; i < env_count; i++) {
es_string_token_t tok = esapi_->ExecEnv(&msg.es_msg().event.exec, i);
pb_exec->add_envs(tok.data, tok.length);
if (env_count > 0) {
pb_exec->mutable_envs()->Reserve(env_count);
for (uint32_t i = 0; i < env_count; i++) {
es_string_token_t tok = esapi_->ExecEnv(&msg.es_msg().event.exec, i);
pb_exec->add_envs(tok.data, tok.length);
}
}

if (msg.es_msg().version >= 4) {
int32_t max_fd = -1;
uint32_t fd_count = esapi_->ExecFDCount(&msg.es_msg().event.exec);
for (uint32_t i = 0; i < fd_count; i++) {
const es_fd_t *fd = esapi_->ExecFD(&msg.es_msg().event.exec, i);
max_fd = std::max(max_fd, fd->fd);
::pbv1::FileDescriptor *pb_fd = pb_exec->add_fds();
pb_fd->set_fd(fd->fd);
pb_fd->set_fd_type(GetFileDescriptorType(fd->fdtype));
if (fd->fdtype == PROX_FDTYPE_PIPE) {
pb_fd->set_pipe_id(fd->pipe.pipe_id);
if (fd_count > 0) {
pb_exec->mutable_fds()->Reserve(fd_count);
for (uint32_t i = 0; i < fd_count; i++) {
const es_fd_t *fd = esapi_->ExecFD(&msg.es_msg().event.exec, i);
max_fd = std::max(max_fd, fd->fd);
::pbv1::FileDescriptor *pb_fd = pb_exec->add_fds();
pb_fd->set_fd(fd->fd);
pb_fd->set_fd_type(GetFileDescriptorType(fd->fdtype));
if (fd->fdtype == PROX_FDTYPE_PIPE) {
pb_fd->set_pipe_id(fd->pipe.pipe_id);
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions Source/santad/Logs/EndpointSecurity/Serializers/Utilities.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

#include "Source/santad/Logs/EndpointSecurity/Serializers/Utilities.h"

#include "Source/common/SantaCache.h"
#import "Source/common/SantaVnode.h"
#include "Source/common/SantaVnodeHash.h"

// These functions are exported by the Security framework, but are not included in headers
extern "C" Boolean SecTranslocateIsTranslocatedURL(CFURLRef path, bool *isTranslocated,
CFErrorRef *__nullable error);
Expand All @@ -32,10 +36,17 @@ static inline void SetThreadIDs(uid_t uid, gid_t gid) {
}

NSString *OriginalPathForTranslocation(const es_process_t *es_proc) {
// Cache vnodes that have been determined to not be translocated
static SantaCache<SantaVnode, bool> isNotTranslocatedCache(1024);

if (!es_proc) {
return nil;
}

if (isNotTranslocatedCache.get(SantaVnode::VnodeForFile(es_proc->executable))) {
return nil;
}

// Note: Benchmarks showed better performance using `URLWithString` with a `file://` prefix
// compared to using `fileURLWithPath`.
CFURLRef cfExecURL = (__bridge CFURLRef)
Expand All @@ -58,6 +69,8 @@ static inline void SetThreadIDs(uid_t uid, gid_t gid) {
if (dropPrivs) {
SetThreadIDs(KAUTH_UID_NONE, KAUTH_GID_NONE);
}
} else {
isNotTranslocatedCache.set(SantaVnode::VnodeForFile(es_proc->executable), true);
}

return [origURL path];
Expand Down