> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Thursday, October 14, 2021 12:45 AM
> To: Peng, ZhihongX <zhihongx.peng@intel.com>
> Cc: Burakov, Anatoly <anatoly.burakov@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; Stephen Hemminger
> <stephen@networkplumber.org>; dev <dev@dpdk.org>; Lin, Xueqin
> <xueqin.lin@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> Thomas Monjalon <thomas@monjalon.net>
> Subject: Re: [PATCH v9 2/3] DPDK code adapts to ASan
>
> On Tue, Oct 12, 2021 at 11:54 AM <zhihongx.peng@intel.com> wrote:
> >
> > From: Zhihong Peng <zhihongx.peng@intel.com>
> >
> > DPDK ASan functionality is currently only supported Linux x86_64.
> > Support other platforms, need to define ASAN_SHADOW_OFFSET value
> > according to google ASan document, and configure meson
> > (config/meson.build).
> >
> > Signed-off-by: Xueqin Lin <xueqin.lin@intel.com>
> > Signed-off-by: Zhihong Peng <zhihongx.peng@intel.com>
> > ---
> > v7: Split doc and code into two.
> > v8: No change.
> > v9: Modify the definition of RTE_MALLOC_ASAN.
> > ---
> > config/meson.build | 2 +
> > lib/eal/common/malloc_elem.c | 26 ++++-
> > lib/eal/common/malloc_elem.h | 194
> ++++++++++++++++++++++++++++++++++-
> > lib/eal/common/malloc_heap.c | 12 +++
> > lib/eal/common/rte_malloc.c | 9 +-
> > 5 files changed, 238 insertions(+), 5 deletions(-)
> >
> > diff --git a/config/meson.build b/config/meson.build index
> > 5170b79fed..1ae9390e68 100644
> > --- a/config/meson.build
> > +++ b/config/meson.build
> > @@ -419,6 +419,8 @@ if get_option('b_sanitize') == 'address'
> > error('broken dependency, "libasan"')
> > endif
> > endif
> > +
> > + dpdk_conf.set10('RTE_MALLOC_ASAN', true)
>
> The test on architecture == x86_64 is missing.
> ARM compilation with ASan is broken.
>
> $ ./devtools/test-meson-builds.sh
> ...
> ...
> ninja: Entering directory `/home/dmarchan/builds/build-arm64-bluefield'
> [0/1] Regenerating build files.
> The Meson build system
> Version: 0.59.0
> Source dir: /home/dmarchan/dpdk
> Build dir: /home/dmarchan/builds/build-arm64-bluefield
> ...
> [2/2784] Compiling C object
> lib/librte_eal.a.p/eal_common_eal_common_memzone.c.o
> FAILED: lib/librte_eal.a.p/eal_common_eal_common_memzone.c.o
> aarch64-linux-gnu-gcc -Ilib/librte_eal.a.p -Ilib -I../../dpdk/lib -I.
> -I../../dpdk -Iconfig -I../../dpdk/config -Ilib/eal/include -
> I../../dpdk/lib/eal/include -Ilib/eal/linux/include -
> I../../dpdk/lib/eal/linux/include -Ilib/eal/arm/include -
> I../../dpdk/lib/eal/arm/include -Ilib/eal/common -
> I../../dpdk/lib/eal/common -Ilib/eal -I../../dpdk/lib/eal -Ilib/kvargs -
> I../../dpdk/lib/kvargs -Ilib/metrics -I../../dpdk/lib/metrics -Ilib/telemetry -
> I../../dpdk/lib/telemetry -fdiagnostics-color=always -fsanitize=address -fno-
> omit-frame-pointer
> -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Werror -O2 -g -include
> rte_config.h -Wextra -Wcast-qual -Wdeprecated -Wformat -Wformat-
> nonliteral -Wformat-security -Wmissing-declarations -Wmissing-prototypes -
> Wnested-externs -Wold-style-definition -Wpointer-arith -Wsign-compare -
> Wstrict-prototypes -Wundef -Wwrite-strings -Wno-address-of-packed-
> member -Wno-packed-not-aligned -Wno-missing-field-initializers -Wno-
> zero-length-bounds -D_GNU_SOURCE -fPIC -mcpu=cortex-a72 -
> DALLOW_EXPERIMENTAL_API -DALLOW_INTERNAL_API -Wno-format-
> truncation '-DABI_VERSION="22.0"'
> -DRTE_LIBEAL_USE_GETENTROPY -DRTE_LOG_DEFAULT_LOGTYPE=lib.eal -
> MD -MQ lib/librte_eal.a.p/eal_common_eal_common_memzone.c.o -MF
> lib/librte_eal.a.p/eal_common_eal_common_memzone.c.o.d -o
> lib/librte_eal.a.p/eal_common_eal_common_memzone.c.o -
> c ../../dpdk/lib/eal/common/eal_common_memzone.c
> In file included from ../../dpdk/lib/eal/include/rte_log.h:25,
> from ../../dpdk/lib/eal/common/eal_common_memzone.c:14:
> ../../dpdk/lib/eal/common/malloc_elem.h: In function ‘asan_set_zone’:
> ../../dpdk/lib/eal/common/malloc_elem.h:118:35: error:
> ‘ASAN_SHADOW_OFFSET’ undeclared (first use in this function); did you
> mean ‘ASAN_SHADOW_SCALE’?
> 118 | RTE_PTR_ADD(ASAN_MEM_SHIFT(mem), ASAN_SHADOW_OFFSET)
> | ^~~~~~~~~~~~~~~~~~
> ../../dpdk/lib/eal/include/rte_common.h:250:58: note: in definition of macro
> ‘RTE_PTR_ADD’
> 250 | #define RTE_PTR_ADD(ptr, x) ((void*)((uintptr_t)(ptr) + (x)))
> | ^
> ../../dpdk/lib/eal/common/malloc_elem.h:142:12: note: in expansion of
> macro ‘ASAN_MEM_TO_SHADOW’
> 142 | shadow = ASAN_MEM_TO_SHADOW((uintptr_t)ptr + offset);
> | ^~~~~~~~~~~~~~~~~~
> ../../dpdk/lib/eal/common/malloc_elem.h:118:35: note: each undeclared
> identifier is reported only once for each function it appears in
> 118 | RTE_PTR_ADD(ASAN_MEM_SHIFT(mem), ASAN_SHADOW_OFFSET)
> | ^~~~~~~~~~~~~~~~~~
> ../../dpdk/lib/eal/include/rte_common.h:250:58: note: in definition of macro
> ‘RTE_PTR_ADD’
> 250 | #define RTE_PTR_ADD(ptr, x) ((void*)((uintptr_t)(ptr) + (x)))
> | ^
> ../../dpdk/lib/eal/common/malloc_elem.h:142:12: note: in expansion of
> macro ‘ASAN_MEM_TO_SHADOW’
> 142 | shadow = ASAN_MEM_TO_SHADOW((uintptr_t)ptr + offset);
> | ^~~~~~~~~~~~~~~~~~
> ../../dpdk/lib/eal/common/malloc_elem.h: In function ‘asan_set_redzone’:
> ../../dpdk/lib/eal/common/malloc_elem.h:118:35: error:
> ‘ASAN_SHADOW_OFFSET’ undeclared (first use in this function); did you
> mean ‘ASAN_SHADOW_SCALE’?
> 118 | RTE_PTR_ADD(ASAN_MEM_SHIFT(mem), ASAN_SHADOW_OFFSET)
> | ^~~~~~~~~~~~~~~~~~
> ../../dpdk/lib/eal/include/rte_common.h:250:58: note: in definition of macro
> ‘RTE_PTR_ADD’
> 250 | #define RTE_PTR_ADD(ptr, x) ((void*)((uintptr_t)(ptr) + (x)))
> | ^
> ../../dpdk/lib/eal/common/malloc_elem.h:196:18: note: in expansion of
> macro ‘ASAN_MEM_TO_SHADOW’
> 196 | front_shadow = ASAN_MEM_TO_SHADOW(head_redzone);
> | ^~~~~~~~~~~~~~~~~~
> ../../dpdk/lib/eal/common/malloc_elem.h: In function ‘asan_clear_redzone’:
> ../../dpdk/lib/eal/common/malloc_elem.h:118:35: error:
> ‘ASAN_SHADOW_OFFSET’ undeclared (first use in this function); did you
> mean ‘ASAN_SHADOW_SCALE’?
> 118 | RTE_PTR_ADD(ASAN_MEM_SHIFT(mem), ASAN_SHADOW_OFFSET)
> | ^~~~~~~~~~~~~~~~~~
> ../../dpdk/lib/eal/include/rte_common.h:250:58: note: in definition of macro
> ‘RTE_PTR_ADD’
> 250 | #define RTE_PTR_ADD(ptr, x) ((void*)((uintptr_t)(ptr) + (x)))
> | ^
> ../../dpdk/lib/eal/common/malloc_elem.h:235:17: note: in expansion of
> macro ‘ASAN_MEM_TO_SHADOW’
> 235 | head_shadow = ASAN_MEM_TO_SHADOW(head_redzone);
> | ^~~~~~~~~~~~~~~~~~
> [31/2784] Compiling C object lib/librte_eal.a.p/eal_linux_eal_interrupts.c.o
> ninja: build stopped: subcommand failed.
The v10 version will be fixed.
All meson code:
if get_option('b_sanitize') == 'address' or get_option('b_sanitize') == 'address,undefined'
if cc.get_id() == 'gcc'
asan_dep = cc.find_library('asan', required: true)
if (not cc.links('int main(int argc, char *argv[]) { return 0; }',
dependencies: asan_dep))
error('broken dependency, "libasan"')
endif
add_project_link_arguments('-lasan', language: 'c')
dpdk_extra_ldflags += '-lasan'
endif
if exec_env == 'linux' and arch_subdir == 'x86'
dpdk_conf.set10('RTE_MALLOC_ASAN', true)
endif
endif
>
>
> --
> David Marchand
>
>
>
>
> --
> David Marchand
@@ -419,6 +419,8 @@ if get_option('b_sanitize') == 'address'
error('broken dependency, "libasan"')
endif
endif
+
+ dpdk_conf.set10('RTE_MALLOC_ASAN', true)
endif
if get_option('default_library') == 'both'
@@ -446,6 +446,8 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align,
struct malloc_elem *new_free_elem =
RTE_PTR_ADD(new_elem, size + MALLOC_ELEM_OVERHEAD);
+ asan_clear_split_alloczone(new_free_elem);
+
split_elem(elem, new_free_elem);
malloc_elem_free_list_insert(new_free_elem);
@@ -458,6 +460,8 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align,
elem->state = ELEM_BUSY;
elem->pad = old_elem_size;
+ asan_clear_alloczone(elem);
+
/* put a dummy header in padding, to point to real element header */
if (elem->pad > 0) { /* pad will be at least 64-bytes, as everything
* is cache-line aligned */
@@ -470,12 +474,18 @@ malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align,
return new_elem;
}
+ asan_clear_split_alloczone(new_elem);
+
/* we are going to split the element in two. The original element
* remains free, and the new element is the one allocated.
* Re-insert original element, in case its new size makes it
* belong on a different list.
*/
+
split_elem(elem, new_elem);
+
+ asan_clear_alloczone(new_elem);
+
new_elem->state = ELEM_BUSY;
malloc_elem_free_list_insert(elem);
@@ -601,6 +611,8 @@ malloc_elem_hide_region(struct malloc_elem *elem, void *start, size_t len)
if (next && next_elem_is_adjacent(elem)) {
len_after = RTE_PTR_DIFF(next, hide_end);
if (len_after >= MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
+ asan_clear_split_alloczone(hide_end);
+
/* split after */
split_elem(elem, hide_end);
@@ -615,6 +627,8 @@ malloc_elem_hide_region(struct malloc_elem *elem, void *start, size_t len)
if (prev && prev_elem_is_adjacent(elem)) {
len_before = RTE_PTR_DIFF(hide_start, elem);
if (len_before >= MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) {
+ asan_clear_split_alloczone(hide_start);
+
/* split before */
split_elem(elem, hide_start);
@@ -628,6 +642,8 @@ malloc_elem_hide_region(struct malloc_elem *elem, void *start, size_t len)
}
}
+ asan_clear_alloczone(elem);
+
remove_elem(elem);
}
@@ -641,8 +657,10 @@ malloc_elem_resize(struct malloc_elem *elem, size_t size)
const size_t new_size = size + elem->pad + MALLOC_ELEM_OVERHEAD;
/* if we request a smaller size, then always return ok */
- if (elem->size >= new_size)
+ if (elem->size >= new_size) {
+ asan_clear_alloczone(elem);
return 0;
+ }
/* check if there is a next element, it's free and adjacent */
if (!elem->next || elem->next->state != ELEM_FREE ||
@@ -661,9 +679,15 @@ malloc_elem_resize(struct malloc_elem *elem, size_t size)
/* now we have a big block together. Lets cut it down a bit, by splitting */
struct malloc_elem *split_pt = RTE_PTR_ADD(elem, new_size);
split_pt = RTE_PTR_ALIGN_CEIL(split_pt, RTE_CACHE_LINE_SIZE);
+
+ asan_clear_split_alloczone(split_pt);
+
split_elem(elem, split_pt);
malloc_elem_free_list_insert(split_pt);
}
+
+ asan_clear_alloczone(elem);
+
return 0;
}
@@ -36,10 +36,20 @@ struct malloc_elem {
uint64_t header_cookie; /* Cookie marking start of data */
/* trailer cookie at start + size */
#endif
+#ifdef RTE_MALLOC_ASAN
+ size_t user_size;
+ uint64_t asan_cookie[2]; /* must be next to header_cookie */
+#endif
} __rte_cache_aligned;
+static const unsigned int MALLOC_ELEM_HEADER_LEN = sizeof(struct malloc_elem);
+
#ifndef RTE_MALLOC_DEBUG
-static const unsigned MALLOC_ELEM_TRAILER_LEN = 0;
+#ifdef RTE_MALLOC_ASAN
+static const unsigned int MALLOC_ELEM_TRAILER_LEN = RTE_CACHE_LINE_SIZE;
+#else
+static const unsigned int MALLOC_ELEM_TRAILER_LEN;
+#endif
/* dummy function - just check if pointer is non-null */
static inline int
@@ -55,7 +65,7 @@ set_trailer(struct malloc_elem *elem __rte_unused){ }
#else
-static const unsigned MALLOC_ELEM_TRAILER_LEN = RTE_CACHE_LINE_SIZE;
+static const unsigned int MALLOC_ELEM_TRAILER_LEN = RTE_CACHE_LINE_SIZE;
#define MALLOC_HEADER_COOKIE 0xbadbadbadadd2e55ULL /**< Header cookie. */
#define MALLOC_TRAILER_COOKIE 0xadd2e55badbadbadULL /**< Trailer cookie.*/
@@ -90,9 +100,187 @@ malloc_elem_cookies_ok(const struct malloc_elem *elem)
#endif
-static const unsigned MALLOC_ELEM_HEADER_LEN = sizeof(struct malloc_elem);
#define MALLOC_ELEM_OVERHEAD (MALLOC_ELEM_HEADER_LEN + MALLOC_ELEM_TRAILER_LEN)
+#ifdef RTE_MALLOC_ASAN
+
+#ifdef RTE_ARCH_X86_64
+#define ASAN_SHADOW_OFFSET 0x00007fff8000
+#endif
+
+#define ASAN_SHADOW_GRAIN_SIZE 8
+#define ASAN_MEM_FREE_FLAG 0xfd
+#define ASAN_MEM_REDZONE_FLAG 0xfa
+#define ASAN_SHADOW_SCALE 3
+
+#define ASAN_MEM_SHIFT(mem) ((void *)((uintptr_t)(mem) >> ASAN_SHADOW_SCALE))
+#define ASAN_MEM_TO_SHADOW(mem) \
+ RTE_PTR_ADD(ASAN_MEM_SHIFT(mem), ASAN_SHADOW_OFFSET)
+
+#if defined(__clang__)
+__attribute__((no_sanitize("address", "hwaddress")))
+#else
+__attribute__((no_sanitize_address))
+#endif
+static inline void
+asan_set_shadow(void *addr, char val)
+{
+ *(char *)addr = val;
+}
+
+static inline void
+asan_set_zone(void *ptr, size_t len, uint32_t val)
+{
+ size_t offset, i;
+ void *shadow;
+ size_t zone_len = len / ASAN_SHADOW_GRAIN_SIZE;
+ if (len % ASAN_SHADOW_GRAIN_SIZE != 0)
+ zone_len += 1;
+
+ for (i = 0; i < zone_len; i++) {
+ offset = i * ASAN_SHADOW_GRAIN_SIZE;
+ shadow = ASAN_MEM_TO_SHADOW((uintptr_t)ptr + offset);
+ asan_set_shadow(shadow, val);
+ }
+}
+
+/*
+ * When the memory is released, the release mark is
+ * set in the corresponding range of the shadow area.
+ */
+static inline void
+asan_set_freezone(void *ptr, size_t size)
+{
+ asan_set_zone(ptr, size, ASAN_MEM_FREE_FLAG);
+}
+
+/*
+ * When the memory is allocated, memory state must set as accessible.
+ */
+static inline void
+asan_clear_alloczone(struct malloc_elem *elem)
+{
+ asan_set_zone((void *)elem, elem->size, 0x0);
+}
+
+static inline void
+asan_clear_split_alloczone(struct malloc_elem *elem)
+{
+ void *ptr = RTE_PTR_SUB(elem, MALLOC_ELEM_TRAILER_LEN);
+ asan_set_zone(ptr, MALLOC_ELEM_OVERHEAD, 0x0);
+}
+
+/*
+ * When the memory is allocated, the memory boundary is
+ * marked in the corresponding range of the shadow area.
+ * Requirement: redzone >= 16, is a power of two.
+ */
+static inline void
+asan_set_redzone(struct malloc_elem *elem, size_t user_size)
+{
+ uintptr_t head_redzone;
+ uintptr_t tail_redzone;
+ void *front_shadow;
+ void *tail_shadow;
+ uint32_t val;
+
+ if (elem != NULL) {
+ if (elem->state != ELEM_PAD)
+ elem = RTE_PTR_ADD(elem, elem->pad);
+
+ elem->user_size = user_size;
+
+ /* Set mark before the start of the allocated memory */
+ head_redzone = (uintptr_t)RTE_PTR_ADD(elem,
+ MALLOC_ELEM_HEADER_LEN - ASAN_SHADOW_GRAIN_SIZE);
+ front_shadow = ASAN_MEM_TO_SHADOW(head_redzone);
+ asan_set_shadow(front_shadow, ASAN_MEM_REDZONE_FLAG);
+ front_shadow = ASAN_MEM_TO_SHADOW(head_redzone
+ - ASAN_SHADOW_GRAIN_SIZE);
+ asan_set_shadow(front_shadow, ASAN_MEM_REDZONE_FLAG);
+
+ /* Set mark after the end of the allocated memory */
+ tail_redzone = (uintptr_t)RTE_PTR_ADD(elem,
+ MALLOC_ELEM_HEADER_LEN
+ + elem->user_size);
+ tail_shadow = ASAN_MEM_TO_SHADOW(tail_redzone);
+ val = (tail_redzone % ASAN_SHADOW_GRAIN_SIZE);
+ val = (val == 0) ? ASAN_MEM_REDZONE_FLAG : val;
+ asan_set_shadow(tail_shadow, val);
+ tail_shadow = ASAN_MEM_TO_SHADOW(tail_redzone
+ + ASAN_SHADOW_GRAIN_SIZE);
+ asan_set_shadow(tail_shadow, ASAN_MEM_REDZONE_FLAG);
+ }
+}
+
+/*
+ * When the memory is released, the mark of the memory boundary
+ * in the corresponding range of the shadow area is cleared.
+ * Requirement: redzone >= 16, is a power of two.
+ */
+static inline void
+asan_clear_redzone(struct malloc_elem *elem)
+{
+ uintptr_t head_redzone;
+ uintptr_t tail_redzone;
+ void *head_shadow;
+ void *tail_shadow;
+
+ if (elem != NULL) {
+ elem = RTE_PTR_ADD(elem, elem->pad);
+
+ /* Clear mark before the start of the allocated memory */
+ head_redzone = (uintptr_t)RTE_PTR_ADD(elem,
+ MALLOC_ELEM_HEADER_LEN - ASAN_SHADOW_GRAIN_SIZE);
+ head_shadow = ASAN_MEM_TO_SHADOW(head_redzone);
+ asan_set_shadow(head_shadow, 0x00);
+ head_shadow = ASAN_MEM_TO_SHADOW(head_redzone
+ - ASAN_SHADOW_GRAIN_SIZE);
+ asan_set_shadow(head_shadow, 0x00);
+
+ /* Clear mark after the end of the allocated memory */
+ tail_redzone = (uintptr_t)RTE_PTR_ADD(elem,
+ MALLOC_ELEM_HEADER_LEN + elem->user_size);
+ tail_shadow = ASAN_MEM_TO_SHADOW(tail_redzone);
+ asan_set_shadow(tail_shadow, 0x00);
+ tail_shadow = ASAN_MEM_TO_SHADOW(tail_redzone
+ + ASAN_SHADOW_GRAIN_SIZE);
+ asan_set_shadow(tail_shadow, 0x00);
+ }
+}
+
+static inline size_t
+old_malloc_size(struct malloc_elem *elem)
+{
+ if (elem->state != ELEM_PAD)
+ elem = RTE_PTR_ADD(elem, elem->pad);
+
+ return elem->user_size;
+}
+#else
+static inline void
+asan_set_freezone(void *ptr __rte_unused, size_t size __rte_unused) { }
+
+static inline void
+asan_clear_alloczone(struct malloc_elem *elem __rte_unused) { }
+
+static inline void
+asan_clear_split_alloczone(struct malloc_elem *elem __rte_unused) { }
+
+static inline void
+asan_set_redzone(struct malloc_elem *elem __rte_unused,
+ size_t user_size __rte_unused) { }
+
+static inline void
+asan_clear_redzone(struct malloc_elem *elem __rte_unused) { }
+
+static inline size_t
+old_malloc_size(struct malloc_elem *elem)
+{
+ return elem->size - elem->pad - MALLOC_ELEM_OVERHEAD;
+}
+#endif
+
/*
* Given a pointer to the start of a memory block returned by malloc, get
* the actual malloc_elem header for that block.
@@ -237,6 +237,7 @@ heap_alloc(struct malloc_heap *heap, const char *type __rte_unused, size_t size,
unsigned int flags, size_t align, size_t bound, bool contig)
{
struct malloc_elem *elem;
+ size_t user_size = size;
size = RTE_CACHE_LINE_ROUNDUP(size);
align = RTE_CACHE_LINE_ROUNDUP(align);
@@ -250,6 +251,8 @@ heap_alloc(struct malloc_heap *heap, const char *type __rte_unused, size_t size,
/* increase heap's count of allocated elements */
heap->alloc_count++;
+
+ asan_set_redzone(elem, user_size);
}
return elem == NULL ? NULL : (void *)(&elem[1]);
@@ -270,6 +273,8 @@ heap_alloc_biggest(struct malloc_heap *heap, const char *type __rte_unused,
/* increase heap's count of allocated elements */
heap->alloc_count++;
+
+ asan_set_redzone(elem, size);
}
return elem == NULL ? NULL : (void *)(&elem[1]);
@@ -841,6 +846,8 @@ malloc_heap_free(struct malloc_elem *elem)
if (!malloc_elem_cookies_ok(elem) || elem->state != ELEM_BUSY)
return -1;
+ asan_clear_redzone(elem);
+
/* elem may be merged with previous element, so keep heap address */
heap = elem->heap;
msl = elem->msl;
@@ -848,6 +855,9 @@ malloc_heap_free(struct malloc_elem *elem)
rte_spinlock_lock(&(heap->lock));
+ void *asan_ptr = RTE_PTR_ADD(elem, MALLOC_ELEM_HEADER_LEN + elem->pad);
+ size_t asan_data_len = elem->size - MALLOC_ELEM_OVERHEAD - elem->pad;
+
/* mark element as free */
elem->state = ELEM_FREE;
@@ -1001,6 +1011,8 @@ malloc_heap_free(struct malloc_elem *elem)
rte_mcfg_mem_write_unlock();
free_unlock:
+ asan_set_freezone(asan_ptr, asan_data_len);
+
rte_spinlock_unlock(&(heap->lock));
return ret;
}
@@ -162,6 +162,8 @@ rte_calloc(const char *type, size_t num, size_t size, unsigned align)
void *
rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket)
{
+ size_t user_size;
+
if (ptr == NULL)
return rte_malloc_socket(NULL, size, align, socket);
@@ -171,6 +173,8 @@ rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket)
return NULL;
}
+ user_size = size;
+
size = RTE_CACHE_LINE_ROUNDUP(size), align = RTE_CACHE_LINE_ROUNDUP(align);
/* check requested socket id and alignment matches first, and if ok,
@@ -181,6 +185,9 @@ rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket)
RTE_PTR_ALIGN(ptr, align) == ptr &&
malloc_heap_resize(elem, size) == 0) {
rte_eal_trace_mem_realloc(size, align, socket, ptr);
+
+ asan_set_redzone(elem, user_size);
+
return ptr;
}
@@ -192,7 +199,7 @@ rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket)
if (new_ptr == NULL)
return NULL;
/* elem: |pad|data_elem|data|trailer| */
- const size_t old_size = elem->size - elem->pad - MALLOC_ELEM_OVERHEAD;
+ const size_t old_size = old_malloc_size(elem);
rte_memcpy(new_ptr, ptr, old_size < size ? old_size : size);
rte_free(ptr);