diff --git a/src/matchers/containerd.cpp b/src/matchers/containerd.cpp index c76f4b6..5b0e6e3 100644 --- a/src/matchers/containerd.cpp +++ b/src/matchers/containerd.cpp @@ -6,7 +6,7 @@ using namespace libsinsp::runc; -static re2::RE2 pattern("^/([A-Za-z0-9]+(?:[._-](?:[A-Za-z0-9]+))*)/$", re2::RE2::POSIX); +static re2::RE2 pattern("/([A-Za-z0-9]+(?:[._-](?:[A-Za-z0-9]+))*)/"); bool containerd::resolve(const std::string& cgroup, std::string& container_id) { std::string containerd_namespace; @@ -20,7 +20,7 @@ bool containerd::resolve(const std::string& cgroup, std::string& container_id) { out << "/" << containerd_namespace << "/"; auto layout_str = out.str(); cgroup_layout CONTAINERD_CGROUP_LAYOUT[] = {{layout_str.c_str(), ""}, {nullptr, nullptr}}; - return matches_runc_cgroup(cgroup, CONTAINERD_CGROUP_LAYOUT, container_id); + return matches_runc_cgroup(cgroup, CONTAINERD_CGROUP_LAYOUT, container_id, true); } return false; } \ No newline at end of file diff --git a/src/matchers/runc.cpp b/src/matchers/runc.cpp index a46d680..77556b6 100644 --- a/src/matchers/runc.cpp +++ b/src/matchers/runc.cpp @@ -3,6 +3,7 @@ namespace { const size_t CONTAINER_ID_LENGTH = 64; const size_t REPORTED_CONTAINER_ID_LENGTH = 12; +const char *CONTAINER_ID_VALID_CHARACTERS = "0123456789abcdefABCDEF"; static_assert(REPORTED_CONTAINER_ID_LENGTH <= CONTAINER_ID_LENGTH, "Reported container ID length cannot be longer than actual length"); @@ -16,28 +17,14 @@ inline static bool endswith(const std::string &s, const std::string &suffix) { return s.rfind(suffix) == (s.size() - suffix.size()); } -inline static bool is_host(const std::string &cgroup) { - // A good approximation to minize false-positives is to exclude systemd suffixes. - if(endswith(cgroup, ".slice") || endswith(cgroup, ".service")) { - return true; - } else if(endswith(cgroup, ".scope")) { - if(cgroup.find("crio-") != std::string::npos || - cgroup.find("docker-") != std::string::npos) { - return false; - } - return true; - } - - return false; -} - // check if cgroup ends with // If true, set to a truncated version of the id and return true. // Otherwise return false and leave container_id unchanged bool match_one_container_id(const std::string &cgroup, const std::string &prefix, const std::string &suffix, - std::string &container_id) { + std::string &container_id, + bool is_containerd) { size_t start_pos = cgroup.rfind(prefix); if(start_pos == std::string::npos) { return false; @@ -49,29 +36,38 @@ bool match_one_container_id(const std::string &cgroup, return false; } - // In some container runtimes the container id is not + if(end_pos - start_pos == CONTAINER_ID_LENGTH && + cgroup.find_first_not_of(CONTAINER_ID_VALID_CHARACTERS, start_pos) >= CONTAINER_ID_LENGTH) { + container_id = cgroup.substr(start_pos, REPORTED_CONTAINER_ID_LENGTH); + return true; + } + + // In some container runtimes the container the container id is not // necessarly CONTAINER_ID_LENGTH long and can be arbitrarly defined. // To keep it simple we only discard the container id > of CONTAINER_ID_LENGTH. if(end_pos - start_pos > CONTAINER_ID_LENGTH || end_pos - start_pos == 0) { return false; } - if(is_host(cgroup)) { - return false; + // For containerd, make sure to skip systemd host cgroups + if(is_containerd && !endswith(cgroup, ".service") && + !endswith(cgroup, ".slice")) { + const size_t reported_len = end_pos - start_pos >= REPORTED_CONTAINER_ID_LENGTH + ? REPORTED_CONTAINER_ID_LENGTH + : end_pos - start_pos; + container_id = cgroup.substr(start_pos, reported_len); + return true; } - size_t reported_len = end_pos - start_pos >= REPORTED_CONTAINER_ID_LENGTH - ? REPORTED_CONTAINER_ID_LENGTH - : end_pos; - container_id = cgroup.substr(start_pos, reported_len); - return true; + return false; } bool matches_runc_cgroup(const std::string &cgroup, const libsinsp::runc::cgroup_layout *layout, - std::string &container_id) { + std::string &container_id, + bool is_containerd) { for(size_t i = 0; layout[i].prefix && layout[i].suffix; ++i) { - if(match_one_container_id(cgroup, layout[i].prefix, layout[i].suffix, container_id)) { + if(match_one_container_id(cgroup, layout[i].prefix, layout[i].suffix, container_id, is_containerd)) { return true; } } diff --git a/src/matchers/runc.h b/src/matchers/runc.h index d7ede7a..d1240bd 100644 --- a/src/matchers/runc.h +++ b/src/matchers/runc.h @@ -52,6 +52,7 @@ bool match_one_container_id(const std::string &cgroup, */ bool matches_runc_cgroup(const std::string &cgroup, const libsinsp::runc::cgroup_layout *layout, - std::string &container_id); + std::string &container_id, + bool is_containerd=false); } // namespace runc } // namespace libsinsp