From: Bruno Haible <bruno@clisp.org>
Date: Sun, 25 Oct 2020 17:03:34 +0000 (+0100)
Subject: ssfmalloc: Fix buffer overrun in bitmap search.
X-Git-Tag: v1.0~3550
X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=c433211e54786e26b9c787f3d4a4212536ffaa46;p=gnulib.git

ssfmalloc: Fix buffer overrun in bitmap search.

* lib/ssfmalloc-bitmap.h (find_first_packet_set): Don't access the
word *words_end.
---

diff --git a/ChangeLog b/ChangeLog
index 8fa32e1ecc..ed0195d760 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2020-10-25  Bruno Haible  <bruno@clisp.org>
+
+	ssfmalloc: Fix buffer overrun in bitmap search.
+	* lib/ssfmalloc-bitmap.h (find_first_packet_set): Don't access the
+	word *words_end.
+
 2020-10-24  Paul Eggert  <eggert@cs.ucla.edu>
 
 	doc: mention ‘restrict’ and C++
diff --git a/lib/ssfmalloc-bitmap.h b/lib/ssfmalloc-bitmap.h
index abf9949b3a..741067529b 100644
--- a/lib/ssfmalloc-bitmap.h
+++ b/lib/ssfmalloc-bitmap.h
@@ -92,217 +92,217 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
       }
     case 2:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t combined = longword & (longword >> 1);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 3:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t combined = longword & (longword >> 1) & (longword >> 2);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 4:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t combined = tmp1 & (tmp1 >> 2);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 5:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t combined = tmp2 & (longword >> 4);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 6:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t combined = tmp1 & (tmp1 >> 2) & (tmp1 >> 4);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 7:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t combined =
               tmp1 & (tmp1 >> 2) & (tmp1 >> 4) & (longword >> 6);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 8:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t combined = tmp2 & (tmp2 >> 4);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 9:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
             uint64_t combined = tmp3 & (longword >> 8);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 10:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
             uint64_t combined = tmp3 & (tmp1 >> 8);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 11:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
             uint64_t combined = tmp3 & (tmp1 >> 8) & (longword >> 10);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 12:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t combined = tmp2 & (tmp2 >> 4) & (tmp2 >> 8);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 13:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t combined =
               tmp2 & (tmp2 >> 4) & (tmp2 >> 8) & (longword >> 12);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 14:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t combined = tmp2 & (tmp2 >> 4) & (tmp2 >> 8) & (tmp1 >> 12);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 15:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             /* Optimized: Use 5, not 6, '&' operations.  */
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
@@ -310,34 +310,34 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp3 & (tmp3 >> 5) & (tmp3 >> 10);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 16:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
             uint64_t combined = tmp3 & (tmp3 >> 8);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 17:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -345,17 +345,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (longword >> 16);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 18:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -363,17 +363,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp1 >> 16);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 19:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -381,17 +381,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp1 >> 16) & (longword >> 18);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 20:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -399,17 +399,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp2 >> 16);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 21:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -417,17 +417,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp2 >> 16) & (longword >> 20);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 22:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -435,17 +435,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp2 >> 16) & (tmp1 >> 20);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 23:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -454,34 +454,34 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp4 & (tmp2 >> 16) & (tmp1 >> 20) & (longword >> 22);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 24:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
             uint64_t combined = tmp3 & (tmp3 >> 8) & (tmp3 >> 16);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 25:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -489,17 +489,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp3 & (tmp3 >> 8) & (tmp3 >> 16) & (longword >> 24);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 26:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -507,17 +507,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp3 & (tmp3 >> 8) & (tmp3 >> 16) & (tmp1 >> 24);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 27:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             /* Optimized: Use 6, not 7, '&' operations.  */
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
@@ -526,17 +526,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp4 >> 9) & (tmp4 >> 18);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 28:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -544,17 +544,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp3 & (tmp3 >> 8) & (tmp3 >> 16) & (tmp2 >> 24);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 29:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -562,17 +562,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp3 & (tmp3 >> 8) & (tmp3 >> 16) & (tmp2 >> 24) & (longword >> 28);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 30:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             /* Optimized: Use 6, not 7, '&' operations.  */
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
@@ -581,17 +581,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp4 >> 10) & (tmp4 >> 20);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 31:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -600,17 +600,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp4 & (tmp3 >> 16) & (tmp2 >> 24) & (tmp1 >> 28) & (longword >> 30);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 32:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -618,7 +618,7 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp4 >> 16);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }