[glibc] Resync with upstream master
Siddhesh Poyarekar
siddhesh at fedoraproject.org
Thu Sep 5 12:05:44 UTC 2013
commit 35b7508499170e8a9e9466499e4ccb82e51e353b
Author: Siddhesh Poyarekar <siddhesh at redhat.com>
Date: Thu Sep 5 17:37:40 2013 +0530
Resync with upstream master
glibc-rh1000924.patch | 24 --
glibc-rh800224.patch | 78 ----
glibc-rh985342.patch | 23 --
glibc-rh995841.patch | 302 ---------------
glibc-strcoll-cve.patch | 940 ++++++++++-------------------------------------
glibc.spec | 26 +-
sources | 2 +-
7 files changed, 206 insertions(+), 1189 deletions(-)
---
diff --git a/glibc-strcoll-cve.patch b/glibc-strcoll-cve.patch
index 5558c1f..7c220f4 100644
--- a/glibc-strcoll-cve.patch
+++ b/glibc-strcoll-cve.patch
@@ -1,203 +1,74 @@
+diff --git a/string/Makefile b/string/Makefile
+index aaad743..f70dc7a 100644
+--- a/string/Makefile
++++ b/string/Makefile
+@@ -57,6 +57,8 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \
+ tests-ifunc := $(strop-tests:%=test-%-ifunc)
+ tests += $(tests-ifunc)
+
++xtests = tst-strcoll-overflow
++
+ include ../Rules
+
+ tester-ENV = LANGUAGE=C
diff --git a/string/strcoll_l.c b/string/strcoll_l.c
-index ecda08f..bb34a72 100644
+index 50ed84d..4ee101a 100644
--- a/string/strcoll_l.c
+++ b/string/strcoll_l.c
-@@ -41,11 +41,434 @@
-
- #include "../locale/localeinfo.h"
-
-+/* Track status while looking for sequences in a string. */
-+typedef struct
-+{
-+ int len; /* Length of the current sequence. */
+@@ -45,7 +45,7 @@
+ typedef struct
+ {
+ int len; /* Length of the current sequence. */
+- int val; /* Position of the sequence relative to the
+ size_t val; /* Position of the sequence relative to the
-+ previous non-ignored sequence. */
-+ size_t idxnow; /* Current index in sequences. */
-+ size_t idxmax; /* Maximum index in sequences. */
-+ size_t idxcnt; /* Current count of indices. */
-+ size_t backw; /* Current Backward sequence index. */
-+ size_t backw_stop; /* Index where the backward sequences stop. */
-+ const USTRING_TYPE *us; /* The string. */
-+ int32_t *idxarr; /* Array to cache weight indices. */
-+ unsigned char *rulearr; /* Array to cache rules. */
+ previous non-ignored sequence. */
+ size_t idxnow; /* Current index in sequences. */
+ size_t idxmax; /* Maximum index in sequences. */
+@@ -55,6 +55,12 @@ typedef struct
+ const USTRING_TYPE *us; /* The string. */
+ int32_t *idxarr; /* Array to cache weight indices. */
+ unsigned char *rulearr; /* Array to cache rules. */
+ unsigned char rule; /* Saved rule for the first sequence. */
+ int32_t idx; /* Index to weight of the current sequence. */
+ int32_t save_idx; /* Save looked up index of a forward
+ sequence after the last backward
+ sequence. */
+ const USTRING_TYPE *back_us; /* Beginning of the backward sequence. */
-+} coll_seq;
-+
-+/* Get next sequence. The weight indices are cached, so we don't need to
-+ traverse the string. */
-+static void
-+get_next_seq_cached (coll_seq *seq, int nrules, int pass,
-+ const unsigned char *rulesets,
-+ const USTRING_TYPE *weights)
-+{
+ } coll_seq;
+
+ /* Get next sequence. The weight indices are cached, so we don't need to
+@@ -64,7 +70,7 @@ get_next_seq_cached (coll_seq *seq, int nrules, int pass,
+ const unsigned char *rulesets,
+ const USTRING_TYPE *weights)
+ {
+- int val = seq->val = 0;
+ size_t val = seq->val = 0;
-+ int len = seq->len;
-+ size_t backw_stop = seq->backw_stop;
-+ size_t backw = seq->backw;
-+ size_t idxcnt = seq->idxcnt;
-+ size_t idxmax = seq->idxmax;
-+ size_t idxnow = seq->idxnow;
-+ unsigned char *rulearr = seq->rulearr;
-+ int32_t *idxarr = seq->idxarr;
-+
-+ while (len == 0)
-+ {
-+ ++val;
-+ if (backw_stop != ~0ul)
-+ {
-+ /* There is something pushed. */
-+ if (backw == backw_stop)
-+ {
-+ /* The last pushed character was handled. Continue
-+ with forward characters. */
-+ if (idxcnt < idxmax)
-+ {
-+ idxnow = idxcnt;
-+ backw_stop = ~0ul;
-+ }
-+ else
-+ {
-+ /* Nothing any more. The backward sequence
-+ ended with the last sequence in the string. */
-+ idxnow = ~0ul;
-+ break;
-+ }
-+ }
-+ else
-+ idxnow = --backw;
-+ }
-+ else
-+ {
-+ backw_stop = idxcnt;
-+
-+ while (idxcnt < idxmax)
-+ {
-+ if ((rulesets[rulearr[idxcnt] * nrules + pass]
-+ & sort_backward) == 0)
-+ /* No more backward characters to push. */
-+ break;
-+ ++idxcnt;
-+ }
-+
-+ if (backw_stop == idxcnt)
-+ {
-+ /* No sequence at all or just one. */
-+ if (idxcnt == idxmax)
-+ /* Note that LEN is still zero. */
-+ break;
-+
-+ backw_stop = ~0ul;
-+ idxnow = idxcnt++;
-+ }
-+ else
-+ /* We pushed backward sequences. */
-+ idxnow = backw = idxcnt - 1;
-+ }
-+ len = weights[idxarr[idxnow]++];
-+ }
-+
-+ /* Update the structure. */
-+ seq->val = val;
-+ seq->len = len;
-+ seq->backw_stop = backw_stop;
-+ seq->backw = backw;
-+ seq->idxcnt = idxcnt;
-+ seq->idxnow = idxnow;
-+}
-+
-+/* Get next sequence. Traverse the string as required. */
-+static void
-+get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets,
-+ const USTRING_TYPE *weights, const int32_t *table,
-+ const USTRING_TYPE *extra, const int32_t *indirect)
-+{
-+#include WEIGHT_H
+ int len = seq->len;
+ size_t backw_stop = seq->backw_stop;
+ size_t backw = seq->backw;
+@@ -146,7 +152,7 @@ get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets,
+ const USTRING_TYPE *extra, const int32_t *indirect)
+ {
+ #include WEIGHT_H
+- int val = seq->val = 0;
+ size_t val = seq->val = 0;
-+ int len = seq->len;
-+ size_t backw_stop = seq->backw_stop;
-+ size_t backw = seq->backw;
-+ size_t idxcnt = seq->idxcnt;
-+ size_t idxmax = seq->idxmax;
-+ size_t idxnow = seq->idxnow;
-+ unsigned char *rulearr = seq->rulearr;
-+ int32_t *idxarr = seq->idxarr;
-+ const USTRING_TYPE *us = seq->us;
-+
-+ while (len == 0)
-+ {
-+ ++val;
-+ if (backw_stop != ~0ul)
-+ {
+ int len = seq->len;
+ size_t backw_stop = seq->backw_stop;
+ size_t backw = seq->backw;
+@@ -162,7 +168,7 @@ get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets,
+ ++val;
+ if (backw_stop != ~0ul)
+ {
+- /* The is something pushed. */
+ /* There is something pushed. */
-+ if (backw == backw_stop)
-+ {
-+ /* The last pushed character was handled. Continue
-+ with forward characters. */
-+ if (idxcnt < idxmax)
-+ {
-+ idxnow = idxcnt;
-+ backw_stop = ~0ul;
-+ }
-+ else
-+ /* Nothing any more. The backward sequence ended with
-+ the last sequence in the string. Note that LEN
-+ is still zero. */
-+ break;
-+ }
-+ else
-+ idxnow = --backw;
-+ }
-+ else
-+ {
-+ backw_stop = idxmax;
-+
-+ while (*us != L('\0'))
-+ {
-+ int32_t tmp = findidx (&us, -1);
-+ rulearr[idxmax] = tmp >> 24;
-+ idxarr[idxmax] = tmp & 0xffffff;
-+ idxcnt = idxmax++;
-+
-+ if ((rulesets[rulearr[idxcnt] * nrules]
-+ & sort_backward) == 0)
-+ /* No more backward characters to push. */
-+ break;
-+ ++idxcnt;
-+ }
-+
-+ if (backw_stop >= idxcnt)
-+ {
-+ /* No sequence at all or just one. */
-+ if (idxcnt == idxmax || backw_stop > idxcnt)
-+ /* Note that LEN is still zero. */
-+ break;
-+
-+ backw_stop = ~0ul;
-+ idxnow = idxcnt;
-+ }
-+ else
-+ /* We pushed backward sequences. */
-+ idxnow = backw = idxcnt - 1;
-+ }
-+ len = weights[idxarr[idxnow]++];
-+ }
-+
-+ /* Update the structure. */
-+ seq->val = val;
-+ seq->len = len;
-+ seq->backw_stop = backw_stop;
-+ seq->backw = backw;
-+ seq->idxcnt = idxcnt;
-+ seq->idxmax = idxmax;
-+ seq->idxnow = idxnow;
-+ seq->us = us;
-+}
-+
+ if (backw == backw_stop)
+ {
+ /* The last pushed character was handled. Continue
+@@ -227,15 +233,199 @@ get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets,
+ seq->us = us;
+ }
+
+-/* Compare two sequences. */
+/* Get next sequence. Traverse the string as required. This function does not
+ set or use any index or rule cache. */
+static void
@@ -383,396 +254,97 @@ index ecda08f..bb34a72 100644
+}
+
+/* Compare two sequences using the index cache. */
-+static int
-+do_compare (coll_seq *seq1, coll_seq *seq2, int position,
-+ const USTRING_TYPE *weights)
-+{
-+ int seq1len = seq1->len;
-+ int seq2len = seq2->len;
+ static int
+ do_compare (coll_seq *seq1, coll_seq *seq2, int position,
+ const USTRING_TYPE *weights)
+ {
+ int seq1len = seq1->len;
+ int seq2len = seq2->len;
+- int val1 = seq1->val;
+- int val2 = seq2->val;
+ size_t val1 = seq1->val;
+ size_t val2 = seq2->val;
-+ int32_t *idx1arr = seq1->idxarr;
-+ int32_t *idx2arr = seq2->idxarr;
-+ int idx1now = seq1->idxnow;
-+ int idx2now = seq2->idxnow;
-+ int result = 0;
-+
-+ /* Test for position if necessary. */
-+ if (position && val1 != val2)
-+ {
+ int32_t *idx1arr = seq1->idxarr;
+ int32_t *idx2arr = seq2->idxarr;
+ int idx1now = seq1->idxnow;
+@@ -245,7 +435,7 @@ do_compare (coll_seq *seq1, coll_seq *seq2, int position,
+ /* Test for position if necessary. */
+ if (position && val1 != val2)
+ {
+- result = val1 - val2;
+ result = val1 > val2 ? 1 : -1;
-+ goto out;
-+ }
-+
-+ /* Compare the two sequences. */
-+ do
-+ {
-+ if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]])
-+ {
-+ /* The sequences differ. */
-+ result = weights[idx1arr[idx1now]] - weights[idx2arr[idx2now]];
-+ goto out;
-+ }
-+
-+ /* Increment the offsets. */
-+ ++idx1arr[idx1now];
-+ ++idx2arr[idx2now];
-+
-+ --seq1len;
-+ --seq2len;
-+ }
-+ while (seq1len > 0 && seq2len > 0);
-+
-+ if (position && seq1len != seq2len)
-+ result = seq1len - seq2len;
-+
-+out:
-+ seq1->len = seq1len;
-+ seq2->len = seq2len;
-+ return result;
-+}
-+
- int
--STRCOLL (s1, s2, l)
-- const STRING_TYPE *s1;
-- const STRING_TYPE *s2;
-- __locale_t l;
-+STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
- {
- struct __locale_data *current = l->__locales[LC_COLLATE];
- uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
-@@ -56,34 +479,6 @@ STRCOLL (s1, s2, l)
- const USTRING_TYPE *weights;
- const USTRING_TYPE *extra;
- const int32_t *indirect;
-- uint_fast32_t pass;
-- int result = 0;
-- const USTRING_TYPE *us1;
-- const USTRING_TYPE *us2;
-- size_t s1len;
-- size_t s2len;
-- int32_t *idx1arr;
-- int32_t *idx2arr;
-- unsigned char *rule1arr;
-- unsigned char *rule2arr;
-- size_t idx1max;
-- size_t idx2max;
-- size_t idx1cnt;
-- size_t idx2cnt;
-- size_t idx1now;
-- size_t idx2now;
-- size_t backw1_stop;
-- size_t backw2_stop;
-- size_t backw1;
-- size_t backw2;
-- int val1;
-- int val2;
-- int position;
-- int seq1len;
-- int seq2len;
-- int use_malloc;
--
--#include WEIGHT_H
-
- if (nrules == 0)
- return STRCMP (s1, s2);
-@@ -98,7 +493,6 @@ STRCOLL (s1, s2, l)
- current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
- indirect = (const int32_t *)
- current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
-- use_malloc = 0;
-
- assert (((uintptr_t) table) % __alignof__ (table[0]) == 0);
- assert (((uintptr_t) weights) % __alignof__ (weights[0]) == 0);
-@@ -106,18 +500,13 @@ STRCOLL (s1, s2, l)
- assert (((uintptr_t) indirect) % __alignof__ (indirect[0]) == 0);
-
- /* We need this a few times. */
-- s1len = STRLEN (s1);
-- s2len = STRLEN (s2);
-+ size_t s1len = STRLEN (s1);
-+ size_t s2len = STRLEN (s2);
+ goto out;
+ }
- /* Catch empty strings. */
-- if (__builtin_expect (s1len == 0, 0) || __builtin_expect (s2len == 0, 0))
-+ if (__glibc_unlikely (s1len == 0) || __glibc_unlikely (s2len == 0))
- return (s1len != 0) - (s2len != 0);
+@@ -334,57 +524,70 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+ memset (&seq1, 0, sizeof (seq1));
+ seq2 = seq1;
- /* We need the elements of the strings as unsigned values since they
-- are used as indeces. */
-- us1 = (const USTRING_TYPE *) s1;
-- us2 = (const USTRING_TYPE *) s2;
--
- /* Perform the first pass over the string and while doing this find
- and store the weights for each character. Since we want this to
- be as fast as possible we are using `alloca' to store the temporary
-@@ -127,411 +516,124 @@ STRCOLL (s1, s2, l)
+- are used as indices. */
+- seq1.us = (const USTRING_TYPE *) s1;
+- seq2.us = (const USTRING_TYPE *) s2;
++ size_t size_max = SIZE_MAX / (sizeof (int32_t) + 1);
- Please note that the localedef programs makes sure that `position'
- is not used at the first level. */
- if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1)))
-- {
-- idx1arr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1));
-- idx2arr = &idx1arr[s1len];
-- rule1arr = (unsigned char *) &idx2arr[s2len];
-- rule2arr = &rule1arr[s1len];
++ if (MIN (s1len, s2len) > size_max
++ || MAX (s1len, s2len) > size_max - MIN (s1len, s2len))
++ {
++ /* If the strings are long enough to cause overflow in the size request,
++ then skip the allocation and proceed with the non-cached routines. */
++ }
++ else if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1)))
+ {
+ seq1.idxarr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1));
+- seq2.idxarr = &seq1.idxarr[s1len];
+- seq1.rulearr = (unsigned char *) &seq2.idxarr[s2len];
+- seq2.rulearr = &seq1.rulearr[s1len];
-
-- if (idx1arr == NULL)
+- if (seq1.idxarr == NULL)
- /* No memory. Well, go with the stack then.
-
- XXX Once this implementation is stable we will handle this
-- differently. Instead of precomputing the indeces we will
+- differently. Instead of precomputing the indices we will
- do this in time. This means, though, that this happens for
- every pass again. */
- goto try_stack;
-- use_malloc = 1;
-- }
-- else
-- {
-- try_stack:
-- idx1arr = (int32_t *) alloca (s1len * sizeof (int32_t));
-- idx2arr = (int32_t *) alloca (s2len * sizeof (int32_t));
-- rule1arr = (unsigned char *) alloca (s1len);
-- rule2arr = (unsigned char *) alloca (s2len);
-- }
-
-- idx1cnt = 0;
-- idx2cnt = 0;
-- idx1max = 0;
-- idx2max = 0;
-- idx1now = 0;
-- idx2now = 0;
-- backw1_stop = ~0ul;
-- backw2_stop = ~0ul;
-- backw1 = ~0ul;
-- backw2 = ~0ul;
-- seq1len = 0;
-- seq2len = 0;
-- position = rulesets[0] & sort_position;
-- while (1)
-- {
-- val1 = 0;
-- val2 = 0;
--
-- /* Get the next non-IGNOREd element for string `s1'. */
-- if (seq1len == 0)
-- do
-- {
-- ++val1;
--
-- if (backw1_stop != ~0ul)
-- {
-- /* The is something pushed. */
-- if (backw1 == backw1_stop)
-- {
-- /* The last pushed character was handled. Continue
-- with forward characters. */
-- if (idx1cnt < idx1max)
-- {
-- idx1now = idx1cnt;
-- backw1_stop = ~0ul;
-- }
-- else
-- /* Nothing anymore. The backward sequence ended with
-- the last sequence in the string. Note that seq1len
-- is still zero. */
-- break;
-- }
-- else
-- idx1now = --backw1;
-- }
-- else
-- {
-- backw1_stop = idx1max;
--
-- while (*us1 != L('\0'))
-- {
-- int32_t tmp = findidx (&us1, -1);
-- rule1arr[idx1max] = tmp >> 24;
-- idx1arr[idx1max] = tmp & 0xffffff;
-- idx1cnt = idx1max++;
--
-- if ((rulesets[rule1arr[idx1cnt] * nrules]
-- & sort_backward) == 0)
-- /* No more backward characters to push. */
-- break;
-- ++idx1cnt;
-- }
--
-- if (backw1_stop >= idx1cnt)
-- {
-- /* No sequence at all or just one. */
-- if (idx1cnt == idx1max || backw1_stop > idx1cnt)
-- /* Note that seq1len is still zero. */
-- break;
--
-- backw1_stop = ~0ul;
-- idx1now = idx1cnt;
-- }
-- else
-- /* We pushed backward sequences. */
-- idx1now = backw1 = idx1cnt - 1;
-- }
-- }
-- while ((seq1len = weights[idx1arr[idx1now]++]) == 0);
--
-- /* And the same for string `s2'. */
-- if (seq2len == 0)
-- do
-- {
-- ++val2;
--
-- if (backw2_stop != ~0ul)
-- {
-- /* The is something pushed. */
-- if (backw2 == backw2_stop)
-- {
-- /* The last pushed character was handled. Continue
-- with forward characters. */
-- if (idx2cnt < idx2max)
-- {
-- idx2now = idx2cnt;
-- backw2_stop = ~0ul;
-- }
-- else
-- /* Nothing anymore. The backward sequence ended with
-- the last sequence in the string. Note that seq2len
-- is still zero. */
-- break;
-- }
-- else
-- idx2now = --backw2;
-- }
-- else
-- {
-- backw2_stop = idx2max;
--
-- while (*us2 != L('\0'))
-- {
-- int32_t tmp = findidx (&us2, -1);
-- rule2arr[idx2max] = tmp >> 24;
-- idx2arr[idx2max] = tmp & 0xffffff;
-- idx2cnt = idx2max++;
--
-- if ((rulesets[rule2arr[idx2cnt] * nrules]
-- & sort_backward) == 0)
-- /* No more backward characters to push. */
-- break;
-- ++idx2cnt;
-- }
--
-- if (backw2_stop >= idx2cnt)
-- {
-- /* No sequence at all or just one. */
-- if (idx2cnt == idx2max || backw2_stop > idx2cnt)
-- /* Note that seq1len is still zero. */
-- break;
--
-- backw2_stop = ~0ul;
-- idx2now = idx2cnt;
-- }
-- else
-- /* We pushed backward sequences. */
-- idx2now = backw2 = idx2cnt - 1;
-- }
-- }
-- while ((seq2len = weights[idx2arr[idx2now]++]) == 0);
--
-- /* See whether any or both strings are empty. */
-- if (seq1len == 0 || seq2len == 0)
-- {
-- if (seq1len == seq2len)
-- /* Both ended. So far so good, both strings are equal at the
-- first level. */
-- break;
--
-- /* This means one string is shorter than the other. Find out
-- which one and return an appropriate value. */
-- result = seq1len == 0 ? -1 : 1;
-- goto free_and_return;
-- }
-+ coll_seq seq1, seq2;
-+ bool use_malloc = false;
-+ int result = 0;
-
-- /* Test for position if necessary. */
-- if (position && val1 != val2)
-- {
-- result = val1 - val2;
-- goto free_and_return;
-- }
-+ memset (&seq1, 0, sizeof (seq1));
-+ seq2 = seq1;
-
-- /* Compare the two sequences. */
-- do
-- {
-- if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]])
-- {
-- /* The sequences differ. */
-- result = weights[idx1arr[idx1now]] - weights[idx2arr[idx2now]];
-- goto free_and_return;
-- }
-+ size_t size_max = SIZE_MAX / (sizeof (int32_t) + 1);
-
-- /* Increment the offsets. */
-- ++idx1arr[idx1now];
-- ++idx2arr[idx2now];
-+ /* If the strings are long enough to cause overflow in the size request, then
-+ skip the allocation and proceed with the non-cached routines. */
-+ if (MIN (s1len, s2len) > size_max
-+ || MAX (s1len, s2len) > size_max - MIN (s1len, s2len))
-+ goto begin_collate;
-
-- --seq1len;
-- --seq2len;
-- }
-- while (seq1len > 0 && seq2len > 0);
-+ if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1)))
-+ {
-+ seq1.idxarr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1));
-
-- if (position && seq1len != seq2len)
+- use_malloc = true;
++
+ /* If we failed to allocate memory, we leave everything as NULL so that
+ we use the nocache version of traversal and comparison functions. */
+ if (seq1.idxarr != NULL)
- {
-- result = seq1len - seq2len;
-- goto free_and_return;
++ {
+ seq2.idxarr = &seq1.idxarr[s1len];
+ seq1.rulearr = (unsigned char *) &seq2.idxarr[s2len];
+ seq2.rulearr = &seq1.rulearr[s1len];
+ use_malloc = true;
- }
++ }
+ }
+ else
+ {
+- try_stack:
+ seq1.idxarr = (int32_t *) alloca (s1len * sizeof (int32_t));
+ seq2.idxarr = (int32_t *) alloca (s2len * sizeof (int32_t));
+ seq1.rulearr = (unsigned char *) alloca (s1len);
+ seq2.rulearr = (unsigned char *) alloca (s2len);
}
-+ else
-+ {
-+ seq1.idxarr = (int32_t *) alloca (s1len * sizeof (int32_t));
-+ seq2.idxarr = (int32_t *) alloca (s2len * sizeof (int32_t));
-+ seq1.rulearr = (unsigned char *) alloca (s1len);
-+ seq2.rulearr = (unsigned char *) alloca (s2len);
-+ }
-- /* Now the remaining passes over the weights. We now use the
-- indeces we found before. */
-- for (pass = 1; pass < nrules; ++pass)
-+ int rule;
-+
-+ begin_collate:
-+ rule = 0;
-+ /* Cache values in the first pass and if needed, use them in subsequent
-+ passes. */
-+ for (int pass = 0; pass < nrules; ++pass)
+- seq1.rulearr[0] = 0;
++ int rule = 0;
+
+ /* Cache values in the first pass and if needed, use them in subsequent
+ passes. */
+ for (int pass = 0; pass < nrules; ++pass)
{
-+ seq1.idxcnt = 0;
+ seq1.idxcnt = 0;
+ seq1.idx = 0;
+ seq2.idx = 0;
-+ seq1.backw_stop = ~0ul;
-+ seq1.backw = ~0ul;
-+ seq2.idxcnt = 0;
-+ seq2.backw_stop = ~0ul;
-+ seq2.backw = ~0ul;
-+
+ seq1.backw_stop = ~0ul;
+ seq1.backw = ~0ul;
+ seq2.idxcnt = 0;
+ seq2.backw_stop = ~0ul;
+ seq2.backw = ~0ul;
+
+ /* We need the elements of the strings as unsigned values since they
+ are used as indices. */
+ seq1.us = (const USTRING_TYPE *) s1;
@@ -780,137 +352,12 @@ index ecda08f..bb34a72 100644
+
/* We assume that if a rule has defined `position' in one section
this is true for all of them. */
-- idx1cnt = 0;
-- idx2cnt = 0;
-- backw1_stop = ~0ul;
-- backw2_stop = ~0ul;
-- backw1 = ~0ul;
-- backw2 = ~0ul;
-- position = rulesets[rule1arr[0] * nrules + pass] & sort_position;
+- int position = rulesets[seq1.rulearr[0] * nrules + pass] & sort_position;
+ int position = rulesets[rule * nrules + pass] & sort_position;
while (1)
{
-- val1 = 0;
-- val2 = 0;
--
-- /* Get the next non-IGNOREd element for string `s1'. */
-- if (seq1len == 0)
-- do
-- {
-- ++val1;
--
-- if (backw1_stop != ~0ul)
-- {
-- /* The is something pushed. */
-- if (backw1 == backw1_stop)
-- {
-- /* The last pushed character was handled. Continue
-- with forward characters. */
-- if (idx1cnt < idx1max)
-- {
-- idx1now = idx1cnt;
-- backw1_stop = ~0ul;
-- }
-- else
-- {
-- /* Nothing anymore. The backward sequence
-- ended with the last sequence in the string. */
-- idx1now = ~0ul;
-- break;
-- }
-- }
-- else
-- idx1now = --backw1;
-- }
-- else
-- {
-- backw1_stop = idx1cnt;
--
-- while (idx1cnt < idx1max)
-- {
-- if ((rulesets[rule1arr[idx1cnt] * nrules + pass]
-- & sort_backward) == 0)
-- /* No more backward characters to push. */
-- break;
-- ++idx1cnt;
-- }
--
-- if (backw1_stop == idx1cnt)
-- {
-- /* No sequence at all or just one. */
-- if (idx1cnt == idx1max)
-- /* Note that seq1len is still zero. */
-- break;
--
-- backw1_stop = ~0ul;
-- idx1now = idx1cnt++;
-- }
-- else
-- /* We pushed backward sequences. */
-- idx1now = backw1 = idx1cnt - 1;
-- }
-- }
-- while ((seq1len = weights[idx1arr[idx1now]++]) == 0);
--
-- /* And the same for string `s2'. */
-- if (seq2len == 0)
-- do
-- {
-- ++val2;
--
-- if (backw2_stop != ~0ul)
-- {
-- /* The is something pushed. */
-- if (backw2 == backw2_stop)
-- {
-- /* The last pushed character was handled. Continue
-- with forward characters. */
-- if (idx2cnt < idx2max)
-- {
-- idx2now = idx2cnt;
-- backw2_stop = ~0ul;
-- }
-- else
-- {
-- /* Nothing anymore. The backward sequence
-- ended with the last sequence in the string. */
-- idx2now = ~0ul;
-- break;
-- }
-- }
-- else
-- idx2now = --backw2;
-- }
-- else
-- {
-- backw2_stop = idx2cnt;
--
-- while (idx2cnt < idx2max)
-- {
-- if ((rulesets[rule2arr[idx2cnt] * nrules + pass]
-- & sort_backward) == 0)
-- /* No more backward characters to push. */
-- break;
-- ++idx2cnt;
-- }
--
-- if (backw2_stop == idx2cnt)
-- {
-- /* No sequence at all or just one. */
-- if (idx2cnt == idx2max)
-- /* Note that seq2len is still zero. */
-- break;
--
-- backw2_stop = ~0ul;
-- idx2now = idx2cnt++;
-- }
-- else
-- /* We pushed backward sequences. */
-- idx2now = backw2 = idx2cnt - 1;
-- }
-- }
-- while ((seq2len = weights[idx2arr[idx2now]++]) == 0);
+- if (pass == 0)
+ if (__glibc_unlikely (seq1.idxarr == NULL))
+ {
+ get_next_seq_nocache (&seq1, nrules, rulesets, weights, table,
@@ -919,73 +366,20 @@ index ecda08f..bb34a72 100644
+ extra, indirect, pass);
+ }
+ else if (pass == 0)
-+ {
-+ get_next_seq (&seq1, nrules, rulesets, weights, table, extra,
-+ indirect);
-+ get_next_seq (&seq2, nrules, rulesets, weights, table, extra,
-+ indirect);
-+ }
-+ else
-+ {
-+ get_next_seq_cached (&seq1, nrules, pass, rulesets, weights);
-+ get_next_seq_cached (&seq2, nrules, pass, rulesets, weights);
-+ }
-
- /* See whether any or both strings are empty. */
-- if (seq1len == 0 || seq2len == 0)
-+ if (seq1.len == 0 || seq2.len == 0)
{
-- if (seq1len == seq2len)
-+ if (seq1.len == seq2.len)
- /* Both ended. So far so good, both strings are equal
- at this level. */
- break;
-
- /* This means one string is shorter than the other. Find out
- which one and return an appropriate value. */
-- result = seq1len == 0 ? -1 : 1;
-+ result = seq1.len == 0 ? -1 : 1;
+ get_next_seq (&seq1, nrules, rulesets, weights, table, extra,
+ indirect);
+@@ -411,10 +614,18 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
goto free_and_return;
}
-- /* Test for position if necessary. */
-- if (position && val1 != val2)
-- {
-- result = val1 - val2;
-- goto free_and_return;
-- }
--
-- /* Compare the two sequences. */
-- do
-- {
-- if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]])
-- {
-- /* The sequences differ. */
-- result = (weights[idx1arr[idx1now]]
-- - weights[idx2arr[idx2now]]);
-- goto free_and_return;
-- }
--
-- /* Increment the offsets. */
-- ++idx1arr[idx1now];
-- ++idx2arr[idx2now];
--
-- --seq1len;
-- --seq2len;
-- }
-- while (seq1len > 0 && seq2len > 0);
--
-- if (position && seq1len != seq2len)
-- {
-- result = seq1len - seq2len;
-- goto free_and_return;
-- }
+- result = do_compare (&seq1, &seq2, position, weights);
+ if (__glibc_unlikely (seq1.idxarr == NULL))
+ result = do_compare_nocache (&seq1, &seq2, position, weights);
+ else
+ result = do_compare (&seq1, &seq2, position, weights);
-+ if (result != 0)
-+ goto free_and_return;
+ if (result != 0)
+ goto free_and_return;
}
+
+ if (__glibc_likely (seq1.rulearr != NULL))
@@ -995,10 +389,70 @@ index ecda08f..bb34a72 100644
}
/* Free the memory if needed. */
- free_and_return:
- if (use_malloc)
-- free (idx1arr);
-+ free (seq1.idxarr);
-
- return result;
- }
+diff --git a/string/tst-strcoll-overflow.c b/string/tst-strcoll-overflow.c
+new file mode 100644
+index 0000000..bb665ac
+--- /dev/null
++++ b/string/tst-strcoll-overflow.c
+@@ -0,0 +1,61 @@
++/* Copyright (C) 2013 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <http://www.gnu.org/licenses/>. */
++
++#include <locale.h>
++#include <stdio.h>
++#include <stdint.h>
++#include <stdlib.h>
++#include <string.h>
++
++/* Verify that strcoll does not crash for large strings for which it cannot
++ cache weight lookup results. The size is large enough to cause integer
++ overflows on 32-bit as well as buffer overflows on 64-bit. The test should
++ work reasonably reliably when overcommit is disabled, but it obviously
++ depends on how much memory the system has. There's a limitation to this
++ test in that it does not run to completion. Actually collating such a
++ large string can take days and we can't have xcheck running that long. For
++ that reason, we run the test for about 5 minutes and then assume that
++ everything is fine if there are no crashes. */
++#define SIZE 0x40000000ul
++
++int
++do_test (void)
++{
++ if (setlocale (LC_COLLATE, "en_GB.UTF-8") == NULL)
++ {
++ puts ("setlocale failed, cannot test for overflow");
++ return 0;
++ }
++
++ char *p = malloc (SIZE);
++
++ if (p == NULL)
++ {
++ puts ("could not allocate memory");
++ return 1;
++ }
++
++ memset (p, 'x', SIZE - 1);
++ p[SIZE - 1] = 0;
++ printf ("%d\n", strcoll (p, p));
++ return 0;
++}
++
++#define TIMEOUT 300
++#define EXPECTED_SIGNAL SIGALRM
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
diff --git a/glibc.spec b/glibc.spec
index f639c07..1d6a829 100644
--- a/glibc.spec
+++ b/glibc.spec
@@ -1,6 +1,6 @@
-%define glibcsrcdir glibc-2.18
-%define glibcversion 2.18
-%define glibcrelease 6%{?dist}
+%define glibcsrcdir glibc-2.18-79-gbb8ea71
+%define glibcversion 2.18.90
+%define glibcrelease 1%{?dist}
# Pre-release tarballs are pulled in from git using a command that is
# effectively:
#
@@ -9,7 +9,7 @@
# gzip -9 $(git describe --match 'glibc-*').tar
#
# glibc_release_url is only defined when we have a release tarball.
-%define glibc_release_url http://ftp.gnu.org/gnu/glibc/
+# % define glibc_release_url http://ftp.gnu.org/gnu/glibc/
##############################################################################
# If run_glibc_tests is zero then tests are not run for the build.
# You must always set run_glibc_tests to one for production builds.
@@ -183,7 +183,6 @@ Patch0042: %{name}-rh970865.patch
#
# Patches from upstream
#
-Patch1001: %{name}-rh995841.patch
#
# Patches submitted, but not yet approved upstream.
@@ -200,9 +199,6 @@ Patch2013: %{name}-rh741105.patch
# Upstream BZ 9954
Patch2021: %{name}-rh739743.patch
-# Upstream BZ 13818
-Patch2022: %{name}-rh800224.patch
-
# Upstream BZ 14247
Patch2023: %{name}-rh827510.patch
@@ -215,12 +211,6 @@ Patch2027: %{name}-rh819430.patch
#Upstream BZ 14547
Patch2028: %{name}-strcoll-cve.patch
-# Initialize res_hconf in nscd
-Patch2029: %{name}-rh1000924.patch
-
-# Pass dl_hwcap to IFUNC resolver on 32-bit ARM.
-Patch2030: %{name}-rh985342.patch
-
##############################################################################
# End of glibc patches.
##############################################################################
@@ -521,7 +511,6 @@ package or when debugging this package.
%patch0019 -p1
%patch0020 -p1
%patch2021 -p1
-%patch2022 -p1
%patch2023 -p1
%patch0024 -p1
%patch0025 -p1
@@ -537,12 +526,9 @@ package or when debugging this package.
%patch0035 -p1
%patch0037 -p1
%patch2028 -p1
-%patch1001 -p1
%patch0040 -p1
%patch0041 -p1
%patch0042 -p1
-%patch2029 -p1
-%patch2030 -p1
##############################################################################
# %%prep - Additional prep required...
@@ -1628,6 +1614,10 @@ rm -f *.filelist*
%endif
%changelog
+* Thu Sep 5 2013 Siddhesh Poyarekar <siddhesh at redhat.com> - 2.18.90-1
+- Resync with upstream master.
+- Drop patch for #800224.
+
* Thu Aug 29 2013 Carlos O'Donell <carlos at redhat.com> - 2.18-6
- Fix Power build (#997531).
diff --git a/sources b/sources
index 56c580f..087cb40 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-b67b22b428ed183148d1344da6d22ea9 glibc-2.18.tar.gz
+411eba8ccda9743d2e2a49ef9379e860 glibc-2.18-79-gbb8ea71.tar.gz
More information about the scm-commits
mailing list