DPDK patches and discussions
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
	Chengwen Feng <fengchengwen@huawei.com>,
	Tyler Retzlaff <roretzla@linux.microsoft.com>,
	Anatoly Burakov <anatoly.burakov@intel.com>
Subject: [PATCH v4 17/17] eal: add function attributes for allocation functions
Date: Mon, 30 Sep 2024 11:44:11 -0700	[thread overview]
Message-ID: <20240930184600.7092-18-stephen@networkplumber.org> (raw)
In-Reply-To: <20240930184600.7092-1-stephen@networkplumber.org>

The allocation functions take a alignment argument that
can be useful to hint the compiler optimizer.

This is supported by Gcc and Clang but only useful with
Gcc because Clang gives warning if alignment is 0.

Recent versions of GCC have a malloc attribute that can
be used to find mismatches between allocation and free;
the typical problem caught is a pointer allocated with
rte_malloc() that is then incorrectly freed using free().

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 doc/guides/rel_notes/release_24_11.rst |  8 ++++
 lib/eal/include/rte_common.h           | 36 +++++++++++++++++
 lib/eal/include/rte_malloc.h           | 55 +++++++++++++++-----------
 3 files changed, 76 insertions(+), 23 deletions(-)

diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst
index 0ff70d9057..f27a37eac4 100644
--- a/doc/guides/rel_notes/release_24_11.rst
+++ b/doc/guides/rel_notes/release_24_11.rst
@@ -55,6 +55,14 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Hardened rte_malloc and related functions.**
+
+  * Added function attributes to  ``rte_malloc`` and similar functions
+    that can catch some obvious bugs at compile time (with GCC 11.0 or later).
+    Examples: calling ``free()`` on pointer that was allocated with ``rte_malloc``
+    (and vice versa); freeing the same pointer twice in the same routine;
+    freeing an object that was not created by allocation; etc.
+
 
 Removed Items
 -------------
diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h
index eec0400dad..d94d2b9a12 100644
--- a/lib/eal/include/rte_common.h
+++ b/lib/eal/include/rte_common.h
@@ -228,6 +228,42 @@ typedef uint16_t unaligned_uint16_t;
 #define __rte_alloc_size(...)
 #endif
 
+/**
+ * Tells the compiler that the function returns a value that points to
+ * memory aligned by a function argument.
+ *
+ * Note: not enabled on Clang because it warns if align argument is zero.
+ */
+#if defined(RTE_CC_GCC)
+#define __rte_alloc_align(argno) \
+	__attribute__((alloc_align(argno)))
+#else
+#define __rte_alloc_align(argno)
+#endif
+
+/**
+ * Tells the compiler this is a function like malloc and that the pointer
+ * returned cannot alias any other pointer (ie new memory).
+ */
+#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
+#define __rte_malloc __attribute__((__malloc__))
+#else
+#define __rte_malloc
+#endif
+
+/**
+ * With recent GCC versions also able to track that proper
+ * dealloctor function is used for this pointer.
+ */
+#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 110000)
+#define __rte_dealloc(dealloc, argno) \
+	__attribute__((malloc(dealloc, argno)))
+#define __rte_dealloc_free __rte_dealloc(rte_free, 1)
+#else
+#define __rte_dealloc(dealloc, argno)
+#define __rte_dealloc_free
+#endif
+
 #define RTE_PRIORITY_LOG 101
 #define RTE_PRIORITY_BUS 110
 #define RTE_PRIORITY_CLASS 120
diff --git a/lib/eal/include/rte_malloc.h b/lib/eal/include/rte_malloc.h
index 1f91e7bdde..9261605939 100644
--- a/lib/eal/include/rte_malloc.h
+++ b/lib/eal/include/rte_malloc.h
@@ -31,6 +31,22 @@ struct rte_malloc_socket_stats {
 	size_t heap_allocsz_bytes; /**< Total allocated bytes on heap */
 };
 
+
+/**
+ * Frees the memory space pointed to by the provided pointer.
+ *
+ * This pointer must have been returned by a previous call to
+ * rte_malloc(), rte_zmalloc(), rte_calloc() or rte_realloc(). The behaviour of
+ * rte_free() is undefined if the pointer does not match this requirement.
+ *
+ * If the pointer is NULL, the function does nothing.
+ *
+ * @param ptr
+ *   The pointer to memory to be freed.
+ */
+void
+rte_free(void *ptr);
+
 /**
  * This function allocates memory from the huge-page area of memory. The memory
  * is not cleared. In NUMA systems, the memory allocated resides on the same
@@ -54,7 +70,8 @@ struct rte_malloc_socket_stats {
  */
 void *
 rte_malloc(const char *type, size_t size, unsigned align)
-	__rte_alloc_size(2);
+	__rte_alloc_size(2) __rte_alloc_align(3)
+	__rte_malloc __rte_dealloc_free;
 
 /**
  * Allocate zeroed memory from the heap.
@@ -81,7 +98,8 @@ rte_malloc(const char *type, size_t size, unsigned align)
  */
 void *
 rte_zmalloc(const char *type, size_t size, unsigned align)
-	__rte_alloc_size(2);
+	__rte_alloc_size(2) __rte_alloc_align(3)
+	__rte_malloc __rte_dealloc_free;
 
 /**
  * Replacement function for calloc(), using huge-page memory. Memory area is
@@ -108,7 +126,8 @@ rte_zmalloc(const char *type, size_t size, unsigned align)
  */
 void *
 rte_calloc(const char *type, size_t num, size_t size, unsigned align)
-	__rte_alloc_size(2, 3);
+	__rte_alloc_size(2, 3)	__rte_alloc_align(4)
+	__rte_malloc __rte_dealloc_free;
 
 /**
  * Replacement function for realloc(), using huge-page memory. Reserved area
@@ -132,7 +151,8 @@ rte_calloc(const char *type, size_t num, size_t size, unsigned align)
  */
 void *
 rte_realloc(void *ptr, size_t size, unsigned int align)
-	__rte_alloc_size(2);
+	__rte_alloc_size(2) __rte_alloc_align(3)
+	__rte_malloc __rte_dealloc_free;
 
 /**
  * Replacement function for realloc(), using huge-page memory. Reserved area
@@ -158,7 +178,8 @@ rte_realloc(void *ptr, size_t size, unsigned int align)
  */
 void *
 rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket)
-	__rte_alloc_size(2);
+	__rte_alloc_size(2) __rte_alloc_align(3)
+	__rte_malloc __rte_dealloc_free;
 
 /**
  * This function allocates memory from the huge-page area of memory. The memory
@@ -185,7 +206,8 @@ rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket)
  */
 void *
 rte_malloc_socket(const char *type, size_t size, unsigned align, int socket)
-	__rte_alloc_size(2);
+	__rte_alloc_size(2) __rte_alloc_align(3)
+	__rte_malloc __rte_dealloc_free;
 
 /**
  * Allocate zeroed memory from the heap.
@@ -214,7 +236,8 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket)
  */
 void *
 rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket)
-	__rte_alloc_size(2);
+	__rte_alloc_size(2) __rte_alloc_align(3)
+	__rte_malloc __rte_dealloc_free;
 
 /**
  * Replacement function for calloc(), using huge-page memory. Memory area is
@@ -243,22 +266,8 @@ rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket)
  */
 void *
 rte_calloc_socket(const char *type, size_t num, size_t size, unsigned align, int socket)
