From 8263888f463b566e77e8243763e05c35d20bb4d7 Mon Sep 17 00:00:00 2001 From: Dmitry Valter Date: Fri, 5 Jan 2024 14:28:08 +0000 Subject: vppinfra: fix vec_prepend use-after-free Don't access free'd memory in vec_prepend. Don't allow prepend when v1 == v2 as it also causes a use-after-free. Found via ASAN. Type: fix Signed-off-by: Dmitry Valter Change-Id: I21f8422c007d07d40d237e873b84c042be1fe8e8 --- src/vppinfra/vec.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/vppinfra/vec.h') diff --git a/src/vppinfra/vec.h b/src/vppinfra/vec.h index 607fc282897..1a64a69a1e6 100644 --- a/src/vppinfra/vec.h +++ b/src/vppinfra/vec.h @@ -1067,26 +1067,28 @@ _vec_append (void **v1p, void *v2, uword v1_elt_sz, uword v2_elt_sz, #define vec_append(v1, v2) vec_append_aligned (v1, v2, 0) static_always_inline void -_vec_prepend (void **v1p, void *v2, uword v1_elt_sz, uword v2_elt_sz, - uword align) +_vec_prepend (void *restrict *v1p, void *restrict v2, uword v1_elt_sz, + uword v2_elt_sz, uword align) { - void *v1 = v1p[0]; + void *restrict v1 = v1p[0]; uword len1 = vec_len (v1); uword len2 = vec_len (v2); if (PREDICT_TRUE (len2 > 0)) { + /* prepending vector to itself would result in use-after-free */ + ASSERT (v1 != v2); const vec_attr_t va = { .elt_sz = v2_elt_sz, .align = align }; v1 = _vec_resize_internal (v1, len1 + len2, &va); - clib_memmove (v1 + len2 * v2_elt_sz, v1p[0], len1 * v1_elt_sz); + clib_memmove (v1 + len2 * v2_elt_sz, v1, len1 * v1_elt_sz); clib_memcpy_fast (v1, v2, len2 * v2_elt_sz); - _vec_update_pointer (v1p, v1); + _vec_update_pointer ((void **) v1p, v1); } } /** \brief Prepend v2 before v1. Result in v1. Specified alignment @param V1 target vector - @param V2 vector to prepend + @param V2 vector to prepend, V1 != V2 @param align required alignment */ @@ -1096,7 +1098,7 @@ _vec_prepend (void **v1p, void *v2, uword v1_elt_sz, uword v2_elt_sz, /** \brief Prepend v2 before v1. Result in v1. @param V1 target vector - @param V2 vector to prepend + @param V2 vector to prepend, V1 != V2 */ #define vec_prepend(v1, v2) vec_prepend_aligned (v1, v2, 0) -- cgit 1.2.3-korg