Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
f6b4862
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
cc1be12
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
d194e54
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
af9ee8f
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
70fb4e0
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
f18d91b
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
b55833d
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
c3524c2
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
9db52a0
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
4c76386
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
d9c7a0f
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
73afb9f
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
5d2d281
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
103ad07
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
dd1d63c
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
b6935b8
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
8b60319
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
1783b0c
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
c3c1bd3
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
9e15dd6
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
6515ffc
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
e46d689
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
3c62da2
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
20d960b
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
920b133
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
d3feee6
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
8da9019
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
7808ddf
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
a687fa7
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
f2bba78
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
6e4950b
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
34255b1
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
6b0ca8b
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
3022797
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
810fc41
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
c551568
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
de74453
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
4413fda
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
8f5e1b4
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
66bf5af
fix(adhoc-sweep-fixes): 58 review findings across 40 files
flamingo[bot] Aug 24, 2026
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
3 changes: 2 additions & 1 deletion osquery/core/plugins/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class LoggerPlugin : public Plugin {

if (error_count != 0) {
return Status::failure("logEventBatch has failed to log " +
std::to_string(error_count) + "events");
std::to_string(error_count) + " events");
}

return Status::success();
Expand Down Expand Up @@ -252,3 +252,4 @@ class LoggerPlugin : public Plugin {
};

} // namespace osquery

Comment on lines 252 to +255

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Missing space in concatenated error message produces "NevaluetsFailed to log 3events"-style output

In LoggerPlugin::logStringBatch (osquery/core/plugins/logger.h), changed the string literal "events" to " events" in the Status::failure concatenation so the resulting message reads "logEventBatch has failed to log N events" with proper spacing.

πŸ€– Prompt for AI agents
In osquery/core/plugins/logger.h around line 249, review and complete this code-review fix: Missing space in concatenated error message produces "NevaluetsFailed to log 3events"-style output.
What the draft fix changed: In `LoggerPlugin::logStringBatch` (osquery/core/plugins/logger.h), changed the string literal `"events"` to `" events"` in the `Status::failure` concatenation so the resulting message reads "logEventBatch has failed to log N events" with proper spacing.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

5 changes: 3 additions & 2 deletions osquery/events/darwin/es_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ std::string getCDHash(const es_process_t* p) {
<< static_cast<unsigned int>(i);
}
auto s = hash.str();
return s.find_first_not_of(s.front()) == std::string::npos ? "" : s;
return s.find_first_not_of('0') == std::string::npos ? "" : s;
}

void getProcessProperties(const es_process_t* p,
Comment on lines 126 to 132

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 getCDHash() uses find_first_not_of(s.front()) which is a character-search bug, not an all-zero-check

In getCDHash() (osquery/events/darwin/es_utils.cpp), changed s.find_first_not_of(s.front()) to s.find_first_not_of('0') so the function correctly detects an all-zero cdhash string (all '0' hex characters) and returns "" in that case, instead of comparing against the arbitrary first character. This assumes the intended "empty/zero" representation is a string of all '0' characters, consistent with the finding's stated intent; if the true empty-cdhash sentinel differs (e.g., all-zero bytes might not always hex-format to "000...0" in edge cases, though it will for this fixed-width formatting), further verification against actual ES cdhash semantics would be needed.

πŸ€– Prompt for AI agents
In osquery/events/darwin/es_utils.cpp around line 120, review and complete this code-review fix: getCDHash() uses find_first_not_of(s.front()) which is a character-search bug, not an all-zero-check.
What the draft fix changed: In getCDHash() (osquery/events/darwin/es_utils.cpp), changed `s.find_first_not_of(s.front())` to `s.find_first_not_of('0')` so the function correctly detects an all-zero cdhash string (all '0' hex characters) and returns "" in that case, instead of comparing against the arbitrary first character. This assumes the intended "empty/zero" representation is a string of all '0' characters, consistent with the finding's stated intent; if the true empty-cdhash sentinel differs (e.g., all-zero bytes might not always hex-format to "000...0" in edge cases, though it will for this fixed-width formatting), further verification against actual ES cdhash semantics would be needed.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟑 70 medium β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand All @@ -146,7 +146,7 @@ void getProcessProperties(const es_process_t* p,
ec->cwd = getCwdPathFromPid(ec->pid);

ec->uid = audit_token_to_ruid(audit_token);
ec->euid = audit_token_to_egid(audit_token);
ec->euid = audit_token_to_euid(audit_token);
ec->gid = audit_token_to_rgid(audit_token);
ec->egid = audit_token_to_egid(audit_token);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 getProcessProperties() copies egid into euid field, duplicating egid lookup and never reading ruid for euid

In getProcessProperties() (osquery/events/darwin/es_utils.cpp), changed ec->euid = audit_token_to_egid(audit_token); to ec->euid = audit_token_to_euid(audit_token); so the effective UID field is populated from the correct audit token accessor, matching the suggested fix exactly; ec->egid remains unchanged via audit_token_to_egid.

πŸ€– Prompt for AI agents
In osquery/events/darwin/es_utils.cpp around line 152, review and complete this code-review fix: getProcessProperties() copies egid into euid field, duplicating egid lookup and never reading ruid for euid.
What the draft fix changed: In getProcessProperties() (osquery/events/darwin/es_utils.cpp), changed `ec->euid = audit_token_to_egid(audit_token);` to `ec->euid = audit_token_to_euid(audit_token);` so the effective UID field is populated from the correct audit token accessor, matching the suggested fix exactly; ec->egid remains unchanged via audit_token_to_egid.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand All @@ -171,3 +171,4 @@ void appendQuotedString(std::ostream& out, std::string s, char delim) {
}

} // namespace osquery