-	__rte_alloc_size(2, 3);
-
-/**
- * Frees the memory space pointed to by the provided pointer.
- *
- * This pointer must have been returned by a previous call to
- * rte_malloc(), rte_zmalloc(), rte_calloc() or rte_realloc(). The behaviour of
- * rte_free() is undefined if the pointer does not match this requirement.
- *
- * If the pointer is NULL, the function does nothing.
- *
- * @param ptr
- *   The pointer to memory to be freed.
- */
-void
-rte_free(void *ptr);
+	__rte_alloc_size(2, 3)	__rte_alloc_align(4)
+	__rte_malloc __rte_dealloc_free;
 
 /**
  * If malloc debug is enabled, check a memory block for header
-- 
2.45.2


      parent reply	other threads:[~2024-09-30 18:47 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-27 20:45 [PATCH 00/16] Fix allocation issues and add hardening Stephen Hemminger
2024-09-27 20:45 ` [PATCH 01/16] eal: add function attributes for allocation functions Stephen Hemminger
2024-09-27 22:09   ` David Marchand
2024-09-27 23:10     ` Stephen Hemminger
2024-09-27 20:45 ` [PATCH 02/16] memzone: fix use after free in tracing Stephen Hemminger
2024-09-27 20:45 ` [PATCH 03/16] cryptodev/bcmfs: fix mis-matched free Stephen Hemminger
2024-09-27 20:45 ` [PATCH 04/16] dma/ixd: fix incorrect free function in cleanup Stephen Hemminger
2024-09-27 20:45 ` [PATCH 05/16] event/cnxk: fix pointer mismatch " Stephen Hemminger
2024-09-27 20:45 ` [PATCH 06/16] examples/vhost: fix free function mismatch Stephen Hemminger
2024-09-27 20:45 ` [PATCH 07/16] net/cnxk: fix use-after-free Stephen Hemminger
2024-09-27 20:45 ` [PATCH 08/16] bpf: fix free mismatch if convert fails Stephen Hemminger
2024-09-27 20:45 ` [PATCH 09/16] net/e1000: fix use-after-free Stephen Hemminger
2024-09-27 20:45 ` [PATCH 10/16] net/sfc: fix use-after-free warning messages Stephen Hemminger
2024-09-28 11:52   ` Ivan Malov
2024-09-27 20:45 ` [PATCH 11/16] net/cpfl: fix free of nonheap object Stephen Hemminger
2024-09-27 20:45 ` [PATCH 12/16] raw/ifpga/base: fix use after free Stephen Hemminger
2024-09-27 20:45 ` [PATCH 13/16] common/qat: " Stephen Hemminger
2024-09-27 20:45 ` [PATCH 14/16] drivers/ifpga: fix free function mismatch Stephen Hemminger
2024-09-27 20:45 ` [PATCH 15/16] eal: add alloc_function attribute to rte_malloc Stephen Hemminger
2024-09-27 20:45 ` [PATCH 16/16] mempool: annotate mempool create Stephen Hemminger
2024-09-28 11:49   ` Morten Brørup
2024-09-28 16:47 ` [PATCH v2 00/16] Fix allocation bugs and add malloc hardening Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 01/16] eal: add function attributes for allocation functions Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 02/16] memzone: fix use after free in tracing Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 03/16] cryptodev/bcmfs: fix mis-matched free Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 04/16] dma/ixd: fix incorrect free function in cleanup Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 05/16] event/cnxk: fix pointer mismatch " Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 06/16] examples/vhost: fix free function mismatch Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 07/16] net/cnxk: fix use-after-free Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 08/16] bpf: fix free mismatch if convert fails Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 09/16] net/e1000: fix use-after-free Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 10/16] net/sfc: fix use-after-free warning messages Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 11/16] net/cpfl: fix free of nonheap object Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 12/16] net/nfp: fix duplicate call to rte_free Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 13/16] raw/ifpga/base: fix use after free Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 14/16] common/qat: " Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 15/16] drivers/ifpga: fix free function mismatch Stephen Hemminger
2024-09-28 16:47   ` [PATCH v2 16/16] eal: add alloc_function attribute to rte_malloc Stephen Hemminger
2024-09-29 15:34 ` [PATCH v3 00/18] Fix allocation bugs and add malloc hardening Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 01/18] memzone: fix use after free in tracing Stephen Hemminger
2024-09-30  9:15     ` fengchengwen
2024-09-29 15:34   ` [PATCH v3 02/18] cryptodev/bcmfs: fix mis-matched free Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 03/18] dma/ixd: fix incorrect free function in cleanup Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 04/18] event/cnxk: fix pointer mismatch " Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 05/18] examples/vhost: fix free function mismatch Stephen Hemminger
2024-09-30  9:16     ` fengchengwen
2024-09-29 15:34   ` [PATCH v3 06/18] net/cnxk: fix use-after-free Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 07/18] bpf: fix free mismatch if convert fails Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 08/18] net/e1000: fix use-after-free Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 09/18] net/sfc: fix use-after-free warning messages Stephen Hemminger
2024-09-30  5:53     ` Andrew Rybchenko
2024-09-29 15:34   ` [PATCH v3 10/18] net/cpfl: fix free of nonheap object Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 11/18] net/nfp: fix duplicate call to rte_free Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 12/18] raw/ifpga/base: fix use after free Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 13/18] common/qat: " Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 14/18] drivers/ifpga: fix free function mismatch Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 15/18] baseband/la12xx: prevent use after free Stephen Hemminger
2024-09-30  8:25     ` Hemant Agrawal
2024-09-29 15:34   ` [PATCH v3 16/18] common/ipdf: fix use after free due Stephen Hemminger
2024-09-29 15:34   ` [PATCH v3 17/18] eal: add function attributes for allocation functions Stephen Hemminger
2024-09-30  9:19     ` fengchengwen
2024-09-29 15:34   ` [PATCH v3 18/18] eal: add alloc_function attribute to rte_malloc Stephen Hemminger
2024-09-30  9:20     ` fengchengwen
2024-09-30 18:43 ` [PATCH v4 00/17] Fix allocation bugs and hardening for rte_malloc Stephen Hemminger
2024-09-30 18:43   ` [PATCH v4 01/17] memzone: fix use after free in tracing Stephen Hemminger
2024-09-30 18:43   ` [PATCH v4 02/17] cryptodev/bcmfs: fix mis-matched free Stephen Hemminger
2024-09-30 20:06     ` Ajit Khaparde
2024-09-30 18:43   ` [PATCH v4 03/17] dma/ixd: fix incorrect free function in cleanup Stephen Hemminger
2024-09-30 18:43   ` [PATCH v4 04/17] event/cnxk: fix pointer mismatch " Stephen Hemminger
2024-09-30 18:43   ` [PATCH v4 05/17] examples/vhost: fix free function mismatch Stephen Hemminger
2024-09-30 18:44   ` [PATCH v4 06/17] net/cnxk: fix use-after-free Stephen Hemminger
2024-09-30 18:44   ` [PATCH v4 07/17] bpf: fix free mismatch if convert fails Stephen Hemminger
2024-09-30 18:44   ` [PATCH v4 08/17] net/e1000: fix use-after-free Stephen Hemminger
2024-09-30 18:44   ` [PATCH v4 09/17] net/sfc: fix use-after-free warning messages Stephen Hemminger
2024-09-30 18:44   ` [PATCH v4 10/17] net/cpfl: fix free of nonheap object Stephen Hemminger
2024-09-30 18:44   ` [PATCH v4 11/17] net/nfp: fix duplicate call to rte_free Stephen Hemminger
2024-09-30 18:44   ` [PATCH v4 12/17] raw/ifpga/base: fix use after free Stephen Hemminger
2024-09-30 18:44   ` [PATCH v4 13/17] common/qat: " Stephen Hemminger
2024-09-30 18:44   ` [PATCH v4 14/17] drivers/ifpga: fix free function mismatch Stephen Hemminger
2024-09-30 18:44   ` [PATCH v4 15/17] baseband/la12xx: prevent use after free Stephen Hemminger
2024-09-30 18:44   ` [PATCH v4 16/17] common/idpf: fix use after free due Stephen Hemminger
2024-09-30 18:44   ` Stephen Hemminger [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240930184600.7092-18-stephen@networkplumber.org \
    --to=stephen@networkplumber.org \
    --cc=anatoly.burakov@intel.com \
    --cc=dev@dpdk.org \
    --cc=fengchengwen@huawei.com \
    --cc=roretzla@linux.microsoft.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).