From: Adhemerval Zanella Date: Tue, 22 Apr 2025 13:50:13 +0000 (-0300) Subject: locale: Fix UB on VLA allocation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eadfcdb2b93a85155051cd3a08edfc2025a72bca;p=thirdparty%2Fglibc.git locale: Fix UB on VLA allocation 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. --- diff --git a/locale/programs/3level.h b/locale/programs/3level.h index 971e0f4c4d..45ed0f15b0 100644 --- a/locale/programs/3level.h +++ b/locale/programs/3level.h @@ -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) diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c index 15fd39c637..4e4f346f35 100644 --- a/locale/programs/ld-ctype.c +++ b/locale/programs/ld-ctype.c @@ -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)