vppinfra: fix clib_array_mask_u32 OOB reads 51/40151/5
authorDmitry Valter <d-valter@yandex-team.com>
Thu, 18 Jan 2024 09:09:12 +0000 (09:09 +0000)
committerDamjan Marion <dmarion@0xa5.net>
Tue, 23 Jan 2024 22:39:43 +0000 (22:39 +0000)
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 <d-valter@yandex-team.com>
Change-Id: Ic1708a3f33fe71ca752345b5c77b6ae7a2d42bcd

src/vppinfra/test/array_mask.c
src/vppinfra/vector/array_mask.h

index c3b475c..4d8fc7c 100644 (file)
@@ -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;
 
index 39bcedc..ba22d79 100644 (file)
@@ -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