]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
locale: Fix UB on VLA allocation
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Tue, 22 Apr 2025 13:50:13 +0000 (10:50 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Wed, 7 May 2025 17:21:21 +0000 (14:21 -0300)
Both level 2 and level 3 sizes can be zero, which triggers a 0-size
VLA.  Reorganize the code to allocate the VLA iff sizes are positive.

locale/programs/3level.h
locale/programs/ld-ctype.c

index 971e0f4c4dc63368f95f1a49ab5d20fec659239c..45ed0f15b098610c425e0e43f38c66f5a02733cf 100644 (file)
@@ -212,58 +212,64 @@ static void
 CONCAT(add_locale_,TABLE) (struct locale_file *file, struct TABLE *t)
 {
   size_t i, j, k;
-  uint32_t reorder3[t->level3_size];
-  uint32_t reorder2[t->level2_size];
   uint32_t level2_offset, level3_offset, last_offset;
 
   /* Uniquify level3 blocks.  */
   k = 0;
-  for (j = 0; j < t->level3_size; j++)
+  if (t->level3_size > 0)
     {
-      for (i = 0; i < k; i++)
-       if (memcmp (&t->level3[i << t->p], &t->level3[j << t->p],
-                   (1 << t->p) * sizeof (ELEMENT)) == 0)
-         break;
-      /* Relocate block j to block i.  */
-      reorder3[j] = i;
-      if (i == k)
+      uint32_t reorder3[t->level3_size];
+      for (j = 0; j < t->level3_size; j++)
        {
-         if (i != j)
-           memcpy (&t->level3[i << t->p], &t->level3[j << t->p],
-                   (1 << t->p) * sizeof (ELEMENT));
-         k++;
+         for (i = 0; i < k; i++)
+           if (memcmp (&t->level3[i << t->p], &t->level3[j << t->p],
+                       (1 << t->p) * sizeof (ELEMENT)) == 0)
+             break;
+         /* Relocate block j to block i.  */
+         reorder3[j] = i;
+         if (i == k)
+           {
+             if (i != j)
+               memcpy (&t->level3[i << t->p], &t->level3[j << t->p],
+                       (1 << t->p) * sizeof (ELEMENT));
+             k++;
+           }
        }
+
+      for (i = 0; i < (t->level2_size << t->q); i++)
+       if (t->level2[i] != EMPTY)
+         t->level2[i] = reorder3[t->level2[i]];
     }
   t->level3_size = k;
 
-  for (i = 0; i < (t->level2_size << t->q); i++)
-    if (t->level2[i] != EMPTY)
-      t->level2[i] = reorder3[t->level2[i]];
-
   /* Uniquify level2 blocks.  */
   k = 0;
-  for (j = 0; j < t->level2_size; j++)
+  if (t->level2_size > 0)
     {
-      for (i = 0; i < k; i++)
-       if (memcmp (&t->level2[i << t->q], &t->level2[j << t->q],
-                   (1 << t->q) * sizeof (uint32_t)) == 0)
-         break;
-      /* Relocate block j to block i.  */
-      reorder2[j] = i;
-      if (i == k)
+      uint32_t reorder2[t->level2_size];
+      for (j = 0; j < t->level2_size; j++)
        {
-         if (i != j)
-           memcpy (&t->level2[i << t->q], &t->level2[j << t->q],
-                   (1 << t->q) * sizeof (uint32_t));
-         k++;
+         for (i = 0; i < k; i++)
+           if (memcmp (&t->level2[i << t->q], &t->level2[j << t->q],
+                       (1 << t->q) * sizeof (uint32_t)) == 0)
+             break;
+         /* Relocate block j to block i.  */
+         reorder2[j] = i;
+         if (i == k)
+           {
+             if (i != j)
+               memcpy (&t->level2[i << t->q], &t->level2[j << t->q],
+                       (1 << t->q) * sizeof (uint32_t));
+             k++;
+           }
        }
+
+      for (i = 0; i < t->level1_size; i++)
+       if (t->level1[i] != EMPTY)
+         t->level1[i] = reorder2[t->level1[i]];
     }
   t->level2_size = k;
 
-  for (i = 0; i < t->level1_size; i++)
-    if (t->level1[i] != EMPTY)
-      t->level1[i] = reorder2[t->level1[i]];
-
   /* Create and fill the resulting compressed representation.  */
   last_offset =
     5 * sizeof (uint32_t)
index 15fd39c6370a6388f89a5da2e1187458c62e9280..4e4f346f35bce3f433744ad18eae17e8573ec052 100644 (file)
@@ -3423,58 +3423,64 @@ static void
 add_locale_wctype_table (struct locale_file *file, struct wctype_table *t)
 {
   size_t i, j, k;
-  uint32_t reorder3[t->level3_size];
-  uint32_t reorder2[t->level2_size];
   uint32_t level2_offset, level3_offset;
 
   /* Uniquify level3 blocks.  */
   k = 0;
-  for (j = 0; j < t->level3_size; j++)
+  if (t->level3_size > 0)
     {
-      for (i = 0; i < k; i++)
-       if (memcmp (&t->level3[i << t->p], &t->level3[j << t->p],
-                   (1 << t->p) * sizeof (uint32_t)) == 0)
-         break;
-      /* Relocate block j to block i.  */
-      reorder3[j] = i;
-      if (i == k)
+      uint32_t reorder3[t->level3_size];
+      for (j = 0; j < t->level3_size; j++)
        {
-         if (i != j)
-           memcpy (&t->level3[i << t->p], &t->level3[j << t->p],
-                   (1 << t->p) * sizeof (uint32_t));
-         k++;
+         for (i = 0; i < k; i++)
+           if (memcmp (&t->level3[i << t->p], &t->level3[j << t->p],
+                       (1 << t->p) * sizeof (uint32_t)) == 0)
+             break;
+         /* Relocate block j to block i.  */
+         reorder3[j] = i;
+         if (i == k)
+           {
+             if (i != j)
+               memcpy (&t->level3[i << t->p], &t->level3[j << t->p],
+                       (1 << t->p) * sizeof (uint32_t));
+             k++;
+           }
        }
+
+      for (i = 0; i < (t->level2_size << t->q); i++)
+       if (t->level2[i] != EMPTY)
+         t->level2[i] = reorder3[t->level2[i]];
     }
   t->level3_size = k;
 
-  for (i = 0; i < (t->level2_size << t->q); i++)
-    if (t->level2[i] != EMPTY)
-      t->level2[i] = reorder3[t->level2[i]];
-
   /* Uniquify level2 blocks.  */
   k = 0;
-  for (j = 0; j < t->level2_size; j++)
+  if (t->level2_size > 0)
     {
-      for (i = 0; i < k; i++)
-       if (memcmp (&t->level2[i << t->q], &t->level2[j << t->q],
-                   (1 << t->q) * sizeof (uint32_t)) == 0)
-         break;
-      /* Relocate block j to block i.  */
-      reorder2[j] = i;
-      if (i == k)
+      uint32_t reorder2[t->level2_size];
+      for (j = 0; j < t->level2_size; j++)
        {
-         if (i != j)
-           memcpy (&t->level2[i << t->q], &t->level2[j << t->q],
-                   (1 << t->q) * sizeof (uint32_t));
-         k++;
+         for (i = 0; i < k; i++)
+           if (memcmp (&t->level2[i << t->q], &t->level2[j << t->q],
+                       (1 << t->q) * sizeof (uint32_t)) == 0)
+             break;
+         /* Relocate block j to block i.  */
+         reorder2[j] = i;
+         if (i == k)
+           {
+             if (i != j)
+               memcpy (&t->level2[i << t->q], &t->level2[j << t->q],
+                       (1 << t->q) * sizeof (uint32_t));
+             k++;
+           }
        }
+
+      for (i = 0; i < t->level1_size; i++)
+       if (t->level1[i] != EMPTY)
+         t->level1[i] = reorder2[t->level1[i]];
     }
   t->level2_size = k;
 
-  for (i = 0; i < t->level1_size; i++)
-    if (t->level1[i] != EMPTY)
-      t->level1[i] = reorder2[t->level1[i]];
-
   t->result_size =
     5 * sizeof (uint32_t)
     + t->level1_size * sizeof (uint32_t)