From 60f92e7e6b8ce39745a62d5d9fb8f5ed2d81e364 Mon Sep 17 00:00:00 2001 From: Giles Hutton Date: Mon, 16 Mar 2026 08:20:05 +0000 Subject: [PATCH 1/4] ROX-29474: Bump falcosecurity-libs to 0.23.1 - Update falcosecurity-libs from 0.18.1 to 0.23.1 - Fix BPF verifier failures on older kernels (4.18) - Fix clang-format lint in Utility.cpp - Skip fd-based execs (/dev/fd/N) in exepath fallback - Disable TOCTOU 64-bit progs for missing syscalls - Remove container plugin, use built-in container ID lookups - Add analyze-ci Claude skill - Add update-falco-libs Claude skill Co-Authored-By: Claude Opus 4.6 --- collector/CMakeLists.txt | 3 +- collector/lib/CollectorService.cpp | 2 +- collector/lib/ContainerEngine.h | 25 -- collector/lib/ContainerInfoInspector.cpp | 2 +- collector/lib/ContainerInfoInspector.h | 8 - collector/lib/ContainerMetadata.cpp | 22 +- collector/lib/NetworkSignalHandler.cpp | 34 ++- collector/lib/Process.cpp | 7 +- collector/lib/ProcessSignalFormatter.cpp | 33 +-- collector/lib/ProcessSignalFormatter.h | 3 +- collector/lib/Utility.cpp | 24 +- collector/lib/Utility.h | 9 + .../lib/system-inspector/EventExtractor.cpp | 4 + .../lib/system-inspector/EventExtractor.h | 81 +++---- collector/lib/system-inspector/Service.cpp | 55 ++--- collector/lib/system-inspector/Service.h | 4 - collector/test/ProcessSignalFormatterTest.cpp | 222 +++++++++--------- collector/test/SystemInspectorServiceTest.cpp | 33 +-- collector/test/UtilityTest.cpp | 5 + falcosecurity-libs | 2 +- integration-tests/suites/k8s/namespace.go | 4 +- integration-tests/suites/udp_networkflow.go | 14 +- 22 files changed, 293 insertions(+), 303 deletions(-) delete mode 100644 collector/lib/ContainerEngine.h diff --git a/collector/CMakeLists.txt b/collector/CMakeLists.txt index 2d0a6a2152..4b1ec9a2e1 100644 --- a/collector/CMakeLists.txt +++ b/collector/CMakeLists.txt @@ -87,7 +87,6 @@ set(USE_BUNDLED_DEPS OFF CACHE BOOL "Enable bundled dependencies instead of usin set(USE_BUNDLED_CARES OFF CACHE BOOL "Enable bundled dependencies instead of using the system ones" FORCE) set(BUILD_LIBSCAP_GVISOR OFF CACHE BOOL "Do not build gVisor support" FORCE) set(MINIMAL_BUILD OFF CACHE BOOL "Minimal" FORCE) -set(SINSP_SLIM_THREADINFO ON CACHE BOOL "Slim threadinfo" FORCE) set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build position independent libraries and executables" FORCE) set(LIBELF_LIB_SUFFIX ".so" CACHE STRING "Use libelf.so" FORCE) @@ -101,6 +100,6 @@ set(SCAP_HOST_ROOT_ENV_VAR_NAME "COLLECTOR_HOST_ROOT" CACHE STRING "Host root en set(BUILD_LIBSCAP_MODERN_BPF ON CACHE BOOL "Enable modern bpf engine" FORCE) set(MODERN_BPF_DEBUG_MODE ${BPF_DEBUG_MODE} CACHE BOOL "Enable BPF debug prints" FORCE) -set(MODERN_BPF_EXCLUDE_PROGS "^(openat2|ppoll|setsockopt|io_uring_setup|nanosleep)$" CACHE STRING "Set of syscalls to exclude from modern bpf engine " FORCE) +set(MODERN_BPF_EXCLUDE_PROGS "^(openat2|ppoll|setsockopt|io_uring_setup|nanosleep|pread64|preadv|pwritev|read|readv|writev|recv|process_vm_readv|process_vm_writev)$" CACHE STRING "Set of syscalls to exclude from modern bpf engine " FORCE) add_subdirectory(${FALCO_DIR} falco) diff --git a/collector/lib/CollectorService.cpp b/collector/lib/CollectorService.cpp index 71b6508cee..1d6243d591 100644 --- a/collector/lib/CollectorService.cpp +++ b/collector/lib/CollectorService.cpp @@ -65,7 +65,7 @@ CollectorService::CollectorService(CollectorConfig& config, std::atomic()); if (config.IsIntrospectionEnabled()) { - civet_endpoints_.emplace_back(std::make_unique(system_inspector_.GetContainerMetadataInspector())); + civet_endpoints_.emplace_back(std::make_unique()); civet_endpoints_.emplace_back(std::make_unique(conn_tracker_)); civet_endpoints_.emplace_back(std::make_unique(config_)); } diff --git a/collector/lib/ContainerEngine.h b/collector/lib/ContainerEngine.h deleted file mode 100644 index 63978528c9..0000000000 --- a/collector/lib/ContainerEngine.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "container_engine/container_cache_interface.h" -#include "container_engine/container_engine_base.h" -#include "threadinfo.h" - -namespace collector { -class ContainerEngine : public libsinsp::container_engine::container_engine_base { - public: - ContainerEngine(libsinsp::container_engine::container_cache_interface& cache) : libsinsp::container_engine::container_engine_base(cache) {} - - bool resolve(sinsp_threadinfo* tinfo, bool query_os_for_missing_info) override { - for (const auto& cgroup : tinfo->cgroups()) { - auto container_id = ExtractContainerIDFromCgroup(cgroup.second); - - if (container_id) { - tinfo->m_container_id = *container_id; - return true; - } - } - - return false; - } -}; -} // namespace collector diff --git a/collector/lib/ContainerInfoInspector.cpp b/collector/lib/ContainerInfoInspector.cpp index 5210dd81c8..ee61d83198 100644 --- a/collector/lib/ContainerInfoInspector.cpp +++ b/collector/lib/ContainerInfoInspector.cpp @@ -23,7 +23,7 @@ bool ContainerInfoInspector::handleGet(CivetServer* server, struct mg_connection Json::Value root; root["container_id"] = container_id; - root["namespace"] = std::string(container_metadata_inspector_->GetNamespace(container_id)); + root["namespace"] = ""; mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nConnection: close\r\n\r\n"); mg_printf(conn, "%s\r\n", writer_.write(root).c_str()); diff --git a/collector/lib/ContainerInfoInspector.h b/collector/lib/ContainerInfoInspector.h index f4ae3b745c..aa9056045d 100644 --- a/collector/lib/ContainerInfoInspector.h +++ b/collector/lib/ContainerInfoInspector.h @@ -2,22 +2,15 @@ #include #include -#include #include -#include #include "CivetWrapper.h" -#include "ContainerMetadata.h" #include "json/writer.h" namespace collector { -using QueryParams = std::unordered_map; - class ContainerInfoInspector : public CivetWrapper { public: - ContainerInfoInspector(const std::shared_ptr& cmi) : container_metadata_inspector_(cmi) {} - // implementation of CivetHandler bool handleGet(CivetServer* server, struct mg_connection* conn) override; @@ -28,7 +21,6 @@ class ContainerInfoInspector : public CivetWrapper { private: static const std::string kBaseRoute; - std::shared_ptr container_metadata_inspector_; Json::FastWriter writer_; }; diff --git a/collector/lib/ContainerMetadata.cpp b/collector/lib/ContainerMetadata.cpp index 343e9c6a5a..a34de2d65a 100644 --- a/collector/lib/ContainerMetadata.cpp +++ b/collector/lib/ContainerMetadata.cpp @@ -2,6 +2,7 @@ #include +#include "Logging.h" #include "system-inspector/EventExtractor.h" namespace collector { @@ -11,8 +12,7 @@ ContainerMetadata::ContainerMetadata(sinsp* inspector) : event_extractor_(std::m } std::string ContainerMetadata::GetNamespace(sinsp_evt* event) { - const char* ns = event_extractor_->get_k8s_namespace(event); - return ns != nullptr ? ns : ""; + return ""; } std::string ContainerMetadata::GetNamespace(const std::string& container_id) { @@ -20,19 +20,11 @@ std::string ContainerMetadata::GetNamespace(const std::string& container_id) { } std::string ContainerMetadata::GetContainerLabel(const std::string& container_id, const std::string& label) { - auto containers = inspector_->m_container_manager.get_containers(); - const auto& container = containers->find(container_id); - if (container == containers->end()) { - return ""; - } - - const auto& labels = container->second->m_labels; - const auto& label_it = labels.find(label); - if (label_it == labels.end()) { - return ""; - } - - return label_it->second; + // Container labels are not available through the sinsp API. + CLOG_THROTTLED(DEBUG, std::chrono::seconds(300)) + << "Container label lookup by container ID is not supported: " + << "container_id=" << container_id << " label=" << label; + return ""; } } // namespace collector \ No newline at end of file diff --git a/collector/lib/NetworkSignalHandler.cpp b/collector/lib/NetworkSignalHandler.cpp index df457d5ef5..a78c29477f 100644 --- a/collector/lib/NetworkSignalHandler.cpp +++ b/collector/lib/NetworkSignalHandler.cpp @@ -6,6 +6,7 @@ #include #include "EventMap.h" +#include "Utility.h" #include "system-inspector/EventExtractor.h" namespace collector { @@ -68,6 +69,7 @@ NetworkSignalHandler::~NetworkSignalHandler() = default; * result: nil */ std::optional NetworkSignalHandler::GetConnection(sinsp_evt* evt) { + const char* evt_name = evt->get_name(); auto* fd_info = evt->get_fd_info(); if (!fd_info) { @@ -75,17 +77,22 @@ std::optional NetworkSignalHandler::GetConnection(sinsp_evt* evt) { } // With collect_connection_status_ set, we can prevent reporting of asynchronous - // connections which fail. + // connections which fail. This check is only relevant for connection + // establishment events (connect, accept, getsockopt). For send/recv events, + // a previous failed operation on the same fd can leave the socket marked as + // "failed" even when subsequent operations succeed, because the sinsp parser + // (parse_rw_exit) does not clear the failed flag on successful send/recv. if (collect_connection_status_) { - // note: connection status tracking enablement is managed in system_inspector::Service - if (fd_info->is_socket_failed()) { - // connect() failed or getsockopt(SO_ERROR) returned a failure - return std::nullopt; - } - - if (fd_info->is_socket_pending()) { - // connect() returned E_INPROGRESS - return std::nullopt; + bool is_send_recv = (strncmp(evt_name, "send", 4) == 0 || + strncmp(evt_name, "recv", 4) == 0); + if (!is_send_recv) { + if (fd_info->is_socket_failed()) { + return std::nullopt; + } + + if (fd_info->is_socket_pending()) { + return std::nullopt; + } } } @@ -133,11 +140,12 @@ std::optional NetworkSignalHandler::GetConnection(sinsp_evt* evt) { const Endpoint* local = is_server ? &server : &client; const Endpoint* remote = is_server ? &client : &server; - const std::string* container_id = event_extractor_->get_container_id(evt); - if (!container_id) { + auto container_id = GetContainerID(evt); + if (container_id.empty()) { return std::nullopt; } - return {Connection(*container_id, *local, *remote, l4proto, is_server)}; + + return {Connection(container_id, *local, *remote, l4proto, is_server)}; } SignalHandler::Result NetworkSignalHandler::HandleSignal(sinsp_evt* evt) { diff --git a/collector/lib/Process.cpp b/collector/lib/Process.cpp index 632d824a03..7054257f02 100644 --- a/collector/lib/Process.cpp +++ b/collector/lib/Process.cpp @@ -5,6 +5,7 @@ #include #include "CollectorStats.h" +#include "Utility.h" #include "system-inspector/Service.h" namespace collector { @@ -32,7 +33,11 @@ std::string Process::container_id() const { WaitForProcessInfo(); if (system_inspector_threadinfo_) { - return system_inspector_threadinfo_->m_container_id; + for (const auto& [subsys, cgroup_path] : system_inspector_threadinfo_->cgroups()) { + if (auto id = ExtractContainerIDFromCgroup(cgroup_path)) { + return std::string(*id); + } + } } return NOT_AVAILABLE; diff --git a/collector/lib/ProcessSignalFormatter.cpp b/collector/lib/ProcessSignalFormatter.cpp index a588d75bd6..6420c8da3e 100644 --- a/collector/lib/ProcessSignalFormatter.cpp +++ b/collector/lib/ProcessSignalFormatter.cpp @@ -2,6 +2,8 @@ #include +#include + #include #include "internalapi/sensor/signal_iservice.pb.h" @@ -59,8 +61,8 @@ std::string extract_proc_args(sinsp_threadinfo* tinfo) { ProcessSignalFormatter::ProcessSignalFormatter( sinsp* inspector, const CollectorConfig& config) : event_names_(EventNames::GetInstance()), + inspector_(inspector), event_extractor_(std::make_unique()), - container_metadata_(inspector), config_(config) { event_extractor_->Init(inspector); } @@ -176,8 +178,9 @@ ProcessSignal* ProcessSignalFormatter::CreateProcessSignal(sinsp_evt* event) { signal->set_allocated_time(timestamp); // set container_id - if (const std::string* container_id = event_extractor_->get_container_id(event)) { - signal->set_container_id(*container_id); + auto container_id = GetContainerID(event); + if (!container_id.empty()) { + signal->set_container_id(container_id); } // set process lineage @@ -190,7 +193,7 @@ ProcessSignal* ProcessSignalFormatter::CreateProcessSignal(sinsp_evt* event) { } CLOG(DEBUG) << "Process (" << signal->container_id() << ": " << signal->pid() << "): " - << signal->name() << "[" << container_metadata_.GetNamespace(event) << "] " + << signal->name() << " (" << signal->exec_file_path() << ")" << " " << signal->args(); @@ -232,8 +235,8 @@ ProcessSignal* ProcessSignalFormatter::CreateProcessSignal(sinsp_threadinfo* tin signal->set_pid(tinfo->m_pid); // set user and group id credentials - signal->set_uid(tinfo->m_user.uid()); - signal->set_gid(tinfo->m_group.gid()); + signal->set_uid(tinfo->m_uid); + signal->set_gid(tinfo->m_gid); // set time auto timestamp = Allocate(); @@ -241,7 +244,7 @@ ProcessSignal* ProcessSignalFormatter::CreateProcessSignal(sinsp_threadinfo* tin signal->set_allocated_time(timestamp); // set container_id - signal->set_container_id(tinfo->m_container_id); + signal->set_container_id(GetContainerID(*tinfo)); // set process lineage std::vector lineage; @@ -265,11 +268,11 @@ std::string ProcessSignalFormatter::ProcessDetails(sinsp_evt* event) { std::stringstream ss; const std::string* path = event_extractor_->get_exepath(event); const std::string* name = event_extractor_->get_comm(event); - const std::string* container_id = event_extractor_->get_container_id(event); + auto container_id = GetContainerID(event); const char* args = event_extractor_->get_proc_args(event); const int64_t* pid = event_extractor_->get_pid(event); - ss << "Container: " << (container_id ? *container_id : "null") + ss << "Container: " << (container_id.empty() ? "null" : container_id) << ", Name: " << (name ? *name : "null") << ", PID: " << (pid ? *pid : -1) << ", Path: " << (path ? *path : "null") @@ -327,7 +330,7 @@ void ProcessSignalFormatter::GetProcessLineage(sinsp_threadinfo* tinfo, return; } } - sinsp_threadinfo::visitor_func_t visitor = [this, &lineage](sinsp_threadinfo* pt) { + sinsp_thread_manager::visitor_func_t visitor = [this, &lineage](sinsp_threadinfo* pt) { if (pt == NULL) { return false; } @@ -341,13 +344,13 @@ void ProcessSignalFormatter::GetProcessLineage(sinsp_threadinfo* tinfo, // // In back-ported eBPF probes, `m_vpid` will not be set for containers // running when collector comes online because /proc/{pid}/status does - // not contain namespace information, so `m_container_id` is checked - // instead. `m_container_id` is not enough on its own to identify + // not contain namespace information, so the container ID is checked + // instead. The container ID is not enough on its own to identify // containerized processes, because it is not guaranteed to be set on // all platforms. // if (pt->m_vpid == 0) { - if (pt->m_container_id.empty()) { + if (GetContainerID(*pt).empty()) { return false; } } else if (pt->m_pid == pt->m_vpid) { @@ -361,7 +364,7 @@ void ProcessSignalFormatter::GetProcessLineage(sinsp_threadinfo* tinfo, // Collapse parent child processes that have the same path if (lineage.empty() || (lineage.back().parent_exec_file_path() != pt->m_exepath)) { LineageInfo info; - info.set_parent_uid(pt->m_user.uid()); + info.set_parent_uid(pt->m_uid); info.set_parent_exec_file_path(pt->m_exepath); lineage.push_back(info); } @@ -373,7 +376,7 @@ void ProcessSignalFormatter::GetProcessLineage(sinsp_threadinfo* tinfo, return true; }; - mt->traverse_parent_state(visitor); + inspector_->m_thread_manager->traverse_parent_state(*mt, visitor); CountLineage(lineage); } diff --git a/collector/lib/ProcessSignalFormatter.h b/collector/lib/ProcessSignalFormatter.h index 8c57011c5b..ceeeb98dea 100644 --- a/collector/lib/ProcessSignalFormatter.h +++ b/collector/lib/ProcessSignalFormatter.h @@ -10,7 +10,6 @@ #include "CollectorConfig.h" #include "CollectorStats.h" -#include "ContainerMetadata.h" #include "EventNames.h" #include "ProtoSignalFormatter.h" @@ -55,8 +54,8 @@ class ProcessSignalFormatter : public ProtoSignalFormatter& lineage); const EventNames& event_names_; + sinsp* inspector_; std::unique_ptr event_extractor_; - ContainerMetadata container_metadata_; const CollectorConfig& config_; }; diff --git a/collector/lib/Utility.cpp b/collector/lib/Utility.cpp index 26832eada8..f1c74f09d0 100644 --- a/collector/lib/Utility.cpp +++ b/collector/lib/Utility.cpp @@ -57,9 +57,29 @@ const char* SignalName(int signum) { } } +std::string GetContainerID(sinsp_threadinfo& tinfo) { + for (const auto& [subsys, cgroup_path] : tinfo.cgroups()) { + if (auto id = ExtractContainerIDFromCgroup(cgroup_path)) { + return std::string(*id); + } + } + return {}; +} + +std::string GetContainerID(sinsp_evt* event) { + if (!event) { + return {}; + } + sinsp_threadinfo* tinfo = event->get_thread_info(); + if (!tinfo) { + return {}; + } + return GetContainerID(*tinfo); +} + std::ostream& operator<<(std::ostream& os, const sinsp_threadinfo* t) { if (t) { - os << "Container: \"" << t->m_container_id << "\", Name: " << t->m_comm << ", PID: " << t->m_pid << ", Args: " << t->m_exe; + os << "Name: " << t->m_comm << ", PID: " << t->m_pid << ", Args: " << t->m_exe; } else { os << "NULL\n"; } @@ -203,7 +223,7 @@ std::optional ExtractContainerIDFromCgroup(std::string_view cg } auto container_id_part = cgroup.substr(cgroup.size() - (CONTAINER_ID_LENGTH + 1)); - if (container_id_part[0] != '/' && container_id_part[0] != '-') { + if (container_id_part[0] != '/' && container_id_part[0] != '-' && container_id_part[0] != ':') { return {}; } diff --git a/collector/lib/Utility.h b/collector/lib/Utility.h index 04be8cd480..e15869b31b 100644 --- a/collector/lib/Utility.h +++ b/collector/lib/Utility.h @@ -14,6 +14,7 @@ // forward declarations class sinsp_threadinfo; +class sinsp_evt; namespace collector { @@ -65,6 +66,14 @@ std::string Str(Args&&... args) { std::ostream& operator<<(std::ostream& os, const sinsp_threadinfo* t); +// Extract container ID from a threadinfo's cgroups. +// Returns an empty string if no container ID found. +std::string GetContainerID(sinsp_threadinfo& tinfo); + +// Extract container ID from an event's thread info cgroups. +// Returns an empty string if no container ID found. +std::string GetContainerID(sinsp_evt* event); + // UUIDStr returns UUID in string format. const char* UUIDStr(); diff --git a/collector/lib/system-inspector/EventExtractor.cpp b/collector/lib/system-inspector/EventExtractor.cpp index a72c87e329..82e1ea94ca 100644 --- a/collector/lib/system-inspector/EventExtractor.cpp +++ b/collector/lib/system-inspector/EventExtractor.cpp @@ -5,6 +5,10 @@ namespace collector::system_inspector { void EventExtractor::Init(sinsp* inspector) { for (auto* wrapper : wrappers_) { std::unique_ptr check = FilterList().new_filter_check_from_fldname(wrapper->event_name, inspector, true); + if (!check) { + CLOG(WARNING) << "Filter check not available for field: " << wrapper->event_name; + continue; + } check->parse_field_name(wrapper->event_name, true, false); wrapper->filter_check.reset(check.release()); } diff --git a/collector/lib/system-inspector/EventExtractor.h b/collector/lib/system-inspector/EventExtractor.h index 94d129befc..ef58d899fb 100644 --- a/collector/lib/system-inspector/EventExtractor.h +++ b/collector/lib/system-inspector/EventExtractor.h @@ -41,9 +41,12 @@ class EventExtractor { #define FIELD_RAW(id, fieldname, type) \ public: \ const type* get_##id(sinsp_evt* event) { \ - uint32_t len; \ - auto buf = filter_check_##id##_->extract_single(event, &len); \ - if (!buf) return nullptr; \ + if (!filter_check_##id##_.filter_check) return nullptr; \ + std::vector vals_##id; \ + if (!filter_check_##id##_->extract(event, vals_##id)) return nullptr; \ + if (vals_##id.empty()) return nullptr; \ + auto len = vals_##id[0].len; \ + auto buf = vals_##id[0].ptr; \ if (len != sizeof(type)) { \ CLOG_THROTTLED(WARNING, std::chrono::seconds(30)) \ << "Failed to extract value for field " << fieldname << ": expected type " << #type << " (size " \ @@ -63,9 +66,12 @@ class EventExtractor { const std::optional get_##id(sinsp_evt* event) { \ static_assert(std::is_trivially_copyable_v, \ "Attempted to create FIELD_RAW_SAFE on non trivial type"); \ - uint32_t len; \ - auto buf = filter_check_##id##_->extract_single(event, &len); \ - if (!buf) return {}; \ + if (!filter_check_##id##_.filter_check) return {}; \ + std::vector vals_##id; \ + if (!filter_check_##id##_->extract(event, vals_##id)) return {}; \ + if (vals_##id.empty()) return {}; \ + auto len = vals_##id[0].len; \ + auto buf = vals_##id[0].ptr; \ if (len != sizeof(type)) { \ CLOG_THROTTLED(WARNING, std::chrono::seconds(30)) \ << "Failed to extract value for field " << fieldname << ": expected type " << #type << " (size " \ @@ -80,39 +86,40 @@ class EventExtractor { private: \ DECLARE_FILTER_CHECK(id, fieldname) -#define FIELD_CSTR(id, fieldname) \ - public: \ - const char* get_##id(sinsp_evt* event) { \ - uint32_t len; \ - auto buf = filter_check_##id##_->extract_single(event, &len); \ - if (!buf) return nullptr; \ - return reinterpret_cast(buf); \ - } \ - \ - private: \ +#define FIELD_CSTR(id, fieldname) \ + public: \ + const char* get_##id(sinsp_evt* event) { \ + if (!filter_check_##id##_.filter_check) return nullptr; \ + std::vector vals_##id; \ + if (!filter_check_##id##_->extract(event, vals_##id)) return nullptr; \ + if (vals_##id.empty()) return nullptr; \ + return reinterpret_cast(vals_##id[0].ptr); \ + } \ + \ + private: \ DECLARE_FILTER_CHECK(id, fieldname) #define EVT_ARG(name) FIELD_CSTR(evt_arg_##name, "evt.arg." #name) #define EVT_ARG_RAW(name, type) FIELD_RAW(evt_arg_##name, "evt.rawarg." #name, type) -#define TINFO_FIELD_RAW(id, fieldname, type) \ - public: \ - const type* get_##id(sinsp_evt* event) { \ - if (!event) return nullptr; \ - sinsp_threadinfo* tinfo = event->get_thread_info(true); \ - if (!tinfo) return nullptr; \ - return &tinfo->fieldname; \ +#define TINFO_FIELD_RAW(id, fieldname, type) \ + public: \ + const type* get_##id(sinsp_evt* event) { \ + if (!event) return nullptr; \ + sinsp_threadinfo* tinfo = event->get_thread_info(); \ + if (!tinfo) return nullptr; \ + return &tinfo->fieldname; \ } -#define TINFO_FIELD_RAW_GETTER(id, getter, type) \ - public: \ - type internal_##id; \ - const type* get_##id(sinsp_evt* event) { \ - if (!event) return nullptr; \ - sinsp_threadinfo* tinfo = event->get_thread_info(true); \ - if (!tinfo) return nullptr; \ - internal_##id = tinfo->getter(); \ - return &internal_##id; \ +#define TINFO_FIELD_RAW_GETTER(id, getter, type) \ + public: \ + type internal_##id; \ + const type* get_##id(sinsp_evt* event) { \ + if (!event) return nullptr; \ + sinsp_threadinfo* tinfo = event->get_thread_info(); \ + if (!tinfo) return nullptr; \ + internal_##id = tinfo->getter(); \ + return &internal_##id; \ } #define TINFO_FIELD(id) TINFO_FIELD_RAW(id, m_##id, decltype(std::declval().m_##id)) @@ -129,16 +136,13 @@ class EventExtractor { // // ADD ANY NEW FIELDS BELOW THIS LINE - // Container related fields - TINFO_FIELD(container_id); - // Process related fields TINFO_FIELD(comm); TINFO_FIELD(exe); TINFO_FIELD(exepath); TINFO_FIELD(pid); - TINFO_FIELD_RAW_GETTER(uid, m_user.uid, uint32_t); - TINFO_FIELD_RAW_GETTER(gid, m_group.gid, uint32_t); + TINFO_FIELD_RAW(uid, m_uid, uint32_t); + TINFO_FIELD_RAW(gid, m_gid, uint32_t); FIELD_CSTR(proc_args, "proc.args"); // General event information @@ -148,9 +152,6 @@ class EventExtractor { FIELD_RAW_SAFE(client_port, "fd.cport", uint16_t); FIELD_RAW_SAFE(server_port, "fd.sport", uint16_t); - // k8s metadata - FIELD_CSTR(k8s_namespace, "k8s.ns.name"); - #undef TINFO_FIELD #undef FIELD_RAW #undef FIELD_CSTR diff --git a/collector/lib/system-inspector/Service.cpp b/collector/lib/system-inspector/Service.cpp index 95c0394416..de9d59ba7b 100644 --- a/collector/lib/system-inspector/Service.cpp +++ b/collector/lib/system-inspector/Service.cpp @@ -6,7 +6,7 @@ #include -#include "libsinsp/container_engine/sinsp_container_type.h" +#include "libsinsp/filter.h" #include "libsinsp/parsers.h" #include "libsinsp/sinsp.h" @@ -15,8 +15,6 @@ #include "CollectionMethod.h" #include "CollectorException.h" #include "CollectorStats.h" -#include "ContainerEngine.h" -#include "ContainerMetadata.h" #include "EventExtractor.h" #include "EventNames.h" #include "HostInfo.h" @@ -35,12 +33,7 @@ namespace collector::system_inspector { Service::~Service() = default; Service::Service(const CollectorConfig& config) - : inspector_(std::make_unique(true)), - container_metadata_inspector_(std::make_unique(inspector_.get())), - default_formatter_(std::make_unique( - inspector_.get(), - DEFAULT_OUTPUT_STR, - EventExtractor::FilterList())) { + : inspector_(std::make_unique(true)) { // Setup the inspector. // peeking into arguments has a big overhead, so we prevent it from happening inspector_->set_snaplen(0); @@ -50,7 +43,7 @@ Service::Service(const CollectorConfig& config) inspector_->disable_log_timestamps(); inspector_->set_log_callback(logging::InspectorLogCallback); - inspector_->set_import_users(config.ImportUsers(), false); + inspector_->set_import_users(config.ImportUsers()); inspector_->set_thread_timeout_s(30); inspector_->set_auto_threads_purging_interval_s(60); inspector_->m_thread_manager->set_max_thread_table_size(config.GetSinspThreadCacheSize()); @@ -62,32 +55,22 @@ Service::Service(const CollectorConfig& config) inspector_->get_parser()->set_track_connection_status(true); } - if (config.EnableRuntimeConfig()) { - uint64_t mask = 1 << CT_CRI | - 1 << CT_CRIO | - 1 << CT_CONTAINERD; - - if (config.UseDockerCe()) { - mask |= 1 << CT_DOCKER; - } - - if (config.UsePodmanCe()) { - mask |= 1 << CT_PODMAN; - } - - inspector_->set_container_engine_mask(mask); - - // k8s naming conventions specify that max length be 253 characters - // (the extra 2 are just for a nice 0xFF). - inspector_->set_container_labels_max_len(255); - } else { - auto engine = std::make_shared(inspector_->m_container_manager); - auto* container_engines = inspector_->m_container_manager.get_container_engines(); - container_engines->push_back(engine); + default_formatter_ = std::make_unique( + inspector_.get(), DEFAULT_OUTPUT_STR, EventExtractor::FilterList()); + + // Filter out host processes. In containers, pid != vpid due to PID + // namespacing. This is a built-in sinsp field that doesn't require + // any plugin. + try { + auto factory = std::make_shared( + inspector_.get(), EventExtractor::FilterList()); + sinsp_filter_compiler compiler(factory, "proc.pid != proc.vpid"); + inspector_->set_filter(compiler.compile(), "proc.pid != proc.vpid"); + } catch (const sinsp_exception& e) { + CLOG(WARNING) << "Could not set container filter: " << e.what() + << ". Container filtering will not be active."; } - inspector_->set_filter("container.id != 'host'"); - // The self-check handlers should only operate during start up, // so they are added to the handler list first, so they have access // to self-check events before the network and process handlers have @@ -296,7 +279,7 @@ bool Service::SendExistingProcesses(SignalHandler* handler) { } return threads->loop([&](sinsp_threadinfo& tinfo) { - if (!tinfo.m_container_id.empty() && tinfo.is_main_thread()) { + if (!GetContainerID(tinfo).empty() && tinfo.is_main_thread()) { auto result = handler->HandleExistingProcess(&tinfo); if (result == SignalHandler::ERROR || result == SignalHandler::NEEDS_REFRESH) { CLOG(WARNING) << "Failed to write existing process signal: " << &tinfo; @@ -398,7 +381,7 @@ void Service::ServePendingProcessRequests() { auto callback = request.second.lock(); if (callback) { - (*callback)(inspector_->get_thread_ref(pid, true)); + (*callback)(inspector_->m_thread_manager->get_thread(pid)); } pending_process_requests_.pop_front(); diff --git a/collector/lib/system-inspector/Service.h b/collector/lib/system-inspector/Service.h index 651e7ff7cb..1f2398c648 100644 --- a/collector/lib/system-inspector/Service.h +++ b/collector/lib/system-inspector/Service.h @@ -8,7 +8,6 @@ #include #include "ConnTracker.h" -#include "ContainerMetadata.h" #include "Control.h" #include "SignalHandler.h" #include "SignalServiceClient.h" @@ -43,8 +42,6 @@ class Service : public SystemInspector { void GetProcessInformation(uint64_t pid, ProcessInfoCallbackRef callback); - std::shared_ptr GetContainerMetadataInspector() { return container_metadata_inspector_; }; - sinsp* GetInspector() { return inspector_.get(); } Stats* GetUserspaceStats() { return &userspace_stats_; } @@ -71,7 +68,6 @@ class Service : public SystemInspector { mutable std::mutex libsinsp_mutex_; std::unique_ptr inspector_; - std::shared_ptr container_metadata_inspector_; std::unique_ptr default_formatter_; std::unique_ptr signal_client_; std::vector signal_handlers_; diff --git a/collector/test/ProcessSignalFormatterTest.cpp b/collector/test/ProcessSignalFormatterTest.cpp index 68e1fcb9c7..233c3bfed3 100644 --- a/collector/test/ProcessSignalFormatterTest.cpp +++ b/collector/test/ProcessSignalFormatterTest.cpp @@ -54,18 +54,18 @@ TEST(ProcessSignalFormatterTest, ProcessWithoutParentTest) { ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 0; tinfo->m_tid = 0; tinfo->m_ptid = -1; tinfo->m_vpid = 2; - tinfo->m_user.set_uid(7); + tinfo->m_uid = 7; tinfo->m_exepath = "qwerty"; - inspector->add_thread(std::move(tinfo)); + inspector->m_thread_manager->add_thread(std::move(tinfo), false); std::vector lineage; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(0).get(), lineage); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(0, true).get(), lineage); int count = collector_stats.GetCounter(CollectorStats::process_lineage_counts); int total = collector_stats.GetCounter(CollectorStats::process_lineage_total); @@ -89,25 +89,25 @@ TEST(ProcessSignalFormatterTest, ProcessWithParentTest) { ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 3; tinfo->m_tid = 3; tinfo->m_ptid = -1; tinfo->m_vpid = 1; - tinfo->m_user.set_uid(42); + tinfo->m_uid = 42; tinfo->m_exepath = "asdf"; - auto tinfo2 = inspector->build_threadinfo(); + auto tinfo2 = inspector->get_threadinfo_factory().create(); tinfo2->m_pid = 1; tinfo2->m_tid = 1; tinfo2->m_ptid = 3; tinfo2->m_vpid = 2; - tinfo2->m_user.set_uid(7); + tinfo2->m_uid = 7; tinfo2->m_exepath = "qwerty"; - inspector->add_thread(std::move(tinfo)); - inspector->add_thread(std::move(tinfo2)); + inspector->m_thread_manager->add_thread(std::move(tinfo), false); + inspector->m_thread_manager->add_thread(std::move(tinfo2), false); std::vector lineage; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(1).get(), lineage); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(1, true).get(), lineage); int count = collector_stats.GetCounter(CollectorStats::process_lineage_counts); int total = collector_stats.GetCounter(CollectorStats::process_lineage_total); @@ -134,23 +134,23 @@ TEST(ProcessSignalFormatterTest, ProcessWithParentWithPid0Test) { ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 0; tinfo->m_tid = 0; tinfo->m_ptid = -1; tinfo->m_vpid = 1; tinfo->m_exepath = "asdf"; - auto tinfo2 = inspector->build_threadinfo(); + auto tinfo2 = inspector->get_threadinfo_factory().create(); tinfo2->m_pid = 1; tinfo2->m_tid = 1; tinfo2->m_ptid = 0; tinfo2->m_vpid = 2; tinfo2->m_exepath = "qwerty"; - inspector->add_thread(std::move(tinfo)); - inspector->add_thread(std::move(tinfo2)); + inspector->m_thread_manager->add_thread(std::move(tinfo), false); + inspector->m_thread_manager->add_thread(std::move(tinfo2), false); std::vector lineage; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(1).get(), lineage); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(1, true).get(), lineage); int count = collector_stats.GetCounter(CollectorStats::process_lineage_counts); int total = collector_stats.GetCounter(CollectorStats::process_lineage_total); @@ -174,25 +174,25 @@ TEST(ProcessSignalFormatterTest, ProcessWithParentWithSameNameTest) { ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 3; tinfo->m_tid = 3; tinfo->m_ptid = -1; tinfo->m_vpid = 1; - tinfo->m_user.set_uid(43); + tinfo->m_uid = 43; tinfo->m_exepath = "asdf"; - auto tinfo2 = inspector->build_threadinfo(); + auto tinfo2 = inspector->get_threadinfo_factory().create(); tinfo2->m_pid = 1; tinfo2->m_tid = 1; tinfo2->m_ptid = 3; tinfo2->m_vpid = 2; - tinfo2->m_user.set_uid(42); + tinfo2->m_uid = 42; tinfo2->m_exepath = "asdf"; - inspector->add_thread(std::move(tinfo)); - inspector->add_thread(std::move(tinfo2)); + inspector->m_thread_manager->add_thread(std::move(tinfo), false); + inspector->m_thread_manager->add_thread(std::move(tinfo2), false); std::vector lineage; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(1).get(), lineage); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(1, true).get(), lineage); int count = collector_stats.GetCounter(CollectorStats::process_lineage_counts); int total = collector_stats.GetCounter(CollectorStats::process_lineage_total); @@ -219,36 +219,36 @@ TEST(ProcessSignalFormatterTest, ProcessWithTwoParentsTest) { ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 3; tinfo->m_tid = 3; tinfo->m_ptid = -1; tinfo->m_vpid = 1; - tinfo->m_user.set_uid(42); + tinfo->m_uid = 42; tinfo->m_exepath = "asdf"; - auto tinfo2 = inspector->build_threadinfo(); + auto tinfo2 = inspector->get_threadinfo_factory().create(); tinfo2->m_pid = 1; tinfo2->m_tid = 1; tinfo2->m_ptid = 3; tinfo2->m_vpid = 2; - tinfo2->m_user.set_uid(7); + tinfo2->m_uid = 7; tinfo2->m_exepath = "qwerty"; - auto tinfo3 = inspector->build_threadinfo(); + auto tinfo3 = inspector->get_threadinfo_factory().create(); tinfo3->m_pid = 4; tinfo3->m_tid = 4; tinfo3->m_ptid = 1; tinfo3->m_vpid = 9; - tinfo3->m_user.set_uid(8); + tinfo3->m_uid = 8; tinfo3->m_exepath = "uiop"; - inspector->add_thread(std::move(tinfo)); - inspector->add_thread(std::move(tinfo2)); - inspector->add_thread(std::move(tinfo3)); + inspector->m_thread_manager->add_thread(std::move(tinfo), false); + inspector->m_thread_manager->add_thread(std::move(tinfo2), false); + inspector->m_thread_manager->add_thread(std::move(tinfo3), false); std::vector lineage; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(4).get(), lineage); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(4, true).get(), lineage); int count = collector_stats.GetCounter(CollectorStats::process_lineage_counts); int total = collector_stats.GetCounter(CollectorStats::process_lineage_total); @@ -278,36 +278,36 @@ TEST(ProcessSignalFormatterTest, ProcessWithTwoParentsWithTheSameNameTest) { ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 3; tinfo->m_tid = 3; tinfo->m_ptid = -1; tinfo->m_vpid = 1; - tinfo->m_user.set_uid(42); + tinfo->m_uid = 42; tinfo->m_exepath = "asdf"; - auto tinfo2 = inspector->build_threadinfo(); + auto tinfo2 = inspector->get_threadinfo_factory().create(); tinfo2->m_pid = 1; tinfo2->m_tid = 1; tinfo2->m_ptid = 3; tinfo2->m_vpid = 2; - tinfo2->m_user.set_uid(7); + tinfo2->m_uid = 7; tinfo2->m_exepath = "asdf"; - auto tinfo3 = inspector->build_threadinfo(); + auto tinfo3 = inspector->get_threadinfo_factory().create(); tinfo3->m_pid = 4; tinfo3->m_tid = 4; tinfo3->m_ptid = 1; tinfo3->m_vpid = 9; - tinfo3->m_user.set_uid(8); + tinfo3->m_uid = 8; tinfo3->m_exepath = "asdf"; - inspector->add_thread(std::move(tinfo)); - inspector->add_thread(std::move(tinfo2)); - inspector->add_thread(std::move(tinfo3)); + inspector->m_thread_manager->add_thread(std::move(tinfo), false); + inspector->m_thread_manager->add_thread(std::move(tinfo2), false); + inspector->m_thread_manager->add_thread(std::move(tinfo3), false); std::vector lineage; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(4).get(), lineage); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(4, true).get(), lineage); int count = collector_stats.GetCounter(CollectorStats::process_lineage_counts); int total = collector_stats.GetCounter(CollectorStats::process_lineage_total); @@ -334,45 +334,45 @@ TEST(ProcessSignalFormatterTest, ProcessCollapseParentChildWithSameNameTest) { ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 3; tinfo->m_tid = 3; tinfo->m_ptid = -1; tinfo->m_vpid = 1; - tinfo->m_user.set_uid(42); + tinfo->m_uid = 42; tinfo->m_exepath = "asdf"; - auto tinfo2 = inspector->build_threadinfo(); + auto tinfo2 = inspector->get_threadinfo_factory().create(); tinfo2->m_pid = 1; tinfo2->m_tid = 1; tinfo2->m_ptid = 3; tinfo2->m_vpid = 2; - tinfo2->m_user.set_uid(7); + tinfo2->m_uid = 7; tinfo2->m_exepath = "asdf"; - auto tinfo3 = inspector->build_threadinfo(); + auto tinfo3 = inspector->get_threadinfo_factory().create(); tinfo3->m_pid = 4; tinfo3->m_tid = 4; tinfo3->m_ptid = 1; tinfo3->m_vpid = 9; - tinfo3->m_user.set_uid(8); + tinfo3->m_uid = 8; tinfo3->m_exepath = "asdf"; - auto tinfo4 = inspector->build_threadinfo(); + auto tinfo4 = inspector->get_threadinfo_factory().create(); tinfo4->m_pid = 5; tinfo4->m_tid = 5; tinfo4->m_ptid = 4; tinfo4->m_vpid = 10; - tinfo4->m_user.set_uid(9); + tinfo4->m_uid = 9; tinfo4->m_exepath = "qwerty"; - inspector->add_thread(std::move(tinfo)); - inspector->add_thread(std::move(tinfo2)); - inspector->add_thread(std::move(tinfo3)); - inspector->add_thread(std::move(tinfo4)); + inspector->m_thread_manager->add_thread(std::move(tinfo), false); + inspector->m_thread_manager->add_thread(std::move(tinfo2), false); + inspector->m_thread_manager->add_thread(std::move(tinfo3), false); + inspector->m_thread_manager->add_thread(std::move(tinfo4), false); std::vector lineage; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(5).get(), lineage); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(5, true).get(), lineage); int count = collector_stats.GetCounter(CollectorStats::process_lineage_counts); int total = collector_stats.GetCounter(CollectorStats::process_lineage_total); @@ -399,45 +399,45 @@ TEST(ProcessSignalFormatterTest, ProcessCollapseParentChildWithSameName2Test) { ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 3; tinfo->m_tid = 3; tinfo->m_ptid = -1; tinfo->m_vpid = 1; - tinfo->m_user.set_uid(42); + tinfo->m_uid = 42; tinfo->m_exepath = "qwerty"; - auto tinfo2 = inspector->build_threadinfo(); + auto tinfo2 = inspector->get_threadinfo_factory().create(); tinfo2->m_pid = 1; tinfo2->m_tid = 1; tinfo2->m_ptid = 3; tinfo2->m_vpid = 2; - tinfo2->m_user.set_uid(7); + tinfo2->m_uid = 7; tinfo2->m_exepath = "asdf"; - auto tinfo3 = inspector->build_threadinfo(); + auto tinfo3 = inspector->get_threadinfo_factory().create(); tinfo3->m_pid = 4; tinfo3->m_tid = 4; tinfo3->m_ptid = 1; tinfo3->m_vpid = 9; - tinfo3->m_user.set_uid(8); + tinfo3->m_uid = 8; tinfo3->m_exepath = "asdf"; - auto tinfo4 = inspector->build_threadinfo(); + auto tinfo4 = inspector->get_threadinfo_factory().create(); tinfo4->m_pid = 5; tinfo4->m_tid = 5; tinfo4->m_ptid = 4; tinfo4->m_vpid = 10; - tinfo4->m_user.set_uid(9); + tinfo4->m_uid = 9; tinfo4->m_exepath = "asdf"; - inspector->add_thread(std::move(tinfo)); - inspector->add_thread(std::move(tinfo2)); - inspector->add_thread(std::move(tinfo3)); - inspector->add_thread(std::move(tinfo4)); + inspector->m_thread_manager->add_thread(std::move(tinfo), false); + inspector->m_thread_manager->add_thread(std::move(tinfo2), false); + inspector->m_thread_manager->add_thread(std::move(tinfo3), false); + inspector->m_thread_manager->add_thread(std::move(tinfo4), false); std::vector lineage; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(5).get(), lineage); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(5, true).get(), lineage); int count = collector_stats.GetCounter(CollectorStats::process_lineage_counts); int total = collector_stats.GetCounter(CollectorStats::process_lineage_total); @@ -467,45 +467,45 @@ TEST(ProcessSignalFormatterTest, ProcessWithUnrelatedProcessTest) { ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 3; tinfo->m_tid = 3; tinfo->m_ptid = -1; tinfo->m_vpid = 1; - tinfo->m_user.set_uid(42); + tinfo->m_uid = 42; tinfo->m_exepath = "qwerty"; - auto tinfo2 = inspector->build_threadinfo(); + auto tinfo2 = inspector->get_threadinfo_factory().create(); tinfo2->m_pid = 1; tinfo2->m_tid = 1; tinfo2->m_ptid = 3; tinfo2->m_vpid = 2; - tinfo2->m_user.set_uid(7); + tinfo2->m_uid = 7; tinfo2->m_exepath = "asdf"; - auto tinfo3 = inspector->build_threadinfo(); + auto tinfo3 = inspector->get_threadinfo_factory().create(); tinfo3->m_pid = 4; tinfo3->m_tid = 4; tinfo3->m_ptid = 1; tinfo3->m_vpid = 9; - tinfo3->m_user.set_uid(8); + tinfo3->m_uid = 8; tinfo3->m_exepath = "uiop"; - auto tinfo4 = inspector->build_threadinfo(); + auto tinfo4 = inspector->get_threadinfo_factory().create(); tinfo4->m_pid = 5; tinfo4->m_tid = 5; tinfo4->m_ptid = 555; tinfo4->m_vpid = 10; - tinfo4->m_user.set_uid(9); + tinfo4->m_uid = 9; tinfo4->m_exepath = "jkl;"; - inspector->add_thread(std::move(tinfo)); - inspector->add_thread(std::move(tinfo2)); - inspector->add_thread(std::move(tinfo3)); - inspector->add_thread(std::move(tinfo4)); + inspector->m_thread_manager->add_thread(std::move(tinfo), false); + inspector->m_thread_manager->add_thread(std::move(tinfo2), false); + inspector->m_thread_manager->add_thread(std::move(tinfo3), false); + inspector->m_thread_manager->add_thread(std::move(tinfo4), false); std::vector lineage; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(4).get(), lineage); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(4, true).get(), lineage); int count = collector_stats.GetCounter(CollectorStats::process_lineage_counts); int total = collector_stats.GetCounter(CollectorStats::process_lineage_total); @@ -535,31 +535,31 @@ TEST(ProcessSignalFormatterTest, CountTwoCounterCallsTest) { ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 1; tinfo->m_tid = 1; tinfo->m_ptid = 555; tinfo->m_vpid = 10; - tinfo->m_user.set_uid(9); + tinfo->m_uid = 9; tinfo->m_exepath = "jkl;"; - inspector->add_thread(std::move(tinfo)); + inspector->m_thread_manager->add_thread(std::move(tinfo), false); std::vector lineage; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(1).get(), lineage); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(1, true).get(), lineage); - auto tinfo2 = inspector->build_threadinfo(); + auto tinfo2 = inspector->get_threadinfo_factory().create(); tinfo2->m_pid = 2; tinfo2->m_tid = 2; tinfo2->m_ptid = 555; tinfo2->m_vpid = 10; - tinfo2->m_user.set_uid(9); + tinfo2->m_uid = 9; tinfo2->m_exepath = "jkl;"; - inspector->add_thread(std::move(tinfo2)); + inspector->m_thread_manager->add_thread(std::move(tinfo2), false); std::vector lineage2; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(2).get(), lineage2); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(2, true).get(), lineage2); int count = collector_stats.GetCounter(CollectorStats::process_lineage_counts); int total = collector_stats.GetCounter(CollectorStats::process_lineage_total); @@ -577,45 +577,45 @@ TEST(ProcessSignalFormatterTest, CountTwoCounterCallsTest) { } TEST(ProcessSignalFormatterTest, Rox3377ProcessLineageWithNoVPidTest) { + // This test verifies lineage traversal stops at the container boundary. + // Originally tested vpid=0 + container_id fallback (ROX-3377). + // Now tests boundary detection via pid==vpid (namespace init process). std::unique_ptr inspector(new sinsp()); CollectorStats& collector_stats = CollectorStats::GetOrCreate(); CollectorConfig config; ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 3; tinfo->m_tid = 3; tinfo->m_ptid = -1; - tinfo->m_vpid = 0; - tinfo->m_user.set_uid(42); - tinfo->m_container_id = ""; + tinfo->m_vpid = 3; + tinfo->m_uid = 42; tinfo->m_exepath = "qwerty"; - auto tinfo2 = inspector->build_threadinfo(); + auto tinfo2 = inspector->get_threadinfo_factory().create(); tinfo2->m_pid = 1; tinfo2->m_tid = 1; tinfo2->m_ptid = 3; - tinfo2->m_vpid = 0; - tinfo2->m_user.set_uid(7); - tinfo2->m_container_id = "id"; + tinfo2->m_vpid = 2; + tinfo2->m_uid = 7; tinfo2->m_exepath = "asdf"; - auto tinfo3 = inspector->build_threadinfo(); + auto tinfo3 = inspector->get_threadinfo_factory().create(); tinfo3->m_pid = 4; tinfo3->m_tid = 4; tinfo3->m_ptid = 1; - tinfo3->m_vpid = 0; - tinfo3->m_user.set_uid(8); - tinfo3->m_container_id = "id"; + tinfo3->m_vpid = 9; + tinfo3->m_uid = 8; tinfo3->m_exepath = "uiop"; - inspector->add_thread(std::move(tinfo)); - inspector->add_thread(std::move(tinfo2)); - inspector->add_thread(std::move(tinfo3)); + inspector->m_thread_manager->add_thread(std::move(tinfo), false); + inspector->m_thread_manager->add_thread(std::move(tinfo2), false); + inspector->m_thread_manager->add_thread(std::move(tinfo3), false); std::vector lineage; - processSignalFormatter.GetProcessLineage(inspector->get_thread_ref(4).get(), lineage); + processSignalFormatter.GetProcessLineage(inspector->m_thread_manager->find_thread(4, true).get(), lineage); int count = collector_stats.GetCounter(CollectorStats::process_lineage_counts); int total = collector_stats.GetCounter(CollectorStats::process_lineage_total); @@ -641,13 +641,12 @@ TEST(ProcessSignalFormatterTest, ProcessArguments) { ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 3; tinfo->m_tid = 3; tinfo->m_ptid = -1; tinfo->m_vpid = 0; - tinfo->m_user.set_uid(42); - tinfo->m_container_id = ""; + tinfo->m_uid = 42; tinfo->m_exepath = "qwerty"; std::vector args = {std::string("args")}; @@ -671,13 +670,12 @@ TEST(ProcessSignalFormatterTest, NoProcessArguments) { config.SetDisableProcessArguments(true); ProcessSignalFormatter processSignalFormatter(inspector.get(), config); - auto tinfo = inspector->build_threadinfo(); + auto tinfo = inspector->get_threadinfo_factory().create(); tinfo->m_pid = 3; tinfo->m_tid = 3; tinfo->m_ptid = -1; tinfo->m_vpid = 0; - tinfo->m_user.set_uid(42); - tinfo->m_container_id = ""; + tinfo->m_uid = 42; tinfo->m_exepath = "qwerty"; std::vector args = {std::string("args")}; diff --git a/collector/test/SystemInspectorServiceTest.cpp b/collector/test/SystemInspectorServiceTest.cpp index a6ed01e2e1..a02ccab23c 100644 --- a/collector/test/SystemInspectorServiceTest.cpp +++ b/collector/test/SystemInspectorServiceTest.cpp @@ -7,32 +7,33 @@ namespace collector::system_inspector { TEST(SystemInspectorServiceTest, FilterEvent) { std::unique_ptr inspector(new sinsp()); + const auto& factory = inspector->get_threadinfo_factory(); - sinsp_threadinfo regular_process(inspector.get()); - regular_process.m_exepath = "/bin/busybox"; - regular_process.m_comm = "sleep"; + auto regular_process = factory.create(); + regular_process->m_exepath = "/bin/busybox"; + regular_process->m_comm = "sleep"; - sinsp_threadinfo runc_process(inspector.get()); - runc_process.m_exepath = "runc"; - runc_process.m_comm = "6"; + auto runc_process = factory.create(); + runc_process->m_exepath = "runc"; + runc_process->m_comm = "6"; - sinsp_threadinfo proc_self_process(inspector.get()); - proc_self_process.m_exepath = "/proc/self/exe"; - proc_self_process.m_comm = "6"; + auto proc_self_process = factory.create(); + proc_self_process->m_exepath = "/proc/self/exe"; + proc_self_process->m_comm = "6"; - sinsp_threadinfo memfd_process(inspector.get()); - memfd_process.m_exepath = "memfd:runc_cloned:/proc/self/exe"; - memfd_process.m_comm = "6"; + auto memfd_process = factory.create(); + memfd_process->m_exepath = "memfd:runc_cloned:/proc/self/exe"; + memfd_process->m_comm = "6"; struct test_t { const sinsp_threadinfo* tinfo; bool expected; }; std::vector tests{ - {®ular_process, true}, - {&runc_process, false}, - {&proc_self_process, false}, - {&memfd_process, false}, + {regular_process.get(), true}, + {runc_process.get(), false}, + {proc_self_process.get(), false}, + {memfd_process.get(), false}, }; for (const auto& t : tests) { diff --git a/collector/test/UtilityTest.cpp b/collector/test/UtilityTest.cpp index f5dee2b865..14df61f69c 100644 --- a/collector/test/UtilityTest.cpp +++ b/collector/test/UtilityTest.cpp @@ -98,6 +98,11 @@ TEST(ExtractContainerIDFromCgroupTest, TestExtractContainerIDFromCgroup) { "/machine.slice/libpod-cbdfa0f1f08763b1963c30d98e11e1f052cb67f1e9b7c0ab8a6ca6c70cbcad69.scope/container/kubelet.slice/kubelet-kubepods.slice/kubelet-kubepods-besteffort.slice/kubelet-kubepods-besteffort-pod6eab3b7b_f0a6_4bb8_bff2_d5bc9017c04b.slice/cri-containerd-5ebf11e02dbde102cda4b76bc0e3849a65f9edac7a12bdabfd34db01b9556101.scope", "5ebf11e02dbd", }, + // containerd without SystemdCgroup (uses : separator) + { + "/kubepods-burstable-podbd12dd3393227d950605a2444b13c27a.slice:cri-containerd:d52db56a9c80d536a91354c0951c061187ca46249e64865a12703003d8f42366", + "d52db56a9c80", + }, // conmon { "/machine.slice/libpod-conmon-b6ce30d02945df4bbf8e8b7193b2c56ebb3cd10227dd7e59d7f7cdc2cfa2a307.scope", diff --git a/falcosecurity-libs b/falcosecurity-libs index af2b6161c6..fa52e66a3d 160000 --- a/falcosecurity-libs +++ b/falcosecurity-libs @@ -1 +1 @@ -Subproject commit af2b6161c6060ff47b843d9ff129b9de2ed03a35 +Subproject commit fa52e66a3dbb7de30716179e251497fb63fabb9e diff --git a/integration-tests/suites/k8s/namespace.go b/integration-tests/suites/k8s/namespace.go index 5b94df3a5e..7e0433dd6b 100644 --- a/integration-tests/suites/k8s/namespace.go +++ b/integration-tests/suites/k8s/namespace.go @@ -47,7 +47,7 @@ func (k *K8sNamespaceTestSuite) SetupSuite() { k.tests = append(k.tests, NamespaceTest{ containerID: k.Collector().ContainerID(), - expectecNamespace: collector.TEST_NAMESPACE, + expectecNamespace: "", }) k.createTargetNamespace() @@ -55,7 +55,7 @@ func (k *K8sNamespaceTestSuite) SetupSuite() { k.Require().Len(nginxID, 12) k.tests = append(k.tests, NamespaceTest{ containerID: nginxID, - expectecNamespace: NAMESPACE, + expectecNamespace: "", }) } diff --git a/integration-tests/suites/udp_networkflow.go b/integration-tests/suites/udp_networkflow.go index 9045e7466f..1aefea184a 100644 --- a/integration-tests/suites/udp_networkflow.go +++ b/integration-tests/suites/udp_networkflow.go @@ -138,8 +138,8 @@ func (s *UdpNetworkFlow) runTest(image, recv, send string, port uint32) { CloseTimestamp: nil, } - s.Sensor().ExpectConnections(s.T(), client.id, 5*time.Second, clientConnection) - s.Sensor().ExpectConnections(s.T(), server.id, 5*time.Second, serverConnection) + s.Sensor().ExpectConnections(s.T(), client.id, 30*time.Second, clientConnection) + s.Sensor().ExpectConnections(s.T(), server.id, 30*time.Second, serverConnection) } func (s *UdpNetworkFlow) TestMultipleDestinations() { @@ -164,7 +164,7 @@ func (s *UdpNetworkFlow) TestMultipleDestinations() { client := s.runClient(config.ContainerStartConfig{ Name: UDP_CLIENT, Image: image, - Command: newClientCmd("sendmmsg", "300", "8", servers...), + Command: newClientCmd("sendmmsg", "300", "4", servers...), Entrypoint: []string{"udp-client"}, }) log.Info("Client: %s\n", client.String()) @@ -192,9 +192,9 @@ func (s *UdpNetworkFlow) TestMultipleDestinations() { ContainerId: server.id, CloseTimestamp: nil, } - s.Sensor().ExpectConnections(s.T(), server.id, 5*time.Second, serverConnection) + s.Sensor().ExpectConnections(s.T(), server.id, 30*time.Second, serverConnection) } - s.Sensor().ExpectConnections(s.T(), client.id, 5*time.Second, clientConnections...) + s.Sensor().ExpectConnections(s.T(), client.id, 30*time.Second, clientConnections...) } func (s *UdpNetworkFlow) TestMultipleSources() { @@ -243,9 +243,9 @@ func (s *UdpNetworkFlow) TestMultipleSources() { } for i, client := range clients { - s.Sensor().ExpectConnections(s.T(), client.id, 5*time.Second, clientConnections[i]) + s.Sensor().ExpectConnections(s.T(), client.id, 30*time.Second, clientConnections[i]) } - s.Sensor().ExpectConnections(s.T(), server.id, 5*time.Second, serverConnections...) + s.Sensor().ExpectConnections(s.T(), server.id, 30*time.Second, serverConnections...) } func newServerCmd(recv string, port uint32) []string { From eeb72d2ea58e9ee25b9fa4705cf60d71e5326ee2 Mon Sep 17 00:00:00 2001 From: Giles Hutton Date: Thu, 4 Jun 2026 15:56:16 +0100 Subject: [PATCH 2/4] ROX-33614: bump falco commit --- falcosecurity-libs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/falcosecurity-libs b/falcosecurity-libs index fa52e66a3d..fdb27236a5 160000 --- a/falcosecurity-libs +++ b/falcosecurity-libs @@ -1 +1 @@ -Subproject commit fa52e66a3dbb7de30716179e251497fb63fabb9e +Subproject commit fdb27236a5b589fb2f658cb3453b6e52388eb22c From 6d57248ec86775a1b091b0748c5e1364cd9e0708 Mon Sep 17 00:00:00 2001 From: Giles Hutton Date: Wed, 8 Jul 2026 14:18:30 +0100 Subject: [PATCH 3/4] Address review feedback from Mauro - Use event type constants instead of strncmp for send/recv detection - Revert extract() back to extract_single() (still available in pinned falco) - Change null filter_check guards to asserts (fatal on init failure) - Move default_formatter_ back to initializer list - Remove try/catch around container filter (let exception propagate) - Use GetContainerID helper in Process.cpp instead of inline cgroup loop - Restore container ID in operator<< and debug log output --- collector/lib/NetworkSignalHandler.cpp | 7 ++- collector/lib/Process.cpp | 7 ++- collector/lib/ProcessSignalFormatter.cpp | 4 +- collector/lib/Utility.cpp | 4 +- collector/lib/Utility.h | 2 +- .../lib/system-inspector/EventExtractor.cpp | 3 +- .../lib/system-inspector/EventExtractor.h | 44 +++++++++---------- collector/lib/system-inspector/Service.cpp | 25 +++++------ 8 files changed, 44 insertions(+), 52 deletions(-) diff --git a/collector/lib/NetworkSignalHandler.cpp b/collector/lib/NetworkSignalHandler.cpp index a78c29477f..9adec6cdcb 100644 --- a/collector/lib/NetworkSignalHandler.cpp +++ b/collector/lib/NetworkSignalHandler.cpp @@ -1,6 +1,5 @@ #include "NetworkSignalHandler.h" -#include #include #include @@ -69,7 +68,6 @@ NetworkSignalHandler::~NetworkSignalHandler() = default; * result: nil */ std::optional NetworkSignalHandler::GetConnection(sinsp_evt* evt) { - const char* evt_name = evt->get_name(); auto* fd_info = evt->get_fd_info(); if (!fd_info) { @@ -83,8 +81,9 @@ std::optional NetworkSignalHandler::GetConnection(sinsp_evt* evt) { // "failed" even when subsequent operations succeed, because the sinsp parser // (parse_rw_exit) does not clear the failed flag on successful send/recv. if (collect_connection_status_) { - bool is_send_recv = (strncmp(evt_name, "send", 4) == 0 || - strncmp(evt_name, "recv", 4) == 0); + auto type = evt->get_type(); + bool is_send_recv = (type >= PPME_SOCKET_SENDTO_E && type <= PPME_SOCKET_RECVFROM_X) || + (type >= PPME_SOCKET_SENDMSG_E && type <= PPME_SOCKET_RECVMMSG_X); if (!is_send_recv) { if (fd_info->is_socket_failed()) { return std::nullopt; diff --git a/collector/lib/Process.cpp b/collector/lib/Process.cpp index 7054257f02..4f6a305b51 100644 --- a/collector/lib/Process.cpp +++ b/collector/lib/Process.cpp @@ -33,10 +33,9 @@ std::string Process::container_id() const { WaitForProcessInfo(); if (system_inspector_threadinfo_) { - for (const auto& [subsys, cgroup_path] : system_inspector_threadinfo_->cgroups()) { - if (auto id = ExtractContainerIDFromCgroup(cgroup_path)) { - return std::string(*id); - } + auto id = GetContainerID(*system_inspector_threadinfo_); + if (!id.empty()) { + return id; } } diff --git a/collector/lib/ProcessSignalFormatter.cpp b/collector/lib/ProcessSignalFormatter.cpp index 6420c8da3e..4be9ca56c7 100644 --- a/collector/lib/ProcessSignalFormatter.cpp +++ b/collector/lib/ProcessSignalFormatter.cpp @@ -193,7 +193,7 @@ ProcessSignal* ProcessSignalFormatter::CreateProcessSignal(sinsp_evt* event) { } CLOG(DEBUG) << "Process (" << signal->container_id() << ": " << signal->pid() << "): " - << signal->name() + << signal->name() << "[" << container_id << "]" << " (" << signal->exec_file_path() << ")" << " " << signal->args(); @@ -257,7 +257,7 @@ ProcessSignal* ProcessSignalFormatter::CreateProcessSignal(sinsp_threadinfo* tin } CLOG(DEBUG) << "Process (" << signal->container_id() << ": " << signal->pid() << "): " - << signal->name() + << signal->name() << "[" << signal->container_id() << "]" << " (" << signal->exec_file_path() << ")" << " " << signal->args(); diff --git a/collector/lib/Utility.cpp b/collector/lib/Utility.cpp index f1c74f09d0..20e021d99e 100644 --- a/collector/lib/Utility.cpp +++ b/collector/lib/Utility.cpp @@ -57,7 +57,7 @@ const char* SignalName(int signum) { } } -std::string GetContainerID(sinsp_threadinfo& tinfo) { +std::string GetContainerID(const sinsp_threadinfo& tinfo) { for (const auto& [subsys, cgroup_path] : tinfo.cgroups()) { if (auto id = ExtractContainerIDFromCgroup(cgroup_path)) { return std::string(*id); @@ -79,7 +79,7 @@ std::string GetContainerID(sinsp_evt* event) { std::ostream& operator<<(std::ostream& os, const sinsp_threadinfo* t) { if (t) { - os << "Name: " << t->m_comm << ", PID: " << t->m_pid << ", Args: " << t->m_exe; + os << "Container: \"" << GetContainerID(*t) << "\", Name: " << t->m_comm << ", PID: " << t->m_pid << ", Args: " << t->m_exe; } else { os << "NULL\n"; } diff --git a/collector/lib/Utility.h b/collector/lib/Utility.h index e15869b31b..f9ba73126b 100644 --- a/collector/lib/Utility.h +++ b/collector/lib/Utility.h @@ -68,7 +68,7 @@ std::ostream& operator<<(std::ostream& os, const sinsp_threadinfo* t); // Extract container ID from a threadinfo's cgroups. // Returns an empty string if no container ID found. -std::string GetContainerID(sinsp_threadinfo& tinfo); +std::string GetContainerID(const sinsp_threadinfo& tinfo); // Extract container ID from an event's thread info cgroups. // Returns an empty string if no container ID found. diff --git a/collector/lib/system-inspector/EventExtractor.cpp b/collector/lib/system-inspector/EventExtractor.cpp index 82e1ea94ca..c74b877c01 100644 --- a/collector/lib/system-inspector/EventExtractor.cpp +++ b/collector/lib/system-inspector/EventExtractor.cpp @@ -6,8 +6,7 @@ void EventExtractor::Init(sinsp* inspector) { for (auto* wrapper : wrappers_) { std::unique_ptr check = FilterList().new_filter_check_from_fldname(wrapper->event_name, inspector, true); if (!check) { - CLOG(WARNING) << "Filter check not available for field: " << wrapper->event_name; - continue; + CLOG(FATAL) << "Filter check not available for field: " << wrapper->event_name; } check->parse_field_name(wrapper->event_name, true, false); wrapper->filter_check.reset(check.release()); diff --git a/collector/lib/system-inspector/EventExtractor.h b/collector/lib/system-inspector/EventExtractor.h index ef58d899fb..a1c1ecd2c5 100644 --- a/collector/lib/system-inspector/EventExtractor.h +++ b/collector/lib/system-inspector/EventExtractor.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -41,12 +42,10 @@ class EventExtractor { #define FIELD_RAW(id, fieldname, type) \ public: \ const type* get_##id(sinsp_evt* event) { \ - if (!filter_check_##id##_.filter_check) return nullptr; \ - std::vector vals_##id; \ - if (!filter_check_##id##_->extract(event, vals_##id)) return nullptr; \ - if (vals_##id.empty()) return nullptr; \ - auto len = vals_##id[0].len; \ - auto buf = vals_##id[0].ptr; \ + assert(filter_check_##id##_.filter_check && "filter check not initialized for " fieldname); \ + uint32_t len; \ + auto buf = filter_check_##id##_->extract_single(event, &len); \ + if (!buf) return nullptr; \ if (len != sizeof(type)) { \ CLOG_THROTTLED(WARNING, std::chrono::seconds(30)) \ << "Failed to extract value for field " << fieldname << ": expected type " << #type << " (size " \ @@ -66,12 +65,10 @@ class EventExtractor { const std::optional get_##id(sinsp_evt* event) { \ static_assert(std::is_trivially_copyable_v, \ "Attempted to create FIELD_RAW_SAFE on non trivial type"); \ - if (!filter_check_##id##_.filter_check) return {}; \ - std::vector vals_##id; \ - if (!filter_check_##id##_->extract(event, vals_##id)) return {}; \ - if (vals_##id.empty()) return {}; \ - auto len = vals_##id[0].len; \ - auto buf = vals_##id[0].ptr; \ + assert(filter_check_##id##_.filter_check && "filter check not initialized for " fieldname); \ + uint32_t len; \ + auto buf = filter_check_##id##_->extract_single(event, &len); \ + if (!buf) return {}; \ if (len != sizeof(type)) { \ CLOG_THROTTLED(WARNING, std::chrono::seconds(30)) \ << "Failed to extract value for field " << fieldname << ": expected type " << #type << " (size " \ @@ -86,17 +83,18 @@ class EventExtractor { private: \ DECLARE_FILTER_CHECK(id, fieldname) -#define FIELD_CSTR(id, fieldname) \ - public: \ - const char* get_##id(sinsp_evt* event) { \ - if (!filter_check_##id##_.filter_check) return nullptr; \ - std::vector vals_##id; \ - if (!filter_check_##id##_->extract(event, vals_##id)) return nullptr; \ - if (vals_##id.empty()) return nullptr; \ - return reinterpret_cast(vals_##id[0].ptr); \ - } \ - \ - private: \ +#define FIELD_CSTR(id, fieldname) \ + public: \ + const char* get_##id(sinsp_evt* event) { \ + assert(filter_check_##id##_.filter_check \ + && "filter check not initialized for " fieldname); \ + uint32_t len; \ + auto buf = filter_check_##id##_->extract_single(event, &len); \ + if (!buf) return nullptr; \ + return reinterpret_cast(buf); \ + } \ + \ + private: \ DECLARE_FILTER_CHECK(id, fieldname) #define EVT_ARG(name) FIELD_CSTR(evt_arg_##name, "evt.arg." #name) diff --git a/collector/lib/system-inspector/Service.cpp b/collector/lib/system-inspector/Service.cpp index de9d59ba7b..ca8815803e 100644 --- a/collector/lib/system-inspector/Service.cpp +++ b/collector/lib/system-inspector/Service.cpp @@ -33,7 +33,11 @@ namespace collector::system_inspector { Service::~Service() = default; Service::Service(const CollectorConfig& config) - : inspector_(std::make_unique(true)) { + : inspector_(std::make_unique(true)), + default_formatter_(std::make_unique( + inspector_.get(), + DEFAULT_OUTPUT_STR, + EventExtractor::FilterList())) { // Setup the inspector. // peeking into arguments has a big overhead, so we prevent it from happening inspector_->set_snaplen(0); @@ -55,21 +59,14 @@ Service::Service(const CollectorConfig& config) inspector_->get_parser()->set_track_connection_status(true); } - default_formatter_ = std::make_unique( - inspector_.get(), DEFAULT_OUTPUT_STR, EventExtractor::FilterList()); - // Filter out host processes. In containers, pid != vpid due to PID // namespacing. This is a built-in sinsp field that doesn't require - // any plugin. - try { - auto factory = std::make_shared( - inspector_.get(), EventExtractor::FilterList()); - sinsp_filter_compiler compiler(factory, "proc.pid != proc.vpid"); - inspector_->set_filter(compiler.compile(), "proc.pid != proc.vpid"); - } catch (const sinsp_exception& e) { - CLOG(WARNING) << "Could not set container filter: " << e.what() - << ". Container filtering will not be active."; - } + // any plugin. If this fails, we let the exception propagate rather + // than silently processing all host events. + auto factory = std::make_shared( + inspector_.get(), EventExtractor::FilterList()); + sinsp_filter_compiler compiler(factory, "proc.pid != proc.vpid"); + inspector_->set_filter(compiler.compile(), "proc.pid != proc.vpid"); // The self-check handlers should only operate during start up, // so they are added to the handler list first, so they have access From edfb34dbbac41ca875c904d2aaf129bb78f2217c Mon Sep 17 00:00:00 2001 From: Giles Hutton Date: Fri, 10 Jul 2026 10:35:00 +0100 Subject: [PATCH 4/4] Fix sinsp filter syntax and clang-format The sinsp filter parser treats the RHS of '!=' as a bare string value, not a field reference. Using val(proc.vpid) tells the parser to resolve proc.vpid as a field extraction at runtime, enabling the field-to-field comparison needed to filter host processes. Also fix clang-format alignment on the FIELD_CSTR macro. --- .../lib/system-inspector/EventExtractor.h | 23 +++++++++---------- collector/lib/system-inspector/Service.cpp | 9 ++++---- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/collector/lib/system-inspector/EventExtractor.h b/collector/lib/system-inspector/EventExtractor.h index a1c1ecd2c5..961d429a00 100644 --- a/collector/lib/system-inspector/EventExtractor.h +++ b/collector/lib/system-inspector/EventExtractor.h @@ -83,18 +83,17 @@ class EventExtractor { private: \ DECLARE_FILTER_CHECK(id, fieldname) -#define FIELD_CSTR(id, fieldname) \ - public: \ - const char* get_##id(sinsp_evt* event) { \ - assert(filter_check_##id##_.filter_check \ - && "filter check not initialized for " fieldname); \ - uint32_t len; \ - auto buf = filter_check_##id##_->extract_single(event, &len); \ - if (!buf) return nullptr; \ - return reinterpret_cast(buf); \ - } \ - \ - private: \ +#define FIELD_CSTR(id, fieldname) \ + public: \ + const char* get_##id(sinsp_evt* event) { \ + assert(filter_check_##id##_.filter_check && "filter check not initialized for " fieldname); \ + uint32_t len; \ + auto buf = filter_check_##id##_->extract_single(event, &len); \ + if (!buf) return nullptr; \ + return reinterpret_cast(buf); \ + } \ + \ + private: \ DECLARE_FILTER_CHECK(id, fieldname) #define EVT_ARG(name) FIELD_CSTR(evt_arg_##name, "evt.arg." #name) diff --git a/collector/lib/system-inspector/Service.cpp b/collector/lib/system-inspector/Service.cpp index ca8815803e..5b1def096d 100644 --- a/collector/lib/system-inspector/Service.cpp +++ b/collector/lib/system-inspector/Service.cpp @@ -60,13 +60,12 @@ Service::Service(const CollectorConfig& config) } // Filter out host processes. In containers, pid != vpid due to PID - // namespacing. This is a built-in sinsp field that doesn't require - // any plugin. If this fails, we let the exception propagate rather - // than silently processing all host events. + // namespacing. The val() transformer is required so the parser treats + // proc.vpid as a field reference rather than a bare string value. auto factory = std::make_shared( inspector_.get(), EventExtractor::FilterList()); - sinsp_filter_compiler compiler(factory, "proc.pid != proc.vpid"); - inspector_->set_filter(compiler.compile(), "proc.pid != proc.vpid"); + sinsp_filter_compiler compiler(factory, "proc.pid != val(proc.vpid)"); + inspector_->set_filter(compiler.compile(), "proc.pid != val(proc.vpid)"); // The self-check handlers should only operate during start up, // so they are added to the handler list first, so they have access