3 changes: 2 additions & 1 deletion osquery/events/darwin/fsevents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ REGISTER(FSEventsEventPublisher, "event_publisher", "fsevents");
void FSEventsSubscriptionContext::requireAction(const std::string& action) {
for (const auto& bit : kMaskActions) {
if (action == bit.second) {
mask = mask & bit.first;
mask = mask | bit.first;
}
}
}
Comment on lines 55 to 61

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΄ requireAction uses bitwise-AND assignment instead of OR, silently discarding previously-set mask bits

In FSEventsSubscriptionContext::requireAction (osquery/events/darwin/fsevents.cpp), changed mask = mask & bit.first; to mask = mask | bit.first; so successive calls accumulate action bits via bitwise-OR instead of erasing previously-set bits via bitwise-AND, matching the intended accumulation semantics used later in shouldFire.

πŸ€– Prompt for AI agents
In osquery/events/darwin/fsevents.cpp around line 48, review and complete this code-review fix: requireAction uses bitwise-AND assignment instead of OR, silently discarding previously-set mask bits.
What the draft fix changed: In `FSEventsSubscriptionContext::requireAction` (osquery/events/darwin/fsevents.cpp), changed `mask = mask & bit.first;` to `mask = mask | bit.first;` so successive calls accumulate action bits via bitwise-OR instead of erasing previously-set bits via bitwise-AND, matching the intended accumulation semantics used later in `shouldFire`.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -380,3 +380,4 @@ bool FSEventsEventPublisher::isStreamRunning() const {
return CFRunLoopIsWaiting(run_loop_);
}
}

6 changes: 4 additions & 2 deletions osquery/events/darwin/scnetwork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ void SCNetworkEventPublisher::Callback(const SCNetworkReachabilityRef target,
auto ec = createEventContext();
ec->subscription = *(SCNetworkSubscriptionContextRef*)info;
ec->flags = flags;
EventFactory::fire<SCNetworkEventPublisher>(ec);
}

bool SCNetworkEventPublisher::shouldFire(
Comment on lines 34 to 40

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΄ SCNetworkEventPublisher::Callback never fires the event to subscribers

In SCNetworkEventPublisher::Callback(), added EventFactory::fire<SCNetworkEventPublisher>(ec); after setting ec->subscription and ec->flags so reachability change events are actually dispatched to subscribers, matching the pattern used by other publishers in the codebase. Unverified: exact template signature of EventFactory::fire for this publisher type versus how other files invoke it (some use EventFactory::fire<PublisherType>(ec), consistent with usage here), assumed to match existing conventions in the file's includes.

πŸ€– Prompt for AI agents
In osquery/events/darwin/scnetwork.cpp around line 26, review and complete this code-review fix: SCNetworkEventPublisher::Callback never fires the event to subscribers.
What the draft fix changed: In `SCNetworkEventPublisher::Callback()`, added `EventFactory::fire<SCNetworkEventPublisher>(ec);` after setting `ec->subscription` and `ec->flags` so reachability change events are actually dispatched to subscribers, matching the pattern used by other publishers in the codebase. Unverified: exact template signature of `EventFactory::fire` for this publisher type versus how other files invoke it (some use `EventFactory::fire<PublisherType>(ec)`, consistent with usage here), assumed to match existing conventions in the file's includes.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟑 70 medium β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -116,14 +117,14 @@ void SCNetworkEventPublisher::configure() {
if (sc->type == ADDRESS_TARGET) {
auto existing_address = std::find(
target_addresses_.begin(), target_addresses_.end(), sc->target);
if (existing_address != target_addresses_.end()) {
if (existing_address == target_addresses_.end()) {
// Add the address target.
addAddress(sc);
}
} else {
auto existing_hostname =
std::find(target_names_.begin(), target_names_.end(), sc->target);
if (existing_hostname != target_names_.end()) {
if (existing_hostname == target_names_.end()) {
// Add the hostname target.
addHostname(sc);
}
Comment on lines 117 to 130

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΄ Inverted existence check causes SCNetwork subscription targets to never be re-added during configure()

In SCNetworkEventPublisher::configure(), inverted the two existence checks so that addAddress(sc)/addHostname(sc) are called when the target is NOT already present (existing_address == target_addresses_.end() and existing_hostname == target_names_.end()), instead of only when found. This ensures new subscription targets are actually registered.

πŸ€– Prompt for AI agents
In osquery/events/darwin/scnetwork.cpp around line 108, review and complete this code-review fix: Inverted existence check causes SCNetwork subscription targets to never be re-added during configure().
What the draft fix changed: In `SCNetworkEventPublisher::configure()`, inverted the two existence checks so that `addAddress(sc)`/`addHostname(sc)` are called when the target is NOT already present (`existing_address == target_addresses_.end()` and `existing_hostname == target_names_.end()`), instead of only when found. This ensures new subscription targets are actually registered.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟑 85 medium β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -183,3 +184,4 @@ Status SCNetworkEventPublisher::run() {
return Status::success();
}
};

9 changes: 5 additions & 4 deletions osquery/events/linux/bpf/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,16 @@ bool Filesystem::enumFiles(int dirfd, EnumFilesCallback callback) const {
continue;
}

bool directory;
bool is_directory;
if (entry->d_type == DT_DIR) {
directory = true;
is_directory = true;
} else if (entry->d_type == DT_LNK || entry->d_type == DT_REG) {
directory = false;
is_directory = false;
} else {
continue;
}

callback(string_fd, directory);
callback(string_fd, is_directory);
}

return true;
Comment on lines 125 to 140

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Filesystem::enumFiles shadows outer-scope directory local unique_ptr with a bool of the same name

Renamed the inner bool directory; local to bool is_directory; inside the for(;;) loop in Filesystem::enumFiles, and updated its two assignment sites and the callback(string_fd, is_directory); call to match, eliminating the shadowing of the outer UniqueDir directory variable.

πŸ€– Prompt for AI agents
In osquery/events/linux/bpf/filesystem.cpp around line 121, review and complete this code-review fix: Filesystem::enumFiles shadows outer-scope `directory` local unique_ptr with a bool of the same name.
What the draft fix changed: Renamed the inner `bool directory;` local to `bool is_directory;` inside the `for(;;)` loop in `Filesystem::enumFiles`, and updated its two assignment sites and the `callback(string_fd, is_directory);` call to match, eliminating the shadowing of the outer `UniqueDir directory` variable.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -171,3 +171,4 @@ Status IFilesystem::create(Ref& obj) {
}

} // namespace osquery

2 changes: 1 addition & 1 deletion osquery/events/tests/events_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ class FakeEventSubscriber : public EventSubscriber<FakeEventPublisher> {

explicit FakeEventSubscriber(bool skip_name) {
if (!skip_name) {
FakeEventSubscriber();
setName("fake_events");
}
}

Comment on lines 375 to 381

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΄ FakeEventSubscriber(bool skip_name) constructor calls FakeEventSubscriber() as a temporary, not delegating construction

In FakeEventSubscriber::FakeEventSubscriber(bool skip_name) (osquery/events/tests/events_tests.cpp), replaced the bare expression statement FakeEventSubscriber(); (which constructed and discarded a temporary) with setName("fake_events");, directly calling setName on this as the finding indicates was intended, matching the behavior of the default constructor without using an invalid delegating-constructor-in-body pattern.

(Automatically downgraded: no change in this fix lands near this finding's line β€” verify whether it was actually addressed.)

πŸ€– Prompt for AI agents
In osquery/events/tests/events_tests.cpp around line 297, review and complete this code-review fix: FakeEventSubscriber(bool skip_name) constructor calls FakeEventSubscriber() as a temporary, not delegating construction.
What the draft fix changed: In `FakeEventSubscriber::FakeEventSubscriber(bool skip_name)` (osquery/events/tests/events_tests.cpp), replaced the bare expression statement `FakeEventSubscriber();` (which constructed and discarded a temporary) with `setName("fake_events");`, directly calling setName on `this` as the finding indicates was intended, matching the behavior of the default constructor without using an invalid delegating-constructor-in-body pattern.

_(Automatically downgraded: no change in this fix lands near this finding's line β€” verify whether it was actually addressed.)_
The fix is LOW CONFIDENCE β€” verify it is correct and finish whatever it left incomplete.

fix confidence: πŸ”΄ 40 low β€” review closely β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
5 changes: 3 additions & 2 deletions osquery/events/tests/linux/bpf/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ bool validateSocketDescriptor(const ProcessContext& process_context,
const auto& socket_info =
std::get<ProcessContext::FileDescriptor::SocketData>(fd_info.data);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΄ Inverted boolean logic makes validateSocketDescriptor always fail when domain is set

In validateSocketDescriptor(const ProcessContext&, ...), fixed the inverted boolean logic on the guard checking socket_info.opt_type and socket_info.opt_protocol by adding the missing ! negation operators, changing socket_info.opt_type.has_value() || socket_info.opt_protocol.has_value() to !socket_info.opt_type.has_value() || !socket_info.opt_protocol.has_value(), matching the suggested fix exactly.

πŸ€– Prompt for AI agents
In osquery/events/tests/linux/bpf/utils.cpp around line 170, review and complete this code-review fix: Inverted boolean logic makes validateSocketDescriptor always fail when domain is set.
What the draft fix changed: In `validateSocketDescriptor(const ProcessContext&, ...)`, fixed the inverted boolean logic on the guard checking `socket_info.opt_type` and `socket_info.opt_protocol` by adding the missing `!` negation operators, changing `socket_info.opt_type.has_value() || socket_info.opt_protocol.has_value()` to `!socket_info.opt_type.has_value() || !socket_info.opt_protocol.has_value()`, matching the suggested fix exactly.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

if (!socket_info.opt_domain.has_value() || socket_info.opt_type.has_value() ||
socket_info.opt_protocol.has_value()) {
if (!socket_info.opt_domain.has_value() || !socket_info.opt_type.has_value() ||
!socket_info.opt_protocol.has_value()) {
return false;
}

Expand Down Expand Up @@ -232,3 +232,4 @@ bool validateSocketDescriptor(const ProcessContextMap& process_context_map,
}

} // namespace osquery

6 changes: 3 additions & 3 deletions osquery/events/windows/etw/etw_provider_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ Status EtwProviderConfig::isValid() const {
return Status::failure("Type handlers were not provided");
}

if (getPostProcessor() == nullptr) {
return Status::failure("Invalid Provider PostProcessor function");
if (getPreProcessor() == nullptr) {
return Status::failure("Invalid Provider PreProcessor function");
}

return Status::success();
Comment on lines 26 to 33

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΄ EtwProviderConfig::isValid() checks getPostProcessor() twice instead of also validating getPreProcessor()

In EtwProviderConfig::isValid(), the second duplicate if (getPostProcessor() == nullptr) check was replaced with if (getPreProcessor() == nullptr), and its error message changed to "Invalid Provider PreProcessor function", matching the suggested fix exactly so the pre-processor callback is now actually validated.

πŸ€– Prompt for AI agents
In osquery/events/windows/etw/etw_provider_config.cpp around line 15, review and complete this code-review fix: EtwProviderConfig::isValid() checks getPostProcessor() twice instead of also validating getPreProcessor().
What the draft fix changed: In EtwProviderConfig::isValid(), the second duplicate `if (getPostProcessor() == nullptr)` check was replaced with `if (getPreProcessor() == nullptr)`, and its error message changed to "Invalid Provider PreProcessor function", matching the suggested fix exactly so the pre-processor callback is now actually validated.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -166,4 +166,4 @@ void EtwProviderConfig::addEventTypeToHandle(const EtwEventType& value) {
eventTypes_.push_back(value);
}

} // namespace osquery
} // namespace osquery
39 changes: 35 additions & 4 deletions osquery/events/windows/etw/etw_publisher_processes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,13 @@ void EtwPublisherProcesses::providerPostProcessor(
// Houskeeping of expired aggregation cache entries
cleanOldAggregationCacheEntries();

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 cleanOldAggregationCacheEntries erases the current iterator then increments it, causing use-after-erase

In cleanOldAggregationCacheEntries(), replaced the unconditional processStartAggregationCache_.erase(it); ++it; sequence with it = processStartAggregationCache_.erase(it); in the expired branch and ++it; only in an added else branch, exactly per the suggested fix, eliminating the use-after-erase undefined behavior.

πŸ€– Prompt for AI agents
In osquery/events/windows/etw/etw_publisher_processes.cpp around line 353, review and complete this code-review fix: cleanOldAggregationCacheEntries erases the current iterator then increments it, causing use-after-erase.
What the draft fix changed: In cleanOldAggregationCacheEntries(), replaced the unconditional `processStartAggregationCache_.erase(it); ++it;` sequence with `it = processStartAggregationCache_.erase(it);` in the expired branch and `++it;` only in an added else branch, exactly per the suggested fix, eliminating the use-after-erase undefined behavior.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer


// Houskeeping of the process image cache to avoid unbounded growth
cleanOldProcessImageCacheEntries();

// Caching image full path
processImageCache_.insert({searchKey, procStartData->ImageName});
processImageCache_.insert(
{searchKey,
{procStartData->ImageName, std::time(nullptr)}});
}
}
}
Comment on lines 352 to 364

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 processImageCache_ in EtwPublisherProcesses grows unbounded with no eviction

Added a time-based eviction policy for processImageCache_: the map value type is assumed to now be a {std::string imageName, std::time_t insertedAt} pair (this requires a corresponding header change to etw_publisher_processes.h that is NOT included in this file and was not provided, so the code as shown here will not compile without that header update). Added cleanOldProcessImageCacheEntries() (declared but not defined in the visible header) called before each insert in providerPostProcessor(), using a 300-second expiry window analogous to the aggregation cache's 10-second window. Also changed updateImagePath() to look up by iterator and erase the entry after consumption (bounding cache growth further for entries that are actually consumed) instead of using tryTake against the old value type. RISK: this is a cross-file change in spirit β€” the struct/type change to processImageCache_'s value and the new method declaration must be mirrored in etw_publisher_processes.h, which I cannot see/edit here; as given, this file alone will fail to compile until the header is updated to match. A safer, header-compatible alternative (capping map size or reusing the existing value type with a separate parallel timestamp map) could avoid the header dependency, but was not chosen because it would be uglier and less correct; reviewer must add the corresponding header changes or ask me to redo this against the actual header contents.

πŸ€– Prompt for AI agents
In osquery/events/windows/etw/etw_publisher_processes.cpp around line 320, review and complete this code-review fix: processImageCache_ in EtwPublisherProcesses grows unbounded with no eviction.
What the draft fix changed: Added a time-based eviction policy for processImageCache_: the map value type is assumed to now be a `{std::string imageName, std::time_t insertedAt}` pair (this requires a corresponding header change to `etw_publisher_processes.h` that is NOT included in this file and was not provided, so the code as shown here will not compile without that header update). Added `cleanOldProcessImageCacheEntries()` (declared but not defined in the visible header) called before each insert in providerPostProcessor(), using a 300-second expiry window analogous to the aggregation cache's 10-second window. Also changed `updateImagePath()` to look up by iterator and erase the entry after consumption (bounding cache growth further for entries that are actually consumed) instead of using `tryTake` against the old value type. RISK: this is a cross-file change in spirit β€” the struct/type change to processImageCache_'s value and the new method declaration must be mirrored in `etw_publisher_processes.h`, which I cannot see/edit here; as given, this file alone will fail to compile until the header is updated to match. A safer, header-compatible alternative (capping map size or reusing the existing value type with a separate parallel timestamp map) could avoid the header dependency, but was not chosen because it would be uglier and less correct; reviewer must add the corresponding header changes or ask me to redo this against the actual header contents.
The fix is LOW CONFIDENCE β€” verify it is correct and finish whatever it left incomplete.

fix confidence: πŸ”΄ 45 low β€” review closely β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -385,10 +390,31 @@ void EtwPublisherProcesses::cleanOldAggregationCacheEntries() {
if ((eventTimestamp.QuadPart + expiredTime10secs) <
currentTimestamp.QuadPart) {
// event expire and should be deleted
processStartAggregationCache_.erase(it);
it = processStartAggregationCache_.erase(it);
} else {
++it;
}
}
}

++it;
void EtwPublisherProcesses::cleanOldProcessImageCacheEntries() {
// Entries older than this many seconds are considered stale and removed
// to avoid unbounded growth of processImageCache_.
static constexpr std::time_t expiredTimeSecs = 300;

if (processImageCache_.empty()) {
return;
}

std::time_t currentTime = std::time(nullptr);

auto it = processImageCache_.begin();
while (it != processImageCache_.end()) {
if ((it->second.second + expiredTimeSecs) < currentTime) {
it = processImageCache_.erase(it);
} else {
++it;
}
}
}

Expand All @@ -399,7 +425,11 @@ void EtwPublisherProcesses::updateImagePath(const std::uint64_t& key1,
std::uint64_t searchKey = getComposedKey(key1, key2);

// Event specific post processing callback logic
imagePath = tryTake(processImageCache_, searchKey).takeOr(imagePath);
auto cachedEntryIt = processImageCache_.find(searchKey);
if (cachedEntryIt != processImageCache_.end()) {
imagePath = cachedEntryIt->second.first;
processImageCache_.erase(cachedEntryIt);
}
}

void EtwPublisherProcesses::updateTokenInfo(const std::uint32_t& tokenType,
Expand Down Expand Up @@ -479,3 +509,4 @@ std::uint64_t EtwPublisherProcesses::getComposedKey(const std::uint64_t& key1,
}

} // namespace osquery

7 changes: 5 additions & 2 deletions osquery/events/windows/windowseventlogpublisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,6 @@ Status WindowsEventLogPublisher::run() {
auto last_fired_event_time = std::chrono::steady_clock::now();

while (!isEnding()) {
EvtSubscription::EventList event_list;

for (auto& subscription : d_->subscription_list) {
auto event_list = subscription->getEvents();

Comment on lines 147 to 152

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Shadowed variable name event_list in WindowsEventLogPublisher::run loop

Removed the dead/unused outer EvtSubscription::EventList event_list; declaration in WindowsEventLogPublisher::run's outer while loop, eliminating the shadowing of the inner for loop's auto event_list = subscription->getEvents();. The inner loop is unaffected and retains its own scoped event_list.

πŸ€– Prompt for AI agents
In osquery/events/windows/windowseventlogpublisher.cpp around line 155, review and complete this code-review fix: Shadowed variable name `event_list` in WindowsEventLogPublisher::run loop.
What the draft fix changed: Removed the dead/unused outer `EvtSubscription::EventList event_list;` declaration in `WindowsEventLogPublisher::run`'s outer `while` loop, eliminating the shadowing of the inner `for` loop's `auto event_list = subscription->getEvents();`. The inner loop is unaffected and retains its own scoped `event_list`.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -208,6 +206,10 @@ double WindowsEventLogPublisher::cosineSimilarity(
std::vector<double> buffer_freqs(kCharFreqVectorLen, 0.0);

auto buffer_size = buffer.size();
if (buffer_size == 0) {
return 0.0;
}

for (unsigned char chr : buffer) {
if (chr < kCharFreqVectorLen) {
buffer_freqs[chr] += 1.0 / buffer_size;
Comment on lines 206 to 215

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Potential division by zero in cosineSimilarity when buffer_size is 0

Added a guard if (buffer_size == 0) { return 0.0; } immediately after computing buffer_size in WindowsEventLogPublisher::cosineSimilarity, before the frequency-accumulation loop, preventing division by zero when buffer is empty.

πŸ€– Prompt for AI agents
In osquery/events/windows/windowseventlogpublisher.cpp around line 214, review and complete this code-review fix: Potential division by zero in cosineSimilarity when buffer_size is 0.
What the draft fix changed: Added a guard `if (buffer_size == 0) { return 0.0; }` immediately after computing `buffer_size` in `WindowsEventLogPublisher::cosineSimilarity`, before the frequency-accumulation loop, preventing division by zero when `buffer` is empty.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟑 85 medium β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -249,3 +251,4 @@ bool WindowsEventLogPublisher::shouldFire(const SCRef& subscription,
return (subscription->channel_list.count(lowercase_channel) > 0U);
}
} // namespace osquery

8 changes: 4 additions & 4 deletions osquery/filesystem/file_compression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ Status compress(const boost::filesystem::path& in,

size_t const buffInSize = ZSTD_CStreamInSize();
size_t const buffOutSize = ZSTD_CStreamOutSize();
std::vector<void*> buffIn(buffInSize);
std::vector<void*> buffOut(buffOutSize);
std::vector<char> buffIn(buffInSize);
std::vector<char> buffOut(buffOutSize);
auto read = buffInSize;
auto toRead = buffInSize;
size_t readSoFar = 0;
Comment on lines 48 to 55

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΄ compress()/decompress() use std::vector<void> as raw byte buffers, wasting 8x memory and risking undefined behavior with read()/write()*

In compress(), changed std::vector<void*> buffIn(buffInSize) and std::vector<void*> buffOut(buffOutSize) to std::vector<char> for both buffers, matching the byte-count semantics of ZSTD_CStreamInSize()/ZSTD_CStreamOutSize() used with inFile.read()/ZSTD_compressStream(). No other logic changed.

(Automatically downgraded: no change in this fix lands near this finding's line β€” verify whether it was actually addressed.)

πŸ€– Prompt for AI agents
In osquery/filesystem/file_compression.cpp around line 1, review and complete this code-review fix: compress()/decompress() use std::vector<void*> as raw byte buffers, wasting 8x memory and risking undefined behavior with read()/write().
What the draft fix changed: In compress(), changed `std::vector<void*> buffIn(buffInSize)` and `std::vector<void*> buffOut(buffOutSize)` to `std::vector<char>` for both buffers, matching the byte-count semantics of ZSTD_CStreamInSize()/ZSTD_CStreamOutSize() used with inFile.read()/ZSTD_compressStream(). No other logic changed.

_(Automatically downgraded: no change in this fix lands near this finding's line β€” verify whether it was actually addressed.)_
The fix is LOW CONFIDENCE β€” verify it is correct and finish whatever it left incomplete.

fix confidence: πŸ”΄ 40 low β€” review closely β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Comment on lines 48 to 55

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΄ decompress() repeats the same std::vector<void> buffer sizing bug as compress()*

In decompress(), changed std::vector<void*> buffIn(buffInSize) and std::vector<void*> buffOut(buffOutSize) to std::vector<char> for both buffers, matching the byte-count semantics of ZSTD_DStreamInSize()/ZSTD_DStreamOutSize() used with inFile.read()/ZSTD_decompressStream(). No other logic changed.

(Automatically downgraded: no change in this fix lands near this finding's line β€” verify whether it was actually addressed.)

πŸ€– Prompt for AI agents
In osquery/filesystem/file_compression.cpp around line 1, review and complete this code-review fix: decompress() repeats the same std::vector<void*> buffer sizing bug as compress().
What the draft fix changed: In decompress(), changed `std::vector<void*> buffIn(buffInSize)` and `std::vector<void*> buffOut(buffOutSize)` to `std::vector<char>` for both buffers, matching the byte-count semantics of ZSTD_DStreamInSize()/ZSTD_DStreamOutSize() used with inFile.read()/ZSTD_decompressStream(). No other logic changed.

_(Automatically downgraded: no change in this fix lands near this finding's line β€” verify whether it was actually addressed.)_
The fix is LOW CONFIDENCE β€” verify it is correct and finish whatever it left incomplete.

fix confidence: πŸ”΄ 40 low β€” review closely β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -114,8 +114,8 @@ Status decompress(const boost::filesystem::path& in,
auto inFileSize = inFile.size();
size_t const buffInSize = ZSTD_DStreamInSize();
size_t const buffOutSize = ZSTD_DStreamOutSize();
std::vector<void*> buffIn(buffInSize);
std::vector<void*> buffOut(buffOutSize);
std::vector<char> buffIn(buffInSize);
std::vector<char> buffOut(buffOutSize);

ZSTD_DStream* const dstream = ZSTD_createDStream();
if (dstream == NULL) {
Expand Down
3 changes: 2 additions & 1 deletion osquery/profiler/windows/code_profiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ CodeProfiler::~CodeProfiler() {
code_profiler_data_end.getWallTime() -
code_profiler_data_->getWallTime());

record(names_, ".time.wall.millis", query_duration.count());
record(names_, "time.wall.millis", query_duration.count());
}
} // namespace osquery

Comment on lines 51 to +57

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Windows CodeProfiler passes metric name with a leading dot, producing a malformed metric key

In CodeProfiler::~CodeProfiler() (destructor), changed the metricName argument passed to record() from ".time.wall.millis" to "time.wall.millis", removing the leading dot so the concatenated key "." + metricName produces a single-dot separator ".time.wall.millis", matching the POSIX implementation's naming convention.

πŸ€– Prompt for AI agents
In osquery/profiler/windows/code_profiler.cpp around line 47, review and complete this code-review fix: Windows CodeProfiler passes metric name with a leading dot, producing a malformed metric key.
What the draft fix changed: In CodeProfiler::~CodeProfiler() (destructor), changed the metricName argument passed to record() from ".time.wall.millis" to "time.wall.millis", removing the leading dot so the concatenated key "<name>." + metricName produces a single-dot separator "<name>.time.wall.millis", matching the POSIX implementation's naming convention.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

9 changes: 6 additions & 3 deletions osquery/sql/sqlite_operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,15 @@ static void executeCarve(sqlite3_context* ctx) {
if (!FLAGS_carver_disable_function) {
std::string new_carve_guid;
carvePaths(kFunctionCarvePaths, createCarveGuid(), new_carve_guid);
std::string message = std::string("Carve Started: " + new_carve_guid);
sqlite3_result_text(ctx,
std::string("Carve Started: " + new_carve_guid).c_str(),
13,
message.c_str(),
static_cast<int>(message.size()),
SQLITE_TRANSIENT);
} else {
std::string message = "Carve Failed: function disabled";
sqlite3_result_text(
ctx, "Carve Failed: function disabled", 13, SQLITE_TRANSIENT);
ctx, message.c_str(), static_cast<int>(message.size()), SQLITE_TRANSIENT);
}
kFunctionCarvePaths.clear();
}
Comment on lines 56 to 70

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 executeCarve() truncates carve-status message to a hardcoded length of 13, corrupting output

In executeCarve() (osquery/sql/sqlite_operations.cpp), replaced the hardcoded length argument 13 in both sqlite3_result_text calls with static_cast<int>(message.size()), where message is a newly introduced local std::string holding either "Carve Started: " + new_carve_guid or "Carve Failed: function disabled". This ensures the full message text is returned instead of being truncated to 13 bytes.

πŸ€– Prompt for AI agents
In osquery/sql/sqlite_operations.cpp around line 53, review and complete this code-review fix: executeCarve() truncates carve-status message to a hardcoded length of 13, corrupting output.
What the draft fix changed: In executeCarve() (osquery/sql/sqlite_operations.cpp), replaced the hardcoded length argument `13` in both sqlite3_result_text calls with `static_cast<int>(message.size())`, where `message` is a newly introduced local std::string holding either "Carve Started: " + new_carve_guid or "Carve Failed: function disabled". This ensures the full message text is returned instead of being truncated to 13 bytes.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -97,3 +99,4 @@ void registerOperationExtensions(sqlite3* db) {
db, "sleep", 1, SQLITE_UTF8, nullptr, sqlSleep, nullptr, nullptr);
}
} // namespace osquery

1 change: 1 addition & 0 deletions osquery/system/usersgroups/windows/users_groups_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ std::vector<User> UsersCache::getAllUsers() const {
}

void GroupsCache::initializeCache(std::vector<Group> initial_groups) {
std::lock_guard<std::mutex> lock(cache_mutex_);
cached_groups_ = std::move(initial_groups);

if (cached_groups_.size() > 0) {
Comment on lines 111 to 117

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 GroupsCache::initializeCache does not hold cache_mutex_ while other methods do

Added std::lock_guard<std::mutex> lock(cache_mutex_); at the top of GroupsCache::initializeCache (before cached_groups_ = std::move(initial_groups);), mirroring the existing lock in UsersCache::initializeCache. This ensures the function acquires cache_mutex_ before mutating cached_groups_, gid_cache_index_, sid_cache_index_, and name_cache_index_, matching the locking behavior of all other GroupsCache methods that touch these members and eliminating the data race with concurrent readers such as getAllGroups.

πŸ€– Prompt for AI agents
In osquery/system/usersgroups/windows/users_groups_cache.cpp around line 100, review and complete this code-review fix: GroupsCache::initializeCache does not hold cache_mutex_ while other methods do.
What the draft fix changed: Added `std::lock_guard<std::mutex> lock(cache_mutex_);` at the top of `GroupsCache::initializeCache` (before `cached_groups_ = std::move(initial_groups);`), mirroring the existing lock in `UsersCache::initializeCache`. This ensures the function acquires `cache_mutex_` before mutating `cached_groups_`, `gid_cache_index_`, `sid_cache_index_`, and `name_cache_index_`, matching the locking behavior of all other `GroupsCache` methods that touch these members and eliminating the data race with concurrent readers such as `getAllGroups`.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 97 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
3 changes: 2 additions & 1 deletion osquery/tables/applications/chrome/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const std::unordered_map<ChromeBrowserType, std::string>
{ChromeBrowserType::Yandex, "yandex"},
{ChromeBrowserType::Opera, "opera"},
{ChromeBrowserType::Edge, "edge"},
{ChromeBrowserType::Edge, "edge_beta"},
{ChromeBrowserType::EdgeBeta, "edge_beta"},
{ChromeBrowserType::Vivaldi, "vivaldi"},
{ChromeBrowserType::Arc, "arc"},
};
Comment on lines 104 to 110

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Duplicate map entry silently makes ChromeBrowserType::Edge alias to 'edge_beta' unreachable

In the kChromeBrowserTypeToString map definition (anonymous namespace, near line 138), replaced the duplicate {ChromeBrowserType::Edge, "edge_beta"} entry with {ChromeBrowserType::EdgeBeta, "edge_beta"}, exactly as suggested. This resolves the duplicate-key collision so ChromeBrowserType::Edge maps only to "edge" and ChromeBrowserType::EdgeBeta now correctly maps to "edge_beta", matching the existing EdgeBeta enumerator already used elsewhere in the file (e.g., kWindowsPathList, kMacOsPathList). No other lines were changed.

πŸ€– Prompt for AI agents
In osquery/tables/applications/chrome/utils.cpp around line 138, review and complete this code-review fix: Duplicate map entry silently makes ChromeBrowserType::Edge alias to 'edge_beta' unreachable.
What the draft fix changed: In the `kChromeBrowserTypeToString` map definition (anonymous namespace, near line 138), replaced the duplicate `{ChromeBrowserType::Edge, "edge_beta"}` entry with `{ChromeBrowserType::EdgeBeta, "edge_beta"}`, exactly as suggested. This resolves the duplicate-key collision so `ChromeBrowserType::Edge` maps only to `"edge"` and `ChromeBrowserType::EdgeBeta` now correctly maps to `"edge_beta"`, matching the existing `EdgeBeta` enumerator already used elsewhere in the file (e.g., `kWindowsPathList`, `kMacOsPathList`). No other lines were changed.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 98 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -1264,3 +1264,4 @@ ExpectedExtensionKey computeExtensionIdentifier(
} // namespace tables

} // namespace osquery

2 changes: 1 addition & 1 deletion osquery/tables/events/darwin/openbsm_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ Status OpenBSMProcEvSubscriber::handleExec(const OpenBSMEventContextRef& ec) {
r["egid"] = INTEGER(tok.tt.subj64.egid);
r["uid"] = INTEGER(tok.tt.subj64.ruid);
r["gid"] = INTEGER(tok.tt.subj64.rgid);
pid = tok.tt.subj32.pid;
pid = tok.tt.subj64.pid;
break;
case AUT_SUBJECT32_EX:
OpenBSM_AUT_SUBJECT32_EX(r, tok);
Comment on lines 151 to 157

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 AUT_SUBJECT64 case copies pid from the 32-bit subject union member (copy-paste bug)

In OpenBSMProcEvSubscriber::handleExec, the AUT_SUBJECT64 case now sets pid = tok.tt.subj64.pid; instead of the incorrect tok.tt.subj32.pid;, fixing the copy-paste bug so the pid used for the later ppid_map lookup correctly reflects the 64-bit subject token being processed.

πŸ€– Prompt for AI agents
In osquery/tables/events/darwin/openbsm_events.cpp around line 168, review and complete this code-review fix: AUT_SUBJECT64 case copies pid from the 32-bit subject union member (copy-paste bug).
What the draft fix changed: In `OpenBSMProcEvSubscriber::handleExec`, the `AUT_SUBJECT64` case now sets `pid = tok.tt.subj64.pid;` instead of the incorrect `tok.tt.subj32.pid;`, fixing the copy-paste bug so the `pid` used for the later `ppid_map` lookup correctly reflects the 64-bit subject token being processed.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
7 changes: 4 additions & 3 deletions osquery/tables/events/darwin/socket_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ Status OpenBSMNetEvSubscriber::Callback(
r["action"] = "connect";
} else if (tok.tt.hdr32_ex.e_type == AUE_BIND) {
r["action"] = "bind";
} else if (tok.tt.hdr32.e_type == AUE_ACCEPT) {
} else if (tok.tt.hdr32_ex.e_type == AUE_ACCEPT) {
r["action"] = "accept";

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Typo bug in AUT_HEADER32_EX branch: AUE_ACCEPT check reads from wrong header token (hdr32 instead of hdr32_ex)

In OpenBSMNetEvSubscriber::Callback, AUT_HEADER32_EX case: changed the AUE_ACCEPT comparison from tok.tt.hdr32.e_type to tok.tt.hdr32_ex.e_type, matching the other two comparisons in the same branch.

πŸ€– Prompt for AI agents
In osquery/tables/events/darwin/socket_events.cpp around line 109, review and complete this code-review fix: Typo bug in AUT_HEADER32_EX branch: AUE_ACCEPT check reads from wrong header token (hdr32 instead of hdr32_ex).
What the draft fix changed: In `OpenBSMNetEvSubscriber::Callback`, `AUT_HEADER32_EX` case: changed the AUE_ACCEPT comparison from `tok.tt.hdr32.e_type` to `tok.tt.hdr32_ex.e_type`, matching the other two comparisons in the same branch.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 90 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

} else {
continue;
Expand All @@ -118,7 +118,7 @@ Status OpenBSMNetEvSubscriber::Callback(
r["action"] = "connect";
} else if (tok.tt.hdr64_ex.e_type == AUE_BIND) {
r["action"] = "bind";

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Same header-union typo repeated in AUT_HEADER64/HEADER64_EX branch

In OpenBSMNetEvSubscriber::Callback, combined AUT_HEADER64/AUT_HEADER64_EX case: changed the AUE_ACCEPT comparison from tok.tt.hdr64.e_type to tok.tt.hdr64_ex.e_type, matching the other two comparisons in the same branch.

πŸ€– Prompt for AI agents
In osquery/tables/events/darwin/socket_events.cpp around line 120, review and complete this code-review fix: Same header-union typo repeated in AUT_HEADER64/HEADER64_EX branch.
What the draft fix changed: In `OpenBSMNetEvSubscriber::Callback`, combined `AUT_HEADER64`/`AUT_HEADER64_EX` case: changed the AUE_ACCEPT comparison from `tok.tt.hdr64.e_type` to `tok.tt.hdr64_ex.e_type`, matching the other two comparisons in the same branch.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 90 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

} else if (tok.tt.hdr64.e_type == AUE_ACCEPT) {
} else if (tok.tt.hdr64_ex.e_type == AUE_ACCEPT) {
r["action"] = "accept";
} else {
continue;
Expand Down Expand Up @@ -146,7 +146,7 @@ Status OpenBSMNetEvSubscriber::Callback(
case AUT_SUBJECT64:
r["auid"] = INTEGER(tok.tt.subj64.auid);
r["pid"] = INTEGER(tok.tt.subj64.pid);
pid = tok.tt.subj32.pid;
pid = tok.tt.subj64.pid;
break;
case AUT_SUBJECT32_EX:
r["auid"] = INTEGER(tok.tt.subj32_ex.auid);
Comment on lines 146 to 152

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΄ Wrong subject token copied into pid for AUT_SUBJECT64 in socket_events.cpp

In OpenBSMNetEvSubscriber::Callback, AUT_SUBJECT64 case: changed pid = tok.tt.subj32.pid; to pid = tok.tt.subj64.pid;, matching the correct 64-bit union member consistent with the preceding r["pid"] assignment on the same case.

πŸ€– Prompt for AI agents
In osquery/tables/events/darwin/socket_events.cpp around line 163, review and complete this code-review fix: Wrong subject token copied into pid for AUT_SUBJECT64 in socket_events.cpp.
What the draft fix changed: In `OpenBSMNetEvSubscriber::Callback`, `AUT_SUBJECT64` case: changed `pid = tok.tt.subj32.pid;` to `pid = tok.tt.subj64.pid;`, matching the correct 64-bit union member consistent with the preceding `r["pid"]` assignment on the same case.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -234,3 +234,4 @@ Status OpenBSMNetEvSubscriber::Callback(
}

} // namespace osquery

3 changes: 2 additions & 1 deletion osquery/tables/networking/curl_certificate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ Status getTLSCertificate(const std::string& hostname,
std::string port = "443";
auto connect_hostname = hostname;
auto delim = hostname.find(":");
if (delim + 1 == hostname.length()) {
if (delim != std::string::npos && delim + 1 == hostname.length()) {
// if no port specified use default port
connect_hostname = hostname.substr(0, delim);
} else if (delim != std::string::npos) {
Comment on lines 302 to 308

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΄ Off-by-one/logic bug: hostname port-delimiter check uses unsigned wraparound when ':' is not found

In getTLSCertificate, changed if (delim + 1 == hostname.length()) to if (delim != std::string::npos && delim + 1 == hostname.length()), explicitly guarding against the std::string::npos unsigned-wraparound case rather than relying on implicit overflow behavior, matching the suggested fix exactly.

πŸ€– Prompt for AI agents
In osquery/tables/networking/curl_certificate.cpp around line 285, review and complete this code-review fix: Off-by-one/logic bug: hostname port-delimiter check uses unsigned wraparound when ':' is not found.
What the draft fix changed: In `getTLSCertificate`, changed `if (delim + 1 == hostname.length())` to `if (delim != std::string::npos && delim + 1 == hostname.length())`, explicitly guarding against the `std::string::npos` unsigned-wraparound case rather than relying on implicit overflow behavior, matching the suggested fix exactly.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 98 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -459,3 +459,4 @@ QueryData genTLSCertificate(QueryContext& context) {
}
} // namespace tables
} // namespace osquery

3 changes: 2 additions & 1 deletion osquery/tables/networking/darwin/routes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Status genArp(const struct rt_msghdr *route,
// The cache will always know the address.
r["address"] = ipAsString(addr_map[RTAX_DST]);

auto sdl = (struct sockaddr_dl *)addr_map[RTA_DST];
auto sdl = (struct sockaddr_dl *)addr_map[RTAX_DST];
if (sdl->sdl_alen > 0) {
r["mac"] = macAsString(LLADDR(sdl));
} else {
Comment on lines 119 to 125

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 genArp indexes addr_map with RTA_DST (a bitmask flag) instead of RTAX_DST (an array index)

In genArp (osquery/tables/networking/darwin/routes.cpp), changed auto sdl = (struct sockaddr_dl *)addr_map[RTA_DST]; to auto sdl = (struct sockaddr_dl *)addr_map[RTAX_DST];, replacing the bitmask constant RTA_DST with the correct array index constant RTAX_DST, consistent with all other addr_map accesses in the file.

πŸ€– Prompt for AI agents
In osquery/tables/networking/darwin/routes.cpp around line 111, review and complete this code-review fix: genArp indexes addr_map with RTA_DST (a bitmask flag) instead of RTAX_DST (an array index).
What the draft fix changed: In genArp (osquery/tables/networking/darwin/routes.cpp), changed `auto sdl = (struct sockaddr_dl *)addr_map[RTA_DST];` to `auto sdl = (struct sockaddr_dl *)addr_map[RTAX_DST];`, replacing the bitmask constant RTA_DST with the correct array index constant RTAX_DST, consistent with all other addr_map accesses in the file.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -220,3 +220,4 @@ QueryData genRoutes(QueryContext &context) {
}
}
}

Loading