When memset() is used before a release function such as free, the compiler if allowed to optimize the memset away under the as-if rules. This is normally ok, but in certain cases such as passwords or security keys it is problematic.
Introduce a DPDK wrapper which uses the bzero_explicit function or SecureZeroMemory on Windows. Signed-off-by: Stephen Hemminger <step...@networkplumber.org> --- lib/eal/common/eal_common_string_fns.c | 15 +++++++++++++++ lib/eal/include/rte_string_fns.h | 19 +++++++++++++++++++ lib/eal/version.map | 3 +++ 3 files changed, 37 insertions(+) diff --git a/lib/eal/common/eal_common_string_fns.c b/lib/eal/common/eal_common_string_fns.c index 9ca2045b18..af9efc1bf2 100644 --- a/lib/eal/common/eal_common_string_fns.c +++ b/lib/eal/common/eal_common_string_fns.c @@ -7,9 +7,14 @@ #include <stdio.h> #include <stdlib.h> + #include <rte_string_fns.h> #include <rte_errno.h> +#ifdef RTE_EXEC_ENV_WINDOWS +#include <rte_windows.h> +#endif + /* split string into tokens */ int rte_strsplit(char *string, int stringlen, @@ -98,3 +103,13 @@ rte_str_to_size(const char *str) } return size; } + +void +rte_memzero_explicit(void *dst, size_t sz) +{ +#ifdef RTE_EXEC_ENV_WINDOWS + SecureZeroMemory(dst, sz); +#else + explicit_bzero(dst, sz); +#endif +} diff --git a/lib/eal/include/rte_string_fns.h b/lib/eal/include/rte_string_fns.h index 702bd81251..d83b346158 100644 --- a/lib/eal/include/rte_string_fns.h +++ b/lib/eal/include/rte_string_fns.h @@ -15,6 +15,7 @@ #include <stdio.h> #include <string.h> +#include <rte_atomic.h> #include <rte_common.h> #include <rte_compat.h> @@ -149,6 +150,24 @@ rte_str_skip_leading_spaces(const char *src) return p; } +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Fill memory with zero's (e.g. sensitive keys). + * Normally using memset() is fine, but in cases where clearing out local data + * before going out of scope is required, use rte_memzero_explicit() instead + * to prevent the compiler from optimizing away the zeroing operation. + * + * @param dst + * target buffer + * @param sz + * number of bytes to fill + */ +__rte_experimental +void +rte_memzero_explicit(void *dst, size_t sz); + #ifdef __cplusplus } #endif diff --git a/lib/eal/version.map b/lib/eal/version.map index a20c713eb1..82a3e91c97 100644 --- a/lib/eal/version.map +++ b/lib/eal/version.map @@ -398,6 +398,9 @@ EXPERIMENTAL { # added in 24.11 rte_bitset_to_str; rte_lcore_var_alloc; + + # added in 25.03 + rte_memzero_explicit; }; INTERNAL { -- 2.47.2