Repository navigation
fix(adhoc-sweep-fixes): CU-86akhf8u2 34 review findings across 27 files #72
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
base: master
Are you sure you want to change the base?
Changes from all commits
b81c15d
8aefea3
f743f72
4a9b65a
e40b469
2636aab
1d209a7
e113b47
6488f4c
f27107d
ce6447e
538858a
09368a7
2259007
efb4a72
ab05f15
48c03d8
0038580
4bffece
491bbe5
2bd650a
6614671
044cbf0
a156b17
60a0bf4
fc85204
4fa4694
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -238,7 +238,7 @@ Status WmiResultItem::GetUnsignedLong(const std::string& name, | |
| VariantClear(&value); | ||
| return Status::failure("Invalid data type returned."); | ||
| } | ||
| ret = value.lVal; | ||
| ret = value.ulVal; | ||
| VariantClear(&value); | ||
| return Status::success(); | ||
| } | ||
|
Comment on lines
238
to
244
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π GetUnsignedLong reads value.lVal instead of the unsigned value.ulVal member In WmiResultItem::GetUnsignedLong, changed π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer
Comment on lines
238
to
244
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π GetLongLong and GetUnsignedLongLong read the wrong VARIANT union member (lVal instead of the 64-bit fields) In WmiResultItem::GetLongLong and WmiResultItem::GetUnsignedLongLong, changed π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer
Comment on lines
238
to
244
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π GetUnsignedLong reads value.lVal instead of the unsigned value.ulVal member In WmiResultItem::GetUnsignedLong, changed π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer |
||
|
|
@@ -255,7 +255,7 @@ Status WmiResultItem::GetLongLong(const std::string& name, | |
| VariantClear(&value); | ||
| return Status::failure("Invalid data type returned."); | ||
| } | ||
| ret = value.lVal; | ||
| ret = value.llVal; | ||
| VariantClear(&value); | ||
| return Status::success(); | ||
| } | ||
|
|
@@ -272,7 +272,7 @@ Status WmiResultItem::GetUnsignedLongLong(const std::string& name, | |
| VariantClear(&value); | ||
| return Status::failure("Invalid data type returned."); | ||
| } | ||
| ret = value.lVal; | ||
| ret = value.ullVal; | ||
| VariantClear(&value); | ||
| return Status::success(); | ||
| } | ||
|
|
@@ -598,3 +598,4 @@ Status WmiRequest::ExecMethod(const WmiResultItem& object, | |
| } | ||
|
|
||
| } // namespace osquery | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,9 +48,14 @@ void SCNetworkEventPublisher::addTarget( | |
| const SCNetworkReachabilityRef& target) { | ||
| targets_.push_back(target); | ||
|
|
||
| // Keep a stable, heap-allocated copy of the subscription context pointer | ||
| // alive for the lifetime of the callback registration. | ||
| auto sc_holder = new SCNetworkSubscriptionContextRef(sc); | ||
| subscription_refs_.push_back(sc_holder); | ||
|
|
||
| // Assign a context (the subscription context) to the target. | ||
| SCNetworkReachabilityContext* context = new SCNetworkReachabilityContext(); | ||
| context->info = (void*)≻ | ||
| context->info = (void*)sc_holder; | ||
| context->retain = nullptr; | ||
| context->release = nullptr; | ||
| contexts_.push_back(context); | ||
|
Comment on lines
48
to
61
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΄ scnetwork.cpp Callback stores a pointer to a local stack variable (dangling reference) via SCNetworkReachabilityContext In π€ Prompt for AI agentsfix confidence: π΄ 55 low β review closely β react π/π to teach the reviewer
Comment on lines
48
to
61
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΄ scnetwork.cpp Callback stores a pointer to a local stack variable (dangling reference) via SCNetworkReachabilityContext In π€ Prompt for AI agentsfix confidence: π΄ 55 low β review closely β react π/π to teach the reviewer |
||
|
|
@@ -98,6 +103,11 @@ void SCNetworkEventPublisher::clearAll() { | |
| } | ||
| contexts_.clear(); | ||
|
|
||
| for (auto& sc_holder : subscription_refs_) { | ||
| delete sc_holder; | ||
| } | ||
| subscription_refs_.clear(); | ||
|
|
||
| target_names_.clear(); | ||
| target_addresses_.clear(); | ||
| } | ||
|
|
@@ -183,3 +193,4 @@ Status SCNetworkEventPublisher::run() { | |
| return Status::success(); | ||
| } | ||
| }; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -69,6 +69,8 @@ Status INotifyEventPublisher::setUp() { | |
| WriteLock lock(scratch_mutex_); | ||
| scratch_ = (char*)malloc(kINotifyBufferSize); | ||
| if (scratch_ == nullptr) { | ||
| ::close(inotify_handle_); | ||
| inotify_handle_ = -1; | ||
| return Status(1, "Could not allocate scratch space"); | ||
| } | ||
| return Status::success(); | ||
|
Comment on lines
69
to
76
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π INotifyEventPublisher::setUp leaks inotify_handle_ on scratch allocation failure In π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer
Comment on lines
69
to
76
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π INotifyEventPublisher::setUp leaks inotify_handle_ on scratch allocation failure In π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer |
||
|
|
@@ -486,3 +488,4 @@ bool INotifyEventPublisher::isPathMonitored(const std::string& path) const { | |
| return (path_iterator != path_descriptors_.end()); | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,7 +22,7 @@ Status EtwProviderConfig::isValid() const { | |
| return Status::failure("Empty list of Events to handle"); | ||
| } | ||
|
|
||
| if (getPostProcessor() == nullptr) { | ||
| if (getPreProcessor() == nullptr) { | ||
| return Status::failure("Type handlers were not provided"); | ||
| } | ||
|
|
||
|
Comment on lines
22
to
28
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π EtwProviderConfig::isValid() checks getPostProcessor() twice, never validating providerPreProcess_ In EtwProviderConfig::isValid() (etw_provider_config.cpp), replaced the first duplicate π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer
Comment on lines
22
to
28
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π EtwProviderConfig::isValid() checks getPostProcessor() twice, never validating providerPreProcess_ In EtwProviderConfig::isValid() (etw_provider_config.cpp), replaced the first duplicate π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer |
||
|
|
@@ -166,4 +166,4 @@ void EtwProviderConfig::addEventTypeToHandle(const EtwEventType& value) { | |
| eventTypes_.push_back(value); | ||
| } | ||
|
|
||
| } // namespace osquery | ||
| } // namespace osquery | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,17 @@ Status procGetNamespaceInode(ino_t& inode, | |
| return Status(1, "Failed to retrieve the inode for namespace " + path); | ||
| } | ||
|
|
||
| // Ensure the buffer is null-terminated, since readlink() does not do this | ||
| // for us | ||
| link_destination[link_dest_length] = '\0'; | ||
|
|
||
| // The link destination must be at least long enough to hold the | ||
| // namespace name, the ":[" separator and a closing "]" | ||
| if (static_cast<std::size_t>(link_dest_length) < | ||
| namespace_name.size() + 3) { | ||
| return Status(1, "Invalid descriptor for namespace " + path); | ||
| } | ||
|
|
||
| // The link destination must be in the following form: namespace:[inode] | ||
| if (std::strncmp(link_destination, | ||
| namespace_name.data(), | ||
|
Comment on lines
37
to
53
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΄ readlink result in procGetNamespaceInode is not null-terminated before strncmp use In procGetNamespaceInode (osquery/filesystem/linux/proc.cpp), after the readlink() call the buffer is now explicitly null-terminated via π€ Prompt for AI agentsfix confidence: π’ 92 high β react π/π to teach the reviewer
Comment on lines
37
to
53
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΄ readlink result in procGetNamespaceInode is not null-terminated before strncmp use In procGetNamespaceInode (osquery/filesystem/linux/proc.cpp), after the readlink() call the buffer is now explicitly null-terminated via π€ Prompt for AI agentsfix confidence: π’ 92 high β react π/π to teach the reviewer |
||
|
|
@@ -430,3 +441,4 @@ Expected<std::uint64_t, ProcError> getProcRSS(const std::string& process) { | |
| } | ||
|
|
||
| } // namespace osquery | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,8 @@ | |
|
|
||
| #include <zlib.h> | ||
|
|
||
| #include <osquery/logger/logger.h> | ||
|
|
||
| namespace osquery { | ||
|
|
||
| #define MOD_GZIP_ZLIB_WINDOWSIZE 15 | ||
|
|
@@ -27,6 +29,8 @@ std::string compressString(const std::string& data) { | |
| MOD_GZIP_ZLIB_WINDOWSIZE + 16, | ||
| MOD_GZIP_ZLIB_CFACTOR, | ||
| Z_DEFAULT_STRATEGY) != Z_OK) { | ||
| LOG(ERROR) << "compressString: deflateInit2 failed to initialize zlib " | ||
| "stream"; | ||
| return std::string(); | ||
| } | ||
|
|
||
|
Comment on lines
29
to
36
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π compressString silently returns empty string on zlib failure without logging In compressString() (osquery/remote/requests.cpp), added π€ Prompt for AI agentsfix confidence: π‘ 80 medium β react π/π to teach the reviewer
Comment on lines
29
to
36
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π compressString silently returns empty string on zlib failure without logging In compressString() (osquery/remote/requests.cpp), added π€ Prompt for AI agentsfix confidence: π‘ 80 medium β react π/π to teach the reviewer |
||
|
|
@@ -51,9 +55,13 @@ std::string compressString(const std::string& data) { | |
|
|
||
| deflateEnd(&zs); | ||
| if (ret != Z_STREAM_END) { | ||
| LOG(ERROR) << "compressString: deflate stream did not end cleanly, " | ||
| "zlib return code: " | ||
| << ret; | ||
| return std::string(); | ||
| } | ||
|
|
||
| return output; | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,7 +40,10 @@ Uri::Uri(const std::string& str) : hasAuthority_(false), port_(0) { | |
|
|
||
| std::smatch match; | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΄ Uri constructor throws on user/attacker-controlled input instead of returning an error status In π€ Prompt for AI agentsfix confidence: π΄ 45 low β review closely β react π/π to teach the reviewer
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΄ Uri constructor throws on user/attacker-controlled input instead of returning an error status In π€ Prompt for AI agentsfix confidence: π΄ 45 low β review closely β react π/π to teach the reviewer |
||
| if (!std::regex_match(str, match, uriRegex)) { | ||
| throw std::invalid_argument("Invalid URL"); | ||
| // Malformed URI (potentially attacker-controlled input); leave this | ||
| // Uri in a safe, empty default state instead of throwing so that a | ||
| // single bad remote-supplied URI cannot crash the process. | ||
| return; | ||
| } | ||
|
|
||
| scheme_ = submatch(match, 1); | ||
|
|
@@ -66,7 +69,18 @@ Uri::Uri(const std::string& str) : hasAuthority_(false), port_(0) { | |
| authority.second, | ||
| authorityMatch, | ||
| authorityRegex)) { | ||
| throw std::invalid_argument("Invalid URI authority"); | ||
| // Malformed authority section (potentially attacker-controlled | ||
| // input); reset to a safe, empty default state instead of throwing. | ||
| scheme_.clear(); | ||
| hasAuthority_ = false; | ||
| username_.clear(); | ||
| password_.clear(); | ||
| host_.clear(); | ||
| path_.clear(); | ||
| port_ = 0; | ||
| query_.clear(); | ||
| fragment_.clear(); | ||
| return; | ||
| } | ||
|
|
||
| std::string port(authorityMatch[4].first, authorityMatch[4].second); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -141,10 +141,18 @@ Status SQLPlugin::call(const PluginRequest& request, PluginResponse& response) { | |
| return Status(1, "SQL plugin must include a request action"); | ||
| } | ||
|
|
||
| if (request.at("action") == "query") { | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π SQLPlugin::call uses request.at("action") repeatedly without checking key existence for sub-keys like "query"/"table", risking std::out_of_range exception In SQLPlugin::call (osquery/sql/sql.cpp), added request.count("query") == 0 / request.count("table") == 0 checks (returning Status::failure via Status(1, ...)) before each request.at("query")/request.at("table") call in the "query", "columns", "attach", "detach", and "tables" branches, and cached request.at("action") into a local reference to avoid repeated lookups. This prevents std::out_of_range from propagating out of the Status-returning API when required sub-keys are missing, per OSQUERY-002-2/OSQUERY-003. π€ Prompt for AI agentsfix confidence: π’ 92 high β react π/π to teach the reviewer
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π SQLPlugin::call uses request.at("action") repeatedly without checking key existence for sub-keys like "query"/"table", risking std::out_of_range exception In SQLPlugin::call (osquery/sql/sql.cpp), added request.count("query") == 0 / request.count("table") == 0 checks (returning Status::failure via Status(1, ...)) before each request.at("query")/request.at("table") call in the "query", "columns", "attach", "detach", and "tables" branches, and cached request.at("action") into a local reference to avoid repeated lookups. This prevents std::out_of_range from propagating out of the Status-returning API when required sub-keys are missing, per OSQUERY-002-2/OSQUERY-003. π€ Prompt for AI agentsfix confidence: π’ 92 high β react π/π to teach the reviewer |
||
| const auto& action = request.at("action"); | ||
|
|
||
| if (action == "query") { | ||
| if (request.count("query") == 0) { | ||
| return Status(1, "SQL plugin query action requires a query"); | ||
| } | ||
| bool use_cache = (request.count("cache") && request.at("cache") == "1"); | ||
| return this->query(request.at("query"), response, use_cache); | ||
| } else if (request.at("action") == "columns") { | ||
| } else if (action == "columns") { | ||
| if (request.count("query") == 0) { | ||
| return Status(1, "SQL plugin columns action requires a query"); | ||
| } | ||
| TableColumns columns; | ||
| auto status = this->getQueryColumns(request.at("query"), columns); | ||
| // Convert columns to response | ||
|
|
@@ -155,12 +163,21 @@ Status SQLPlugin::call(const PluginRequest& request, PluginResponse& response) { | |
| {"o", INTEGER(static_cast<size_t>(std::get<2>(column)))}}); | ||
| } | ||
| return status; | ||
| } else if (request.at("action") == "attach") { | ||
| } else if (action == "attach") { | ||
| if (request.count("table") == 0) { | ||
| return Status(1, "SQL plugin attach action requires a table"); | ||
| } | ||
| // Attach a virtual table name using an optional included definition. | ||
| return this->attach(request.at("table")); | ||
| } else if (request.at("action") == "detach") { | ||
| } else if (action == "detach") { | ||
| if (request.count("table") == 0) { | ||
| return Status(1, "SQL plugin detach action requires a table"); | ||
| } | ||
| return this->detach(request.at("table")); | ||
| } else if (request.at("action") == "tables") { | ||
| } else if (action == "tables") { | ||
| if (request.count("query") == 0) { | ||
| return Status(1, "SQL plugin tables action requires a query"); | ||
| } | ||
| std::vector<std::string> tables; | ||
| auto status = this->getQueryTables(request.at("query"), tables); | ||
| if (status.ok()) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -178,8 +178,13 @@ static void getParentDirectory(sqlite3_context* context, | |
| sqlite3_result_null(context); | ||
| return; | ||
| } | ||
| char* result = reinterpret_cast<char*>(malloc(last_slash_pos)); | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΄ getParentDirectory leaks/mismatches allocator: malloc() paired with SQLite's free destructor is fine, but result buffer is not null-terminated In π€ Prompt for AI agentsfix confidence: π’ 90 high β react π/π to teach the reviewer
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΄ getParentDirectory leaks/mismatches allocator: malloc() paired with SQLite's free destructor is fine, but result buffer is not null-terminated In π€ Prompt for AI agentsfix confidence: π’ 90 high β react π/π to teach the reviewer |
||
| char* result = reinterpret_cast<char*>(malloc(last_slash_pos + 1)); | ||
| if (result == nullptr) { | ||
| sqlite3_result_error_nomem(context); | ||
| return; | ||
| } | ||
| memcpy(result, path, last_slash_pos); | ||
| result[last_slash_pos] = '\0'; | ||
| sqlite3_result_text(context, result, last_slash_pos, free); | ||
| } | ||
|
|
||
|
|
@@ -210,3 +215,4 @@ void registerFilesystemExtensions(sqlite3* db) { | |
| nullptr); | ||
| } | ||
| } // namespace osquery | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,9 @@ | |
| #include <string> | ||
| #include <vector> | ||
|
|
||
| #include <boost/algorithm/string/classification.hpp> | ||
| #include <boost/algorithm/string/split.hpp> | ||
|
|
||
| #include <osquery/core/flags.h> | ||
| #include <osquery/core/tables.h> | ||
| #include <osquery/events/linux/udev.h> | ||
|
|
@@ -55,7 +58,17 @@ Status HardwareEventSubscriber::Callback(const ECRef& ec, const SCRef& sc) { | |
|
|
||
| struct udev_device* device = ec->device; | ||
| r["type"] = ec->devtype; | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π find() on std::string used as a substring/exact-match filter is misapplied for hardware_disabled_types In HardwareEventSubscriber::Callback, replaced the substring check π€ Prompt for AI agentsfix confidence: π‘ 60 medium β react π/π to teach the reviewer
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π find() on std::string used as a substring/exact-match filter is misapplied for hardware_disabled_types In HardwareEventSubscriber::Callback, replaced the substring check π€ Prompt for AI agentsfix confidence: π‘ 60 medium β react π/π to teach the reviewer |
||
| if (FLAGS_hardware_disabled_types.find(r.at("type")) != std::string::npos) { | ||
|
|
||
| std::vector<std::string> disabled_types; | ||
| boost::split(disabled_types, | ||
| FLAGS_hardware_disabled_types, | ||
| boost::is_any_of(",")); | ||
| for (auto& disabled_type : disabled_types) { | ||
| boost::trim(disabled_type); | ||
| } | ||
| if (std::find(disabled_types.begin(), | ||
| disabled_types.end(), | ||
| r.at("type")) != disabled_types.end()) { | ||
| return Status::success(); | ||
| } | ||
|
|
||
|
|
@@ -74,9 +87,8 @@ Status HardwareEventSubscriber::Callback(const ECRef& ec, const SCRef& sc) { | |
| r["vendor"] = UdevEventPublisher::getValue(device, "ID_VENDOR_FROM_DATABASE"); | ||
| r["vendor_id"] = | ||
| INTEGER(UdevEventPublisher::getValue(device, "ID_VENDOR_ID")); | ||
| r["serial"] = | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π INTEGER() applied to non-numeric udev serial/vendor string fields will silently mis-render values In HardwareEventSubscriber::Callback, removed INTEGER() wrapping around r["serial"] and r["revision"], assigning the raw string values from UdevEventPublisher::getValue(device, "ID_SERIAL_SHORT") and "ID_REVISION" directly, so alphanumeric/hex serial and revision strings are preserved instead of being silently truncated/zeroed by numeric conversion. vendor_id/model_id were left as INTEGER() since the finding only cited serial/vendor_id/revision text but vendor_id/model_id are genuinely numeric IDs in udev and not flagged as broken; only serial and revision (explicitly named as the problematic alphanumeric fields) were changed. π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π INTEGER() applied to non-numeric udev serial/vendor string fields will silently mis-render values In HardwareEventSubscriber::Callback, removed INTEGER() wrapping around r["serial"] and r["revision"], assigning the raw string values from UdevEventPublisher::getValue(device, "ID_SERIAL_SHORT") and "ID_REVISION" directly, so alphanumeric/hex serial and revision strings are preserved instead of being silently truncated/zeroed by numeric conversion. vendor_id/model_id were left as INTEGER() since the finding only cited serial/vendor_id/revision text but vendor_id/model_id are genuinely numeric IDs in udev and not flagged as broken; only serial and revision (explicitly named as the problematic alphanumeric fields) were changed. π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer |
||
| INTEGER(UdevEventPublisher::getValue(device, "ID_SERIAL_SHORT")); | ||
| r["revision"] = INTEGER(UdevEventPublisher::getValue(device, "ID_REVISION")); | ||
| r["serial"] = UdevEventPublisher::getValue(device, "ID_SERIAL_SHORT"); | ||
| r["revision"] = UdevEventPublisher::getValue(device, "ID_REVISION"); | ||
| add(r); | ||
| return Status(0); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,17 +49,17 @@ TEST_F(ETWProcessEventsTests, test_subscriber_exists) { | |
| ASSERT_TRUE(Registry::get().exists("event_subscriber", ETW_SUBSCRIBER_NAME)); | ||
|
|
||
| auto plugin = Registry::get().plugin("event_subscriber", ETW_SUBSCRIBER_NAME); | ||
| auto* subscriber = | ||
| reinterpret_cast<std::shared_ptr<EtwProcessEventSubscriber>*>(&plugin); | ||
| auto subscriber = | ||
| std::dynamic_pointer_cast<EtwProcessEventSubscriber>(plugin); | ||
| EXPECT_NE(subscriber, nullptr); | ||
| } | ||
|
|
||
| TEST_F(ETWProcessEventsTests, test_publisher_exists) { | ||
| ASSERT_TRUE(Registry::get().exists("event_publisher", ETW_PUBLISHER_NAME)); | ||
|
|
||
| auto plugin = Registry::get().plugin("event_publisher", ETW_PUBLISHER_NAME); | ||
| auto* publisher = | ||
| reinterpret_cast<std::shared_ptr<EtwPublisherProcesses>*>(&plugin); | ||
| auto publisher = | ||
| std::dynamic_pointer_cast<EtwPublisherProcesses>(plugin); | ||
| EXPECT_NE(publisher, nullptr); | ||
| } | ||
|
|
||
|
Comment on lines
49
to
65
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π Dead/unreachable code: reinterpret_cast of local shared_ptr always yields a non-null pointer, EXPECT_NE(subscriber, nullptr) never fails In π€ Prompt for AI agentsfix confidence: π‘ 80 medium β react π/π to teach the reviewer
Comment on lines
49
to
65
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π Dead/unreachable code: reinterpret_cast of local shared_ptr always yields a non-null pointer, EXPECT_NE(subscriber, nullptr) never fails In π€ Prompt for AI agentsfix confidence: π‘ 80 medium β react π/π to teach the reviewer |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -76,7 +76,7 @@ Status EtwProcessEventSubscriber::eventCallback( | |
| newRow["token_elevation_status"] = INTEGER(eventPayload->TokenIsElevated); | ||
| newRow["mandatory_label"] = SQL_TEXT(eventPayload->MandatoryLabelSid); | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π process_sequence_number field is populated with ParentProcessSequenceNumber instead of the process's own sequence number In EtwProcessEventSubscriber::eventCallback, ProcessStart branch, changed π€ Prompt for AI agentsfix confidence: π‘ 65 medium β react π/π to teach the reviewer
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π process_sequence_number field is populated with ParentProcessSequenceNumber instead of the process's own sequence number In EtwProcessEventSubscriber::eventCallback, ProcessStart branch, changed π€ Prompt for AI agentsfix confidence: π‘ 65 medium β react π/π to teach the reviewer |
||
| newRow["process_sequence_number"] = | ||
| BIGINT(eventPayload->ParentProcessSequenceNumber); | ||
| BIGINT(eventPayload->ProcessSequenceNumber); | ||
| newRow["parent_process_sequence_number"] = | ||
| BIGINT(eventPayload->ParentProcessSequenceNumber); | ||
|
|
||
|
|
@@ -118,3 +118,4 @@ Status EtwProcessEventSubscriber::eventCallback( | |
| } | ||
|
|
||
| } // namespace osquery | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| * SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only) | ||
| */ | ||
|
|
||
| #include <cstdlib> | ||
| #include <fstream> | ||
|
|
||
| #include <boost/algorithm/string/split.hpp> | ||
|
|
@@ -21,6 +22,10 @@ namespace tables { | |
|
|
||
| const std::string kLinuxArpTable = "/proc/net/arp"; | ||
|
|
||
| // ARP flag bits as defined by the kernel (see <linux/if_arp.h>). | ||
| static const unsigned long kAtfCom = 0x02; | ||
| static const unsigned long kAtfPerm = 0x04; | ||
|
|
||
| QueryData genArpCache(QueryContext& context) { | ||
| QueryData results; | ||
|
|
||
|
|
@@ -62,8 +67,8 @@ QueryData genArpCache(QueryContext& context) { | |
| r["interface"] = fields[5]; | ||
|
|
||
| // Note: it's also possible to detect publish entries (ATF_PUB). | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΅ hardcoded literal used for ATF_COM|ATF_PERM flag comparison instead of named constant In genArpCache() in osquery/tables/networking/linux/arp_cache.cpp, replaced the magic-string comparison π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΅ hardcoded literal used for ATF_COM|ATF_PERM flag comparison instead of named constant In genArpCache() in osquery/tables/networking/linux/arp_cache.cpp, replaced the magic-string comparison π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer |
||
| if (fields[2] == "0x6") { | ||
| // The string representation of ATF_COM | ATF_PERM. | ||
| unsigned long flags = strtoul(fields[2].c_str(), nullptr, 16); | ||
| if ((flags & (kAtfCom | kAtfPerm)) == (kAtfCom | kAtfPerm)) { | ||
| r["permanent"] = "1"; | ||
| } else { | ||
| r["permanent"] = "0"; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -368,6 +368,9 @@ bool parseProcCmdline(std::string& args, size_t len) { | |
| start = 0; | ||
| while (nargs-- && nul != std::string::npos) { | ||
| nul = args.find('\0', start); | ||
| if (nul == std::string::npos) { | ||
| break; | ||
| } | ||
| args[nul] = ' '; | ||
| start = nul + 1; | ||
| } | ||
|
Comment on lines
368
to
376
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π parseProcCmdline uses args[nul] after find may return npos on the last iteration In π€ Prompt for AI agentsfix confidence: π’ 92 high β react π/π to teach the reviewer
Comment on lines
368
to
376
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π parseProcCmdline uses args[nul] after find may return npos on the last iteration In π€ Prompt for AI agentsfix confidence: π’ 92 high β react π/π to teach the reviewer |
||
|
|
@@ -808,3 +811,4 @@ QueryData genProcessMemoryMap(QueryContext& context) { | |
| } | ||
| } // namespace tables | ||
| } // namespace osquery | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -120,10 +120,10 @@ int getPrinterSharingStatus() { | |
| int ret = cupsAdminGetServerSettings(cups, &num_settings, &settings); | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π getPrinterSharingStatus leaks cups_option_t settings array when cupsAdminGetServerSettings fails In getPrinterSharingStatus (sharing_preferences.cpp), moved the cupsFreeOptions(num_settings, settings) call out of the success-only branch of the π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π getPrinterSharingStatus leaks cups_option_t settings array when cupsAdminGetServerSettings fails In getPrinterSharingStatus (sharing_preferences.cpp), moved the cupsFreeOptions(num_settings, settings) call out of the success-only branch of the π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer |
||
| if (ret != 0) { | ||
| value = cupsGetOption("_share_printers", num_settings, settings); | ||
| cupsFreeOptions(num_settings, settings); | ||
| } else { | ||
| VLOG(1) << "Unable to get CUPS server settings: " << cupsLastErrorString(); | ||
| } | ||
| cupsFreeOptions(num_settings, settings); | ||
| httpClose(cups); | ||
|
|
||
| if (value != nullptr) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,9 +28,12 @@ void genUSBDevice(const io_service_t& device, QueryData& results) { | |
| Row r; | ||
|
|
||
| // Get the device details | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π genUSBDevice does not check the return value of IORegistryEntryCreateCFProperties In genUSBDevice (osquery/tables/system/darwin/usb_devices.cpp), initialized π€ Prompt for AI agentsfix confidence: π’ 92 high β react π/π to teach the reviewer
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π genUSBDevice does not check the return value of IORegistryEntryCreateCFProperties In genUSBDevice (osquery/tables/system/darwin/usb_devices.cpp), initialized π€ Prompt for AI agentsfix confidence: π’ 92 high β react π/π to teach the reviewer |
||
| CFMutableDictionaryRef details; | ||
| IORegistryEntryCreateCFProperties( | ||
| CFMutableDictionaryRef details = nullptr; | ||
| auto ret = IORegistryEntryCreateCFProperties( | ||
| device, &details, kCFAllocatorDefault, kNilOptions); | ||
| if (ret != KERN_SUCCESS || details == nullptr) { | ||
| return; | ||
| } | ||
|
|
||
| r["usb_address"] = getIOKitProperty(details, "USB Address"); | ||
| r["usb_port"] = getIOKitProperty(details, "PortNum"); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
𦩠π GetLongLong and GetUnsignedLongLong read the wrong VARIANT union member (lVal instead of the 64-bit fields)
In WmiResultItem::GetLongLong and WmiResultItem::GetUnsignedLongLong, changed
ret = value.lVal;toret = value.llVal;andret = value.ullVal;respectively, so the 64-bit VARIANT union members matching VT_I8/VT_UI8 are read instead of the 32-bit LONG member.π€ Prompt for AI agents
fix confidence: π’ 95 high β react π/π to teach the reviewer