Integer underflow and out-of-bounds read (VPP-1442)
[vpp.git] / src / vppinfra / string.h
index 5a47725..2c794ba 100644 (file)
@@ -324,12 +324,17 @@ clib_memset_u8 (void *p, u8 val, uword count)
 static_always_inline uword
 clib_count_equal_u64 (u64 * data, uword max_count)
 {
-  uword count = 0;
-  u64 first = data[0];
+  uword count;
+  u64 first;
 
+  if (max_count == 1)
+    return 1;
   if (data[0] != data[1])
     return 1;
 
+  count = 0;
+  first = data[0];
+
 #if defined(CLIB_HAVE_VEC256)
   u64x4 splat = u64x4_splat (first);
   while (1)
@@ -351,7 +356,7 @@ clib_count_equal_u64 (u64 * data, uword max_count)
 #endif
   count += 2;
   data += 2;
-  while (count < max_count - 3 &&
+  while (count + 3 < max_count &&
         ((data[0] ^ first) | (data[1] ^ first) |
          (data[2] ^ first) | (data[3] ^ first)) == 0)
     {
@@ -369,12 +374,17 @@ clib_count_equal_u64 (u64 * data, uword max_count)
 static_always_inline uword
 clib_count_equal_u32 (u32 * data, uword max_count)
 {
-  uword count = 0;
-  u32 first = data[0];
+  uword count;
+  u32 first;
 
+  if (max_count == 1)
+    return 1;
   if (data[0] != data[1])
     return 1;
 
+  count = 0;
+  first = data[0];
+
 #if defined(CLIB_HAVE_VEC256)
   u32x8 splat = u32x8_splat (first);
   while (1)
@@ -414,7 +424,7 @@ clib_count_equal_u32 (u32 * data, uword max_count)
 #endif
   count += 2;
   data += 2;
-  while (count < max_count - 3 &&
+  while (count + 3 < max_count &&
         ((data[0] ^ first) | (data[1] ^ first) |
          (data[2] ^ first) | (data[3] ^ first)) == 0)
     {
@@ -432,12 +442,17 @@ clib_count_equal_u32 (u32 * data, uword max_count)
 static_always_inline uword
 clib_count_equal_u16 (u16 * data, uword max_count)
 {
-  uword count = 0;
-  u16 first = data[0];
+  uword count;
+  u16 first;
 
+  if (max_count == 1)
+    return 1;
   if (data[0] != data[1])
     return 1;
 
+  count = 0;
+  first = data[0];
+
 #if defined(CLIB_HAVE_VEC256)
   u16x16 splat = u16x16_splat (first);
   while (1)
@@ -477,7 +492,7 @@ clib_count_equal_u16 (u16 * data, uword max_count)
 #endif
   count += 2;
   data += 2;
-  while (count < max_count - 3 &&
+  while (count + 3 < max_count &&
         ((data[0] ^ first) | (data[1] ^ first) |
          (data[2] ^ first) | (data[3] ^ first)) == 0)
     {
@@ -495,12 +510,17 @@ clib_count_equal_u16 (u16 * data, uword max_count)
 static_always_inline uword
 clib_count_equal_u8 (u8 * data, uword max_count)
 {
-  uword count = 0;
-  u8 first = data[0];
+  uword count;
+  u8 first;
 
+  if (max_count == 1)
+    return 1;
   if (data[0] != data[1])
     return 1;
 
+  count = 0;
+  first = data[0];
+
 #if defined(CLIB_HAVE_VEC256)
   u8x32 splat = u8x32_splat (first);
   while (1)
@@ -540,7 +560,7 @@ clib_count_equal_u8 (u8 * data, uword max_count)
 #endif
   count += 2;
   data += 2;
-  while (count < max_count - 3 &&
+  while (count + 3 < max_count &&
         ((data[0] ^ first) | (data[1] ^ first) |
          (data[2] ^ first) | (data[3] ^ first)) == 0)
     {