[v6,01/11] eal: introduce new secure memory fill

Message ID 20250213221819.1856769-2-stephen@networkplumber.org (mailing list archive)
State Superseded
Delegated to: Thomas Monjalon
Headers
Series secure zeroing of memory |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Stephen Hemminger Feb. 13, 2025, 10:16 p.m. UTC
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 is equivalent to the
C23 memset_explicit function.
Name ot the new function chosen to be similar to
Linux kernel internal memzero_explicit().

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/eal/include/rte_string_fns.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
  

Comments

Morten Brørup Feb. 15, 2025, 3:21 p.m. UTC | #1
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Thursday, 13 February 2025 23.16
> 
> 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 is equivalent to the
> C23 memset_explicit function.

I agree that zeroing is better than passing the fill character as a parameter.

After switching to zeroing, it's no longer like C23 memset_explicit.

> Name ot the new function chosen to be similar to

Typo: ot -> of

> Linux kernel internal memzero_explicit().

Just merge these last two sentences into one, e.g.:

Introduce a DPDK wrapper which is equivalent to the Linux kernel internal memzero_explicit().

> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  lib/eal/include/rte_string_fns.h | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/lib/eal/include/rte_string_fns.h
> b/lib/eal/include/rte_string_fns.h
> index 702bd81251..93aae66614 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,29 @@ rte_str_skip_leading_spaces(const char *src)
>  	return p;
>  }
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Fill memory with 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 or freeing,
> + * use rte_memzero_explicit() to preven the compiler from optimizing

Typo: preven -> prevent

> + * away the zeroing.
> + *
> + * @param dst
> + *   target buffer
> + * @param sz
> + *   number of bytes to fill
> + */
> +__rte_experimental
> +static inline void
> +rte_memzero_explicit(void *dst, size_t sz)
> +{
> +	memset(dst, 0, sz);
> +	rte_compiler_barrier();
> +}
> +
>  #ifdef __cplusplus
>  }
>  #endif
> --
> 2.47.2

With description and typos fixed,
Acked-by: Morten Brørup <mb@smartsharesystems.com>
  

Patch

diff --git a/lib/eal/include/rte_string_fns.h b/lib/eal/include/rte_string_fns.h
index 702bd81251..93aae66614 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,29 @@  rte_str_skip_leading_spaces(const char *src)
 	return p;
 }
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Fill memory with 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 or freeing,
+ * use rte_memzero_explicit() to preven the compiler from optimizing
+ * away the zeroing.
+ *
+ * @param dst
+ *   target buffer
+ * @param sz
+ *   number of bytes to fill
+ */
+__rte_experimental
+static inline void
+rte_memzero_explicit(void *dst, size_t sz)
+{
+	memset(dst, 0, sz);
+	rte_compiler_barrier();
+}
+
 #ifdef __cplusplus
 }
 #endif