From a21889174f48434b04997c250369c1e31d69e196 Mon Sep 17 00:00:00 2001 From: Dmitry Valter Date: Thu, 18 Jan 2024 09:09:12 +0000 Subject: vppinfra: fix clib_array_mask_u32 OOB reads Handle non-even n_elts for the larger array instead of reading past the source buffer. Type: fix Fixes: f62ed3f9c1ec3e8db36f63d6a54f46b7bea43723 Signed-off-by: Dmitry Valter Change-Id: Ic1708a3f33fe71ca752345b5c77b6ae7a2d42bcd --- src/vppinfra/test/array_mask.c | 23 ++++++++++++++++++++++- src/vppinfra/vector/array_mask.h | 12 ++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/vppinfra/test/array_mask.c b/src/vppinfra/test/array_mask.c index c3b475c431b..4d8fc7c59e2 100644 --- a/src/vppinfra/test/array_mask.c +++ b/src/vppinfra/test/array_mask.c @@ -83,7 +83,7 @@ static array_mask_test_t tests[] = { static clib_error_t * test_clib_array_mask_u32 (clib_error_t *err) { - u32 i, j; + u32 i, j, len; for (i = 0; i < ARRAY_LEN (tests) - 1; i++) { u32 src[256]; @@ -102,6 +102,27 @@ test_clib_array_mask_u32 (clib_error_t *err) } } + for (i = 0; i < ARRAY_LEN (tests) - 1; i++) + { + for (len = 1; len <= 256; len++) + { + u32 src[len]; + for (j = 0; j < ARRAY_LEN (src); j++) + src[j] = j; + + array_mask_test_t *t = tests + i; + clib_array_mask_u32_wrapper (src, t->mask, ARRAY_LEN (src)); + for (j = 0; j < ARRAY_LEN (src); j++) + { + if (src[j] != t->expected[j]) + return clib_error_return (err, + "testcase %u failed at " + "(src[%u] = 0x%x, expected 0x%x)", + i, j, src[j], t->expected[j]); + } + } + } + u32 src[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; array_mask_test_t *t = tests + i; diff --git a/src/vppinfra/vector/array_mask.h b/src/vppinfra/vector/array_mask.h index 39bcedcd191..ba22d79560f 100644 --- a/src/vppinfra/vector/array_mask.h +++ b/src/vppinfra/vector/array_mask.h @@ -26,8 +26,8 @@ clib_array_mask_u32 (u32 *src, u32 mask, u32 n_elts) u32x16_mask_store (r & mask16, src, m); return; } - for (int i = 0; i < n_elts; i += 16) - *((u32x16u *) (src + i)) &= mask16; + for (; n_elts >= 16; n_elts -= 16, src += 16) + *((u32x16u *) src) &= mask16; *((u32x16u *) (src + n_elts - 16)) &= mask16; #elif defined(CLIB_HAVE_VEC256) u32x8 mask8 = u32x8_splat (mask); @@ -60,8 +60,8 @@ clib_array_mask_u32 (u32 *src, u32 mask, u32 n_elts) } #endif - for (int i = 0; i < n_elts; i += 8) - *((u32x8u *) (src + i)) &= mask8; + for (; n_elts >= 8; n_elts -= 8, src += 8) + *((u32x8u *) src) &= mask8; *((u32x8u *) (src + n_elts - 8)) &= mask8; #elif defined(CLIB_HAVE_VEC128) u32x4 mask4 = u32x4_splat (mask); @@ -79,8 +79,8 @@ clib_array_mask_u32 (u32 *src, u32 mask, u32 n_elts) return; } - for (int i = 0; i < n_elts; i += 4) - *((u32x4u *) (src + i)) &= mask4; + for (; n_elts >= 4; n_elts -= 4, src += 4) + *((u32x4u *) src) &= mask4; *((u32x4u *) (src + n_elts - 4)) &= mask4; return; #else -- cgit 1.2.3-korg