From c9f9e1451728a438a714e08602c6857923651233 Mon Sep 17 00:00:00 2001 From: Roberto Scolaro Date: Tue, 7 Jan 2025 21:56:46 +0000 Subject: [PATCH] refactor(libsinsp): move transformers in differnt files Signed-off-by: Roberto Scolaro --- userspace/libsinsp/CMakeLists.txt | 8 +- .../libsinsp/sinsp_filter_transformer.cpp | 349 ------------------ .../libsinsp/sinsp_filter_transformers.h | 57 +++ .../sinsp_filter_transformer.cpp | 60 +++ .../sinsp_filter_transformer.h | 66 +--- .../sinsp_filter_transformer_base64.cpp | 43 +++ .../sinsp_filter_transformer_base64.h | 26 ++ .../sinsp_filter_transformer_basename.cpp | 51 +++ .../sinsp_filter_transformer_basename.h | 26 ++ .../sinsp_filter_transformer_len.cpp | 100 +++++ .../sinsp_filter_transformer_len.h | 26 ++ .../sinsp_filter_transformer_storage.cpp | 47 +++ .../sinsp_filter_transformer_storage.h | 26 ++ .../sinsp_filter_transformer_tolower.cpp | 46 +++ .../sinsp_filter_transformer_tolower.h | 26 ++ .../sinsp_filter_transformer_toupper.cpp | 46 +++ .../sinsp_filter_transformer_toupper.h | 26 ++ userspace/libsinsp/sinsp_filtercheck.cpp | 2 +- userspace/libsinsp/sinsp_filtercheck.h | 2 +- .../libsinsp/test/filter_transformer.ut.cpp | 17 +- 20 files changed, 635 insertions(+), 415 deletions(-) delete mode 100644 userspace/libsinsp/sinsp_filter_transformer.cpp create mode 100644 userspace/libsinsp/sinsp_filter_transformers.h create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer.cpp rename userspace/libsinsp/{ => sinsp_filter_transformers}/sinsp_filter_transformer.h (59%) create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_base64.cpp create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_base64.h create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_basename.cpp create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_basename.h create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_len.cpp create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_len.h create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_storage.cpp create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_storage.h create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_tolower.cpp create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_tolower.h create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_toupper.cpp create mode 100644 userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_toupper.h diff --git a/userspace/libsinsp/CMakeLists.txt b/userspace/libsinsp/CMakeLists.txt index ccfcce0ef8..35e1d1a450 100644 --- a/userspace/libsinsp/CMakeLists.txt +++ b/userspace/libsinsp/CMakeLists.txt @@ -66,7 +66,13 @@ add_library( dumper.cpp fdinfo.cpp filter.cpp - sinsp_filter_transformer.cpp + sinsp_filter_transformers/sinsp_filter_transformer.cpp + sinsp_filter_transformers/sinsp_filter_transformer_base64.cpp + sinsp_filter_transformers/sinsp_filter_transformer_basename.cpp + sinsp_filter_transformers/sinsp_filter_transformer_len.cpp + sinsp_filter_transformers/sinsp_filter_transformer_storage.cpp + sinsp_filter_transformers/sinsp_filter_transformer_tolower.cpp + sinsp_filter_transformers/sinsp_filter_transformer_toupper.cpp sinsp_filtercheck.cpp sinsp_filtercheck_container.cpp sinsp_filtercheck_event.cpp diff --git a/userspace/libsinsp/sinsp_filter_transformer.cpp b/userspace/libsinsp/sinsp_filter_transformer.cpp deleted file mode 100644 index 7faca9239b..0000000000 --- a/userspace/libsinsp/sinsp_filter_transformer.cpp +++ /dev/null @@ -1,349 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* -Copyright (C) 2024 The Falco Authors. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include - -static void throw_unsupported_err(filter_transformer_type t) { - throw sinsp_exception("transformer '" + std::to_string(t) + "' is not supported"); -} - -static void throw_type_incompatibility_err(ppm_param_type t, const std::string& trname) { - throw sinsp_exception("field type '" + std::to_string(t) + "' is not supported by '" + trname + - "' transformer"); -} - -// base class -sinsp_filter_transformer::~sinsp_filter_transformer() {} - -bool sinsp_filter_transformer::transform_type(ppm_param_type& t, uint32_t& flags) const { - throw_unsupported_err(m_type); - return false; -} - -bool sinsp_filter_transformer::string_transformer(std::vector& vec, - ppm_param_type t, - str_transformer_func_t f) { - m_storage_values.resize(vec.size()); - for(std::size_t i = 0; i < vec.size(); i++) { - storage_t& buf = m_storage_values[i]; - - buf.clear(); - if(vec[i].ptr == nullptr) { - continue; - } - - // we don't know whether this will come as a string or a byte buf, - // so we sanitize by skipping all terminator characters - size_t in_len = vec[i].len; - while(in_len > 0 && vec[i].ptr[in_len - 1] == '\0') { - in_len--; - } - - // each function can assume that the input size does NOT include - // the terminator character, and should not assume that the string - // is null-terminated - std::string_view in{(const char*)vec[i].ptr, in_len}; - if(!f(in, buf)) { - return false; - } - - // we insert a null terminator in case we miss one, just to stay safe - if(buf.size() == 0 || buf[buf.size() - 1] != '\0') { - buf.push_back('\0'); - } - - vec[i].ptr = (uint8_t*)&buf[0]; - vec[i].len = buf.size(); - } - return true; -} - -// toupper -sinsp_filter_transformer_toupper::sinsp_filter_transformer_toupper() { - m_type = FTR_TOUPPER; -}; - -bool sinsp_filter_transformer_toupper::transform_type(ppm_param_type& t, uint32_t& flags) const { - switch(t) { - case PT_CHARBUF: - case PT_FSPATH: - case PT_FSRELPATH: - // for TOUPPER, the transformed type is the same as the input type - return true; - default: - return false; - } -} - -bool sinsp_filter_transformer_toupper::transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) { - if(!transform_type(t, flags)) { - throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); - } - - return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { - for(auto c : in) { - out.push_back(toupper(c)); - } - return true; - }); -} - -// tolower -sinsp_filter_transformer_tolower::sinsp_filter_transformer_tolower() { - m_type = FTR_TOLOWER; -}; - -bool sinsp_filter_transformer_tolower::transform_type(ppm_param_type& t, uint32_t& flags) const { - switch(t) { - case PT_CHARBUF: - case PT_FSPATH: - case PT_FSRELPATH: - // for TOLOWER, the transformed type is the same as the input type - return true; - default: - return false; - } -} - -bool sinsp_filter_transformer_tolower::transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) { - if(!transform_type(t, flags)) { - throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); - } - - return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { - for(auto c : in) { - out.push_back(tolower(c)); - } - return true; - }); -} - -// base64 -sinsp_filter_transformer_base64::sinsp_filter_transformer_base64() { - m_type = FTR_BASE64; -} - -bool sinsp_filter_transformer_base64::transform_type(ppm_param_type& t, uint32_t& flags) const { - switch(t) { - case PT_CHARBUF: - case PT_BYTEBUF: - // for BASE64, the transformed type is the same as the input type - return true; - default: - return false; - } -} - -bool sinsp_filter_transformer_base64::transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) { - if(!transform_type(t, flags)) { - throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); - } - - return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { - return Base64::decodeWithoutPadding(in, out); - }); -} - -// storage -sinsp_filter_transformer_storage::sinsp_filter_transformer_storage() { - m_type = FTR_STORAGE; -}; - -bool sinsp_filter_transformer_storage::transform_type(ppm_param_type& t, uint32_t& flags) const { - return true; -} - -bool sinsp_filter_transformer_storage::transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) { - // note: for STORAGE, the transformed type is the same as the input type - m_storage_values.resize(vec.size()); - for(std::size_t i = 0; i < vec.size(); i++) { - storage_t& buf = m_storage_values[i]; - - buf.clear(); - if(vec[i].ptr == nullptr) { - continue; - } - - // We reserve one extra chat for the null terminator - buf.resize(vec[i].len + 1); - memcpy(&(buf[0]), vec[i].ptr, vec[i].len); - // We put the string terminator in any case - buf[vec[i].len] = '\0'; - vec[i].ptr = &(buf[0]); - // `vec[i].len` is the same as before - } - return true; -} - -// basename -sinsp_filter_transformer_basename::sinsp_filter_transformer_basename() { - m_type = FTR_BASENAME; -}; - -bool sinsp_filter_transformer_basename::transform_type(ppm_param_type& t, uint32_t& flags) const { - switch(t) { - case PT_CHARBUF: - case PT_FSPATH: - case PT_FSRELPATH: - // for BASENAME, the transformed type is the same as the input type - return true; - default: - return false; - } -} - -bool sinsp_filter_transformer_basename::transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) { - if(!transform_type(t, flags)) { - throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); - } - - return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { - auto last_slash_pos = in.find_last_of("/"); - std::string_view::size_type start_idx = - last_slash_pos == std::string_view::npos ? 0 : last_slash_pos + 1; - - for(std::string_view::size_type i = start_idx; i < in.length(); i++) { - out.push_back(in[i]); - } - - return true; - }); -} - -// len -sinsp_filter_transformer_len::sinsp_filter_transformer_len() { - m_type = FTR_LEN; -}; - -bool sinsp_filter_transformer_len::transform_type(ppm_param_type& t, uint32_t& flags) const { - bool is_list = flags & EPF_IS_LIST; - if(is_list) { - t = PT_UINT64; - flags = flags & ~EPF_IS_LIST; - return true; - } - switch(t) { - case PT_CHARBUF: - case PT_BYTEBUF: - case PT_FSPATH: - case PT_FSRELPATH: - t = PT_UINT64; - return true; - default: - return false; - } -} - -bool sinsp_filter_transformer_len::transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) { - bool is_list = flags & EPF_IS_LIST; - ppm_param_type original_type = t; - if(!transform_type(t, flags)) { - throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); - } - - assert((void("len() type must be PT_UINT64"), t == PT_UINT64)); - m_storage_values.clear(); - if(is_list) { - uint64_t len = static_cast(vec.size()); - auto stored_val = store_scalar(len); - vec.clear(); - vec.push_back(stored_val); - return true; - } - - // not a list: could be string or buffer - bool is_string = false; - switch(original_type) { - case PT_CHARBUF: - case PT_FSPATH: - case PT_FSRELPATH: - is_string = true; - break; - case PT_BYTEBUF: - is_string = false; - break; - default: - return false; - } - - if(vec.size() == 0) { - // should never happen since there is no way to - // call len() with no arguments - return false; - } - - // we are assuming that if this is not a list then it's a single element - assert((void("non-list elements to transform with len() must be a vector with a single " - "element"), - vec.size() == 1)); - uint64_t len; - if(vec[0].ptr == nullptr) { - vec[0] = store_scalar(0); - return true; - } - - if(is_string) { - len = static_cast(strnlen(reinterpret_cast(vec[0].ptr), vec[0].len)); - vec[0] = store_scalar(len); - return true; - } - - // buffer - len = static_cast(vec[0].len); - vec[0] = store_scalar(len); - return true; -} - -std::unique_ptr sinsp_filter_transformer::create_transformer( - filter_transformer_type trtype) { - switch(trtype) { - case FTR_TOUPPER: { - return std::make_unique(); - } - case FTR_TOLOWER: { - return std::make_unique(); - } - case FTR_BASE64: { - return std::make_unique(); - } - case FTR_STORAGE: { - // for STORAGE, the transformed type is the same as the input type - // return true; - return std::make_unique(); - } - case FTR_BASENAME: { - return std::make_unique(); - } - case FTR_LEN: { - return std::make_unique(); - } - default: - throw_unsupported_err(trtype); - return nullptr; - } -} diff --git a/userspace/libsinsp/sinsp_filter_transformers.h b/userspace/libsinsp/sinsp_filter_transformers.h new file mode 100644 index 0000000000..6485a33fc3 --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers.h @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2024 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +class sinsp_filter_transformer_factory { +public: + sinsp_filter_transformer_factory() = delete; + ~sinsp_filter_transformer_factory() = delete; + sinsp_filter_transformer_factory operator=(const sinsp_filter_transformer_factory&) = delete; + + static std::unique_ptr create_transformer( + filter_transformer_type trtype) { + switch(trtype) { + case FTR_TOUPPER: { + return std::make_unique(); + } + case FTR_TOLOWER: { + return std::make_unique(); + } + case FTR_BASE64: { + return std::make_unique(); + } + case FTR_STORAGE: { + return std::make_unique(); + } + case FTR_BASENAME: { + return std::make_unique(); + } + case FTR_LEN: { + return std::make_unique(); + } + default: + throw sinsp_exception("transformer '" + std::to_string(trtype) + "' is not supported"); + return nullptr; + } + } +}; diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer.cpp b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer.cpp new file mode 100644 index 0000000000..3169b3488f --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer.cpp @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include + +sinsp_filter_transformer::~sinsp_filter_transformer() {} + +bool sinsp_filter_transformer::transform_type(ppm_param_type& t, uint32_t& flags) const { + throw_unsupported_err(m_type); + return false; +} + +bool sinsp_filter_transformer::string_transformer(std::vector& vec, + ppm_param_type t, + str_transformer_func_t f) { + m_storage_values.resize(vec.size()); + for(std::size_t i = 0; i < vec.size(); i++) { + storage_t& buf = m_storage_values[i]; + + buf.clear(); + if(vec[i].ptr == nullptr) { + continue; + } + + // we don't know whether this will come as a string or a byte buf, + // so we sanitize by skipping all terminator characters + size_t in_len = vec[i].len; + while(in_len > 0 && vec[i].ptr[in_len - 1] == '\0') { + in_len--; + } + + // each function can assume that the input size does NOT include + // the terminator character, and should not assume that the string + // is null-terminated + std::string_view in{(const char*)vec[i].ptr, in_len}; + if(!f(in, buf)) { + return false; + } + + // we insert a null terminator in case we miss one, just to stay safe + if(buf.size() == 0 || buf[buf.size() - 1] != '\0') { + buf.push_back('\0'); + } + + vec[i].ptr = (uint8_t*)&buf[0]; + vec[i].len = buf.size(); + } + return true; +} diff --git a/userspace/libsinsp/sinsp_filter_transformer.h b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer.h similarity index 59% rename from userspace/libsinsp/sinsp_filter_transformer.h rename to userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer.h index 4d72fb6c95..5b7f4abee8 100644 --- a/userspace/libsinsp/sinsp_filter_transformer.h +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer.h @@ -78,9 +78,6 @@ class sinsp_filter_transformer { ppm_param_type& t, uint32_t& flags) = 0; - static std::unique_ptr create_transformer( - filter_transformer_type trtype); - protected: using str_transformer_func_t = std::function; @@ -95,60 +92,15 @@ class sinsp_filter_transformer { return {static_cast(stored_val.data()), static_cast(stored_val.size())}; } - filter_transformer_type m_type; - std::vector m_storage_values; -}; - -class sinsp_filter_transformer_toupper : public sinsp_filter_transformer { -public: - sinsp_filter_transformer_toupper(); - bool transform_type(ppm_param_type& t, uint32_t& flags) const override; - bool transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) override; -}; - -class sinsp_filter_transformer_tolower : public sinsp_filter_transformer { -public: - sinsp_filter_transformer_tolower(); - bool transform_type(ppm_param_type& t, uint32_t& flags) const override; - bool transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) override; -}; - -class sinsp_filter_transformer_base64 : public sinsp_filter_transformer { -public: - sinsp_filter_transformer_base64(); - bool transform_type(ppm_param_type& t, uint32_t& flags) const override; - bool transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) override; -}; - -class sinsp_filter_transformer_storage : public sinsp_filter_transformer { -public: - sinsp_filter_transformer_storage(); - bool transform_type(ppm_param_type& t, uint32_t& flags) const override; - bool transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) override; -}; + void throw_unsupported_err(filter_transformer_type t) const { + throw sinsp_exception("transformer '" + std::to_string(t) + "' is not supported"); + } -class sinsp_filter_transformer_basename : public sinsp_filter_transformer { -public: - sinsp_filter_transformer_basename(); - bool transform_type(ppm_param_type& t, uint32_t& flags) const override; - bool transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) override; -}; + void throw_type_incompatibility_err(ppm_param_type t, const std::string& trname) const { + throw sinsp_exception("field type '" + std::to_string(t) + "' is not supported by '" + + trname + "' transformer"); + } -class sinsp_filter_transformer_len : public sinsp_filter_transformer { -public: - sinsp_filter_transformer_len(); - bool transform_type(ppm_param_type& t, uint32_t& flags) const override; - bool transform_values(std::vector& vec, - ppm_param_type& t, - uint32_t& flags) override; + filter_transformer_type m_type; + std::vector m_storage_values; }; diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_base64.cpp b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_base64.cpp new file mode 100644 index 0000000000..bc5c321630 --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_base64.cpp @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +sinsp_filter_transformer_base64::sinsp_filter_transformer_base64() { + m_type = FTR_BASE64; +} + +bool sinsp_filter_transformer_base64::transform_type(ppm_param_type& t, uint32_t& flags) const { + switch(t) { + case PT_CHARBUF: + case PT_BYTEBUF: + // for BASE64, the transformed type is the same as the input type + return true; + default: + return false; + } +} + +bool sinsp_filter_transformer_base64::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { + if(!transform_type(t, flags)) { + throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); + } + + return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { + return Base64::decodeWithoutPadding(in, out); + }); +} diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_base64.h b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_base64.h new file mode 100644 index 0000000000..eaa8682723 --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_base64.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include + +class sinsp_filter_transformer_base64 : public sinsp_filter_transformer { +public: + sinsp_filter_transformer_base64(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_basename.cpp b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_basename.cpp new file mode 100644 index 0000000000..5cb1db66b7 --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_basename.cpp @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include + +sinsp_filter_transformer_basename::sinsp_filter_transformer_basename() { + m_type = FTR_BASENAME; +}; + +bool sinsp_filter_transformer_basename::transform_type(ppm_param_type& t, uint32_t& flags) const { + switch(t) { + case PT_CHARBUF: + case PT_FSPATH: + case PT_FSRELPATH: + // for BASENAME, the transformed type is the same as the input type + return true; + default: + return false; + } +} + +bool sinsp_filter_transformer_basename::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { + if(!transform_type(t, flags)) { + throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); + } + + return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { + auto last_slash_pos = in.find_last_of("/"); + std::string_view::size_type start_idx = + last_slash_pos == std::string_view::npos ? 0 : last_slash_pos + 1; + + for(std::string_view::size_type i = start_idx; i < in.length(); i++) { + out.push_back(in[i]); + } + + return true; + }); +} diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_basename.h b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_basename.h new file mode 100644 index 0000000000..c27bc96302 --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_basename.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include + +class sinsp_filter_transformer_basename : public sinsp_filter_transformer { +public: + sinsp_filter_transformer_basename(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_len.cpp b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_len.cpp new file mode 100644 index 0000000000..b56216f01e --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_len.cpp @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include + +sinsp_filter_transformer_len::sinsp_filter_transformer_len() { + m_type = FTR_LEN; +}; + +bool sinsp_filter_transformer_len::transform_type(ppm_param_type& t, uint32_t& flags) const { + bool is_list = flags & EPF_IS_LIST; + if(is_list) { + t = PT_UINT64; + flags = flags & ~EPF_IS_LIST; + return true; + } + switch(t) { + case PT_CHARBUF: + case PT_BYTEBUF: + case PT_FSPATH: + case PT_FSRELPATH: + t = PT_UINT64; + return true; + default: + return false; + } +} + +bool sinsp_filter_transformer_len::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { + bool is_list = flags & EPF_IS_LIST; + ppm_param_type original_type = t; + if(!transform_type(t, flags)) { + throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); + } + + assert((void("len() type must be PT_UINT64"), t == PT_UINT64)); + m_storage_values.clear(); + if(is_list) { + uint64_t len = static_cast(vec.size()); + auto stored_val = store_scalar(len); + vec.clear(); + vec.push_back(stored_val); + return true; + } + + // not a list: could be string or buffer + bool is_string = false; + switch(original_type) { + case PT_CHARBUF: + case PT_FSPATH: + case PT_FSRELPATH: + is_string = true; + break; + case PT_BYTEBUF: + is_string = false; + break; + default: + return false; + } + + if(vec.size() == 0) { + // should never happen since there is no way to + // call len() with no arguments + return false; + } + + // we are assuming that if this is not a list then it's a single element + assert((void("non-list elements to transform with len() must be a vector with a single " + "element"), + vec.size() == 1)); + uint64_t len; + if(vec[0].ptr == nullptr) { + vec[0] = store_scalar(0); + return true; + } + + if(is_string) { + len = static_cast(strnlen(reinterpret_cast(vec[0].ptr), vec[0].len)); + vec[0] = store_scalar(len); + return true; + } + + // buffer + len = static_cast(vec[0].len); + vec[0] = store_scalar(len); + return true; +} diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_len.h b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_len.h new file mode 100644 index 0000000000..3f8efce71f --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_len.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include + +class sinsp_filter_transformer_len : public sinsp_filter_transformer { +public: + sinsp_filter_transformer_len(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_storage.cpp b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_storage.cpp new file mode 100644 index 0000000000..9d47cc4104 --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_storage.cpp @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include + +sinsp_filter_transformer_storage::sinsp_filter_transformer_storage() { + m_type = FTR_STORAGE; +}; + +bool sinsp_filter_transformer_storage::transform_type(ppm_param_type& t, uint32_t& flags) const { + return true; +} + +bool sinsp_filter_transformer_storage::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { + // note: for STORAGE, the transformed type is the same as the input type + m_storage_values.resize(vec.size()); + for(std::size_t i = 0; i < vec.size(); i++) { + storage_t& buf = m_storage_values[i]; + + buf.clear(); + if(vec[i].ptr == nullptr) { + continue; + } + + // We reserve one extra chat for the null terminator + buf.resize(vec[i].len + 1); + memcpy(&(buf[0]), vec[i].ptr, vec[i].len); + // We put the string terminator in any case + buf[vec[i].len] = '\0'; + vec[i].ptr = &(buf[0]); + // `vec[i].len` is the same as before + } + return true; +} diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_storage.h b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_storage.h new file mode 100644 index 0000000000..3ace19fae2 --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_storage.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include + +class sinsp_filter_transformer_storage : public sinsp_filter_transformer { +public: + sinsp_filter_transformer_storage(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_tolower.cpp b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_tolower.cpp new file mode 100644 index 0000000000..9b3f351834 --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_tolower.cpp @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include + +sinsp_filter_transformer_tolower::sinsp_filter_transformer_tolower() { + m_type = FTR_TOLOWER; +}; + +bool sinsp_filter_transformer_tolower::transform_type(ppm_param_type& t, uint32_t& flags) const { + switch(t) { + case PT_CHARBUF: + case PT_FSPATH: + case PT_FSRELPATH: + // for TOLOWER, the transformed type is the same as the input type + return true; + default: + return false; + } +} + +bool sinsp_filter_transformer_tolower::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { + if(!transform_type(t, flags)) { + throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); + } + + return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { + for(auto c : in) { + out.push_back(tolower(c)); + } + return true; + }); +} diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_tolower.h b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_tolower.h new file mode 100644 index 0000000000..65cc50950d --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_tolower.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include + +class sinsp_filter_transformer_tolower : public sinsp_filter_transformer { +public: + sinsp_filter_transformer_tolower(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_toupper.cpp b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_toupper.cpp new file mode 100644 index 0000000000..da9f3010e2 --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_toupper.cpp @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include + +sinsp_filter_transformer_toupper::sinsp_filter_transformer_toupper() { + m_type = FTR_TOUPPER; +}; + +bool sinsp_filter_transformer_toupper::transform_type(ppm_param_type& t, uint32_t& flags) const { + switch(t) { + case PT_CHARBUF: + case PT_FSPATH: + case PT_FSRELPATH: + // for TOUPPER, the transformed type is the same as the input type + return true; + default: + return false; + } +} + +bool sinsp_filter_transformer_toupper::transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) { + if(!transform_type(t, flags)) { + throw_type_incompatibility_err(t, filter_transformer_type_str(m_type)); + } + + return string_transformer(vec, t, [](std::string_view in, storage_t& out) -> bool { + for(auto c : in) { + out.push_back(toupper(c)); + } + return true; + }); +} diff --git a/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_toupper.h b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_toupper.h new file mode 100644 index 0000000000..84536b5574 --- /dev/null +++ b/userspace/libsinsp/sinsp_filter_transformers/sinsp_filter_transformer_toupper.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include + +class sinsp_filter_transformer_toupper : public sinsp_filter_transformer { +public: + sinsp_filter_transformer_toupper(); + bool transform_type(ppm_param_type& t, uint32_t& flags) const override; + bool transform_values(std::vector& vec, + ppm_param_type& t, + uint32_t& flags) override; +}; diff --git a/userspace/libsinsp/sinsp_filtercheck.cpp b/userspace/libsinsp/sinsp_filtercheck.cpp index 0f585dc55c..65b7eec9f9 100644 --- a/userspace/libsinsp/sinsp_filtercheck.cpp +++ b/userspace/libsinsp/sinsp_filtercheck.cpp @@ -1060,7 +1060,7 @@ void sinsp_filter_check::add_transformer(filter_transformer_type trtype) { // apply type transformation, both as a feasibility check and // as an information to be returned later on - auto tr = sinsp_filter_transformer::create_transformer(trtype); + auto tr = sinsp_filter_transformer_factory::create_transformer(trtype); if(!tr->transform_type(m_transformed_field->m_type, m_transformed_field->m_flags)) { throw sinsp_exception("can't add field transformer: type '" + std::string(param_type_to_string(m_transformed_field->m_type)) + diff --git a/userspace/libsinsp/sinsp_filtercheck.h b/userspace/libsinsp/sinsp_filtercheck.h index 43dcffd25b..5a52e038fd 100644 --- a/userspace/libsinsp/sinsp_filtercheck.h +++ b/userspace/libsinsp/sinsp_filtercheck.h @@ -24,7 +24,7 @@ limitations under the License. #include #include #include -#include +#include #include diff --git a/userspace/libsinsp/test/filter_transformer.ut.cpp b/userspace/libsinsp/test/filter_transformer.ut.cpp index 4473de313f..8da1ac4e82 100644 --- a/userspace/libsinsp/test/filter_transformer.ut.cpp +++ b/userspace/libsinsp/test/filter_transformer.ut.cpp @@ -20,7 +20,7 @@ limitations under the License. #include #include -#include +#include #include static std::set all_param_types() { @@ -112,7 +112,8 @@ static void check_unsupported_types(const std::unique_ptr supported_types{PT_CHARBUF, PT_FSPATH, PT_FSRELPATH}; std::set supported_list_types = supported_types; @@ -159,7 +160,8 @@ TEST(sinsp_filter_transformer, toupper) { } TEST(sinsp_filter_transformer, tolower) { - auto tr = sinsp_filter_transformer::create_transformer(filter_transformer_type::FTR_TOLOWER); + auto tr = sinsp_filter_transformer_factory::create_transformer( + filter_transformer_type::FTR_TOLOWER); std::set supported_types{PT_CHARBUF, PT_FSPATH, PT_FSRELPATH}; std::set supported_list_types = supported_types; @@ -207,7 +209,8 @@ TEST(sinsp_filter_transformer, tolower) { } TEST(sinsp_filter_transformer, b64) { - auto tr = sinsp_filter_transformer::create_transformer(filter_transformer_type::FTR_BASE64); + auto tr = sinsp_filter_transformer_factory::create_transformer( + filter_transformer_type::FTR_BASE64); std::set supported_types{PT_CHARBUF, PT_FSPATH, PT_FSRELPATH, PT_BYTEBUF}; std::set supported_list_types = supported_types; @@ -249,7 +252,8 @@ TEST(sinsp_filter_transformer, b64) { } TEST(sinsp_filter_transformer, basename) { - auto tr = sinsp_filter_transformer::create_transformer(filter_transformer_type::FTR_BASENAME); + auto tr = sinsp_filter_transformer_factory::create_transformer( + filter_transformer_type::FTR_BASENAME); std::set supported_types{PT_CHARBUF, PT_FSPATH, PT_FSRELPATH}; std::set supported_list_types = supported_types; @@ -294,7 +298,8 @@ TEST(sinsp_filter_transformer, basename) { } TEST(sinsp_filter_transformer, len) { - auto tr = sinsp_filter_transformer::create_transformer(filter_transformer_type::FTR_LEN); + auto tr = + sinsp_filter_transformer_factory::create_transformer(filter_transformer_type::FTR_LEN); std::set supported_types{PT_CHARBUF, PT_FSPATH, PT_FSRELPATH, PT_BYTEBUF}; std::set supported_list_types = all_param_types();