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

Message ID 20250211173720.1188517-2-stephen@networkplumber.org (mailing list archive)
State Superseded
Delegated to: Thomas Monjalon
Headers
Series memset security fixes |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Stephen Hemminger Feb. 11, 2025, 5:35 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 C++ memset_s
function.  Naming chosen to be similar to kernel.

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

Comments

fengchengwen Feb. 12, 2025, 1:37 a.m. UTC | #1
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>

On 2025/2/12 1:35, Stephen Hemminger wrote:
> 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 C++ memset_s
> function.  Naming chosen to be similar to kernel.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
  
Morten Brørup Feb. 12, 2025, 9:09 a.m. UTC | #2
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Tuesday, 11 February 2025 18.35
> 
> 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 C++ memset_s
> function.  Naming chosen to be similar to kernel.

It's not like C11 memset_s, which takes one more parameter, and is an optional part of the C11 standard.
It's like C23 memset_explicit.

Wouldn't it be better to name it after the C standard function, i.e. rte_memset_explicit?

Or maybe backport memset_explicit from C23, i.e. omit the rte_ prefix, if not using a C23 compiler?
  
Stephen Hemminger Feb. 12, 2025, 3:03 p.m. UTC | #3
On Wed, 12 Feb 2025 10:09:27 +0100
Morten Brørup <mb@smartsharesystems.com> wrote:

> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Tuesday, 11 February 2025 18.35
> > 
> > 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 C++ memset_s
> > function.  Naming chosen to be similar to kernel.  
> 
> It's not like C11 memset_s, which takes one more parameter, and is an optional part of the C11 standard.
> It's like C23 memset_explicit.
> 
> Wouldn't it be better to name it after the C standard function, i.e. rte_memset_explicit?
> 
> Or maybe backport memset_explicit from C23, i.e. omit the rte_ prefix, if not using a C23 compiler?
> 

I prefer parallel Linux kernal API names, lots of drivers share code.
  

Patch

diff --git a/lib/eal/include/rte_string_fns.h b/lib/eal/include/rte_string_fns.h
index 702bd81251..4874703957 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,32 @@  rte_str_skip_leading_spaces(const char *src)
 	return p;
 }
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Fill memory with constant byte but can not be optimized away.
+ * Use as a replacement for memset() for sensitive information.
+ *
+ * @param dst
+ *   target buffer
+ * @param ch
+ *   byte to fill
+ * @param sz
+ *   number of bytes to fill
+ *
+ * @return
+ *  like memset() returns a pointer th the memory area dst.
+ */
+__rte_experimental
+static inline void *
+rte_memset_sensitive(void *dst, int ch, size_t sz)
+{
+	void *ret = memset(dst, ch, sz);
+	rte_compiler_barrier();
+	return ret;
+}
+
 #ifdef __cplusplus
 }
 #endif