diff --git a/pkgs/development/libraries/glibc/2.18/common.nix b/pkgs/development/libraries/glibc/2.18/common.nix
index 6ffc8d495f18..0a1b32bbdb0d 100644
--- a/pkgs/development/libraries/glibc/2.18/common.nix
+++ b/pkgs/development/libraries/glibc/2.18/common.nix
@@ -53,6 +53,12 @@ stdenv.mkDerivation ({
          rfc3484_sort: Assertion `src->results[i].native == -1 ||
          src->results[i].native == a2_native' failed." crashes. */
       ./glibc-rh739743.patch
+
+      ./cve-2012-4412+4424.patch
+      ./cve-2013-4237.patch
+      ./cve-2013-4332.patch
+      ./cve-2013-4458.patch
+      ./cve-2013-4788.patch
     ];
 
   postPatch = ''
diff --git a/pkgs/development/libraries/glibc/2.18/cve-2012-4412+4424.patch b/pkgs/development/libraries/glibc/2.18/cve-2012-4412+4424.patch
new file mode 100644
index 000000000000..67ffbbc217b6
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.18/cve-2012-4412+4424.patch
@@ -0,0 +1,1006 @@
+https://projects.archlinux.org/svntogit/packages.git/tree/trunk/glibc-2.18-strcoll-CVE-2012-4412+4424.patch?h=packages/glibc
+
+diff --git a/string/strcoll_l.c b/string/strcoll_l.c
+index ecda08f..bb34a72 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.  */
++  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.  */
++  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)
++{
++  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
++  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)
++	{
++	  /* 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;
++}
++
++/* Get next sequence.  Traverse the string as required.  This function does not
++   set or use any index or rule cache.  */
++static void
++get_next_seq_nocache (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,
++		      int pass)
++{
++#include WEIGHT_H
++  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;
++  int32_t idx = seq->idx;
++  const USTRING_TYPE *us = seq->us;
++
++  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)
++		{
++		  idx = seq->save_idx;
++		  backw_stop = ~0ul;
++		}
++	      else
++		{
++		  /* Nothing anymore.  The backward sequence ended with
++		     the last sequence in the string.  Note that len is
++		     still zero.  */
++		  idx = 0;
++		  break;
++	        }
++	    }
++	  else
++	    {
++	      /* XXX Traverse BACKW sequences from the beginning of
++		 BACKW_STOP to get the next sequence.  Is ther a quicker way
++	         to do this?  */
++	      size_t i = backw_stop;
++	      us = seq->back_us;
++	      while (i < backw)
++		{
++		  int32_t tmp = findidx (&us, -1);
++		  idx = tmp & 0xffffff;
++		  i++;
++		}
++	      --backw;
++	      us = seq->us;
++	    }
++	}
++      else
++	{
++	  backw_stop = idxmax;
++	  int32_t prev_idx = idx;
++
++	  while (*us != L('\0'))
++	    {
++	      int32_t tmp = findidx (&us, -1);
++	      unsigned char rule = tmp >> 24;
++	      prev_idx = idx;
++	      idx = tmp & 0xffffff;
++	      idxcnt = idxmax++;
++
++	      /* Save the rule for the first sequence.  */
++	      if (__glibc_unlikely (idxcnt == 0))
++	        seq->rule = rule;
++
++	      if ((rulesets[rule * 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 || backw_stop > idxcnt)
++		/* Note that len is still zero.  */
++		break;
++
++	      backw_stop = ~0ul;
++	    }
++	  else
++	    {
++	      /* We pushed backward sequences.  If the stream ended with the
++		 backward sequence, then we process the last sequence we
++		 found.  Otherwise we process the sequence before the last
++		 one since the last one was a forward sequence.  */
++	      seq->back_us = seq->us;
++	      seq->us = us;
++	      backw = idxcnt;
++	      if (idxmax > idxcnt)
++		{
++		  backw--;
++		  seq->save_idx = idx;
++		  idx = prev_idx;
++		}
++	      if (backw > backw_stop)
++		backw--;
++	    }
++	}
++
++      len = weights[idx++];
++      /* Skip over indices of previous levels.  */
++      for (int i = 0; i < pass; i++)
++	{
++	  idx += len;
++	  len = weights[idx];
++	  idx++;
++	}
++    }
++
++  /* Update the structure.  */
++  seq->val = val;
++  seq->len = len;
++  seq->backw_stop = backw_stop;
++  seq->backw = backw;
++  seq->idxcnt = idxcnt;
++  seq->idxmax = idxmax;
++  seq->us = us;
++  seq->idx = idx;
++}
++
++/* Compare two sequences.  This version does not use the index and rules
++   cache.  */
++static int
++do_compare_nocache (coll_seq *seq1, coll_seq *seq2, int position,
++		    const USTRING_TYPE *weights)
++{
++  int seq1len = seq1->len;
++  int seq2len = seq2->len;
++  size_t val1 = seq1->val;
++  size_t val2 = seq2->val;
++  int idx1 = seq1->idx;
++  int idx2 = seq2->idx;
++  int result = 0;
++
++  /* Test for position if necessary.  */
++  if (position && val1 != val2)
++    {
++      result = val1 > val2 ? 1 : -1;
++      goto out;
++    }
++
++  /* Compare the two sequences.  */
++  do
++    {
++      if (weights[idx1] != weights[idx2])
++	{
++	  /* The sequences differ.  */
++	  result = weights[idx1] - weights[idx2];
++	  goto out;
++	}
++
++      /* Increment the offsets.  */
++      ++idx1;
++      ++idx2;
++
++      --seq1len;
++      --seq2len;
++    }
++  while (seq1len > 0 && seq2len > 0);
++
++  if (position && seq1len != seq2len)
++    result = seq1len - seq2len;
++
++out:
++  seq1->len = seq1len;
++  seq2->len = seq2len;
++  seq1->idx = idx1;
++  seq2->idx = idx2;
++  return result;
++}
++
++/* 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;
++  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)
++    {
++      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);
+ 
+   /* 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);
+ 
+-  /* 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)
+ 
+      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 (idx1arr == 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
+-	   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)
++      /* 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
++    {
++      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.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;
++
++      /* We need the elements of the strings as unsigned values since they
++	 are used as indices.  */
++      seq1.us = (const USTRING_TYPE *) s1;
++      seq2.us = (const USTRING_TYPE *) s2;
++
+       /* 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[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 (__glibc_unlikely (seq1.idxarr == NULL))
++	    {
++	      get_next_seq_nocache (&seq1, nrules, rulesets, weights, table,
++				    extra, indirect, pass);
++	      get_next_seq_nocache (&seq2, nrules, rulesets, weights, table,
++				    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;
+ 	      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;
+-	    }
++	  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 (__glibc_likely (seq1.rulearr != NULL))
++	rule = seq1.rulearr[0];
++      else
++	rule = seq1.rule;
+     }
+ 
+   /* Free the memory if needed.  */
+  free_and_return:
+   if (use_malloc)
+-    free (idx1arr);
++    free (seq1.idxarr);
+ 
+   return result;
+ }
diff --git a/pkgs/development/libraries/glibc/2.18/cve-2013-4237.patch b/pkgs/development/libraries/glibc/2.18/cve-2013-4237.patch
new file mode 100644
index 000000000000..f745cb003aa2
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.18/cve-2013-4237.patch
@@ -0,0 +1,302 @@
+commit 91ce40854d0b7f865cf5024ef95a8026b76096f3
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Aug 16 09:38:52 2013 +0200
+
+    CVE-2013-4237, BZ #14699: Buffer overflow in readdir_r
+    
+    	* sysdeps/posix/dirstream.h (struct __dirstream): Add errcode
+    	member.
+    	* sysdeps/posix/opendir.c (__alloc_dir): Initialize errcode
+    	member.
+    	* sysdeps/posix/rewinddir.c (rewinddir): Reset errcode member.
+    	* sysdeps/posix/readdir_r.c (__READDIR_R): Enforce NAME_MAX limit.
+    	Return delayed error code.  Remove GETDENTS_64BIT_ALIGNED
+    	conditional.
+    	* sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c: Do not define
+    	GETDENTS_64BIT_ALIGNED.
+    	* sysdeps/unix/sysv/linux/i386/readdir64_r.c: Likewise.
+    	* manual/filesys.texi (Reading/Closing Directory): Document
+    	ENAMETOOLONG return value of readdir_r.  Recommend readdir more
+    	strongly.
+    	* manual/conf.texi (Limits for Files): Add portability note to
+    	NAME_MAX, PATH_MAX.
+    	(Pathconf): Add portability note for _PC_NAME_MAX, _PC_PATH_MAX.
+
+diff --git a/manual/conf.texi b/manual/conf.texi
+index 7eb8b36..c720063 100644
+--- a/manual/conf.texi
++++ b/manual/conf.texi
+@@ -1149,6 +1149,9 @@ typed ahead as input.  @xref{I/O Queues}.
+ @deftypevr Macro int NAME_MAX
+ The uniform system limit (if any) for the length of a file name component, not
+ including the terminating null character.
++
++@strong{Portability Note:} On some systems, @theglibc{} defines
++@code{NAME_MAX}, but does not actually enforce this limit.
+ @end deftypevr
+ 
+ @comment limits.h
+@@ -1157,6 +1160,9 @@ including the terminating null character.
+ The uniform system limit (if any) for the length of an entire file name (that
+ is, the argument given to system calls such as @code{open}), including the
+ terminating null character.
++
++@strong{Portability Note:} @Theglibc{} does not enforce this limit
++even if @code{PATH_MAX} is defined.
+ @end deftypevr
+ 
+ @cindex limits, pipe buffer size
+@@ -1476,6 +1482,9 @@ Inquire about the value of @code{POSIX_REC_MIN_XFER_SIZE}.
+ Inquire about the value of @code{POSIX_REC_XFER_ALIGN}.
+ @end table
+ 
++@strong{Portability Note:} On some systems, @theglibc{} does not
++enforce @code{_PC_NAME_MAX} or @code{_PC_PATH_MAX} limits.
++
+ @node Utility Limits
+ @section Utility Program Capacity Limits
+ 
+diff --git a/manual/filesys.texi b/manual/filesys.texi
+index 1df9cf2..814c210 100644
+--- a/manual/filesys.texi
++++ b/manual/filesys.texi
+@@ -444,9 +444,9 @@ symbols are declared in the header file @file{dirent.h}.
+ @comment POSIX.1
+ @deftypefun {struct dirent *} readdir (DIR *@var{dirstream})
+ This function reads the next entry from the directory.  It normally
+-returns a pointer to a structure containing information about the file.
+-This structure is statically allocated and can be rewritten by a
+-subsequent call.
++returns a pointer to a structure containing information about the
++file.  This structure is associated with the @var{dirstream} handle
++and can be rewritten by a subsequent call.
+ 
+ @strong{Portability Note:} On some systems @code{readdir} may not
+ return entries for @file{.} and @file{..}, even though these are always
+@@ -461,19 +461,61 @@ conditions are defined for this function:
+ The @var{dirstream} argument is not valid.
+ @end table
+ 
+-@code{readdir} is not thread safe.  Multiple threads using
+-@code{readdir} on the same @var{dirstream} may overwrite the return
+-value.  Use @code{readdir_r} when this is critical.
++To distinguish between an end-of-directory condition or an error, you
++must set @code{errno} to zero before calling @code{readdir}.  To avoid
++entering an infinite loop, you should stop reading from the directory
++after the first error.
++
++In POSIX.1-2008, @code{readdir} is not thread-safe.  In @theglibc{}
++implementation, it is safe to call @code{readdir} concurrently on
++different @var{dirstream}s, but multiple threads accessing the same
++@var{dirstream} result in undefined behavior.  @code{readdir_r} is a
++fully thread-safe alternative, but suffers from poor portability (see
++below).  It is recommended that you use @code{readdir}, with external
++locking if multiple threads access the same @var{dirstream}.
+ @end deftypefun
+ 
+ @comment dirent.h
+ @comment GNU
+ @deftypefun int readdir_r (DIR *@var{dirstream}, struct dirent *@var{entry}, struct dirent **@var{result})
+-This function is the reentrant version of @code{readdir}.  Like
+-@code{readdir} it returns the next entry from the directory.  But to
+-prevent conflicts between simultaneously running threads the result is
+-not stored in statically allocated memory.  Instead the argument
+-@var{entry} points to a place to store the result.
++This function is a version of @code{readdir} which performs internal
++locking.  Like @code{readdir} it returns the next entry from the
++directory.  To prevent conflicts between simultaneously running
++threads the result is stored inside the @var{entry} object.
++
++@strong{Portability Note:} It is recommended to use @code{readdir}
++instead of @code{readdir_r} for the following reasons:
++
++@itemize @bullet
++@item
++On systems which do not define @code{NAME_MAX}, it may not be possible
++to use @code{readdir_r} safely because the caller does not specify the
++length of the buffer for the directory entry.
++
++@item
++On some systems, @code{readdir_r} cannot read directory entries with
++very long names.  If such a name is encountered, @theglibc{}
++implementation of @code{readdir_r} returns with an error code of
++@code{ENAMETOOLONG} after the final directory entry has been read.  On
++other systems, @code{readdir_r} may return successfully, but the
++@code{d_name} member may not be NUL-terminated or may be truncated.
++
++@item
++POSIX-1.2008 does not guarantee that @code{readdir} is thread-safe,
++even when access to the same @var{dirstream} is serialized.  But in
++current implementations (including @theglibc{}), it is safe to call
++@code{readdir} concurrently on different @var{dirstream}s, so there is
++no need to use @code{readdir_r} in most multi-threaded programs.  In
++the rare case that multiple threads need to read from the same
++@var{dirstream}, it is still better to use @code{readdir} and external
++synchronization.
++
++@item
++It is expected that future versions of POSIX will obsolete
++@code{readdir_r} and mandate the level of thread safety for
++@code{readdir} which is provided by @theglibc{} and other
++implementations today.
++@end itemize
+ 
+ Normally @code{readdir_r} returns zero and sets @code{*@var{result}}
+ to @var{entry}.  If there are no more entries in the directory or an
+@@ -481,15 +523,6 @@ error is detected, @code{readdir_r} sets @code{*@var{result}} to a
+ null pointer and returns a nonzero error code, also stored in
+ @code{errno}, as described for @code{readdir}.
+ 
+-@strong{Portability Note:} On some systems @code{readdir_r} may not
+-return a NUL terminated string for the file name, even when there is no
+-@code{d_reclen} field in @code{struct dirent} and the file
+-name is the maximum allowed size.  Modern systems all have the
+-@code{d_reclen} field, and on old systems multi-threading is not
+-critical.  In any case there is no such problem with the @code{readdir}
+-function, so that even on systems without the @code{d_reclen} member one
+-could use multiple threads by using external locking.
+-
+ It is also important to look at the definition of the @code{struct
+ dirent} type.  Simply passing a pointer to an object of this type for
+ the second parameter of @code{readdir_r} might not be enough.  Some
+diff --git a/sysdeps/posix/dirstream.h b/sysdeps/posix/dirstream.h
+index a7a074d..8e8570d 100644
+--- a/sysdeps/posix/dirstream.h
++++ b/sysdeps/posix/dirstream.h
+@@ -39,6 +39,8 @@ struct __dirstream
+ 
+     off_t filepos;		/* Position of next entry to read.  */
+ 
++    int errcode;		/* Delayed error code.  */
++
+     /* Directory block.  */
+     char data[0] __attribute__ ((aligned (__alignof__ (void*))));
+   };
+diff --git a/sysdeps/posix/opendir.c b/sysdeps/posix/opendir.c
+index ddfc3a7..fc05b0f 100644
+--- a/sysdeps/posix/opendir.c
++++ b/sysdeps/posix/opendir.c
+@@ -231,6 +231,7 @@ __alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp)
+   dirp->size = 0;
+   dirp->offset = 0;
+   dirp->filepos = 0;
++  dirp->errcode = 0;
+ 
+   return dirp;
+ }
+diff --git a/sysdeps/posix/readdir_r.c b/sysdeps/posix/readdir_r.c
+index b5a8e2e..8ed5c3f 100644
+--- a/sysdeps/posix/readdir_r.c
++++ b/sysdeps/posix/readdir_r.c
+@@ -40,6 +40,7 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
+   DIRENT_TYPE *dp;
+   size_t reclen;
+   const int saved_errno = errno;
++  int ret;
+ 
+   __libc_lock_lock (dirp->lock);
+ 
+@@ -70,10 +71,10 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
+ 		  bytes = 0;
+ 		  __set_errno (saved_errno);
+ 		}
++	      if (bytes < 0)
++		dirp->errcode = errno;
+ 
+ 	      dp = NULL;
+-	      /* Reclen != 0 signals that an error occurred.  */
+-	      reclen = bytes != 0;
+ 	      break;
+ 	    }
+ 	  dirp->size = (size_t) bytes;
+@@ -106,29 +107,46 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
+       dirp->filepos += reclen;
+ #endif
+ 
+-      /* Skip deleted files.  */
++#ifdef NAME_MAX
++      if (reclen > offsetof (DIRENT_TYPE, d_name) + NAME_MAX + 1)
++	{
++	  /* The record is very long.  It could still fit into the
++	     caller-supplied buffer if we can skip padding at the
++	     end.  */
++	  size_t namelen = _D_EXACT_NAMLEN (dp);
++	  if (namelen <= NAME_MAX)
++	    reclen = offsetof (DIRENT_TYPE, d_name) + namelen + 1;
++	  else
++	    {
++	      /* The name is too long.  Ignore this file.  */
++	      dirp->errcode = ENAMETOOLONG;
++	      dp->d_ino = 0;
++	      continue;
++	    }
++	}
++#endif
++
++      /* Skip deleted and ignored files.  */
+     }
+   while (dp->d_ino == 0);
+ 
+   if (dp != NULL)
+     {
+-#ifdef GETDENTS_64BIT_ALIGNED
+-      /* The d_reclen value might include padding which is not part of
+-	 the DIRENT_TYPE data structure.  */
+-      reclen = MIN (reclen,
+-		    offsetof (DIRENT_TYPE, d_name) + sizeof (dp->d_name));
+-#endif
+       *result = memcpy (entry, dp, reclen);
+-#ifdef GETDENTS_64BIT_ALIGNED
++#ifdef _DIRENT_HAVE_D_RECLEN
+       entry->d_reclen = reclen;
+ #endif
++      ret = 0;
+     }
+   else
+-    *result = NULL;
++    {
++      *result = NULL;
++      ret = dirp->errcode;
++    }
+ 
+   __libc_lock_unlock (dirp->lock);
+ 
+-  return dp != NULL ? 0 : reclen ? errno : 0;
++  return ret;
+ }
+ 
+ #ifdef __READDIR_R_ALIAS
+diff --git a/sysdeps/posix/rewinddir.c b/sysdeps/posix/rewinddir.c
+index 2935a8e..d4991ad 100644
+--- a/sysdeps/posix/rewinddir.c
++++ b/sysdeps/posix/rewinddir.c
+@@ -33,6 +33,7 @@ rewinddir (dirp)
+   dirp->filepos = 0;
+   dirp->offset = 0;
+   dirp->size = 0;
++  dirp->errcode = 0;
+ #ifndef NOT_IN_libc
+   __libc_lock_unlock (dirp->lock);
+ #endif
+diff --git a/sysdeps/unix/sysv/linux/i386/readdir64_r.c b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
+index 8ebbcfd..a7d114e 100644
+--- a/sysdeps/unix/sysv/linux/i386/readdir64_r.c
++++ b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
+@@ -18,7 +18,6 @@
+ #define __READDIR_R __readdir64_r
+ #define __GETDENTS __getdents64
+ #define DIRENT_TYPE struct dirent64
+-#define GETDENTS_64BIT_ALIGNED 1
+ 
+ #include <sysdeps/posix/readdir_r.c>
+ 
+diff --git a/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c b/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c
+index 5ed8e95..290f2c8 100644
+--- a/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c
++++ b/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c
+@@ -1,5 +1,4 @@
+ #define readdir64_r __no_readdir64_r_decl
+-#define GETDENTS_64BIT_ALIGNED 1
+ #include <sysdeps/posix/readdir_r.c>
+ #undef readdir64_r
+ weak_alias (__readdir_r, readdir64_r)
diff --git a/pkgs/development/libraries/glibc/2.18/cve-2013-4332.patch b/pkgs/development/libraries/glibc/2.18/cve-2013-4332.patch
new file mode 100644
index 000000000000..94d25d7bbe1c
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.18/cve-2013-4332.patch
@@ -0,0 +1,56 @@
+https://projects.archlinux.org/svntogit/packages.git/tree/trunk/glibc-2.18-malloc-corrupt-CVE-2013-4332.patch?h=packages/glibc
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index dd295f5..7f43ba3 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -3082,6 +3082,13 @@ __libc_pvalloc(size_t bytes)
+   size_t page_mask = GLRO(dl_pagesize) - 1;
+   size_t rounded_bytes = (bytes + page_mask) & ~(page_mask);
+ 
++  /* Check for overflow.  */
++  if (bytes > SIZE_MAX - 2*pagesz - MINSIZE)
++    {
++      __set_errno (ENOMEM);
++      return 0;
++    }
++
+   void *(*hook) (size_t, size_t, const void *) =
+     force_reg (__memalign_hook);
+   if (__builtin_expect (hook != NULL, 0))
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 7f43ba3..3148c5f 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -3046,6 +3046,13 @@ __libc_valloc(size_t bytes)
+ 
+   size_t pagesz = GLRO(dl_pagesize);
+ 
++  /* Check for overflow.  */
++  if (bytes > SIZE_MAX - pagesz - MINSIZE)
++    {
++      __set_errno (ENOMEM);
++      return 0;
++    }
++
+   void *(*hook) (size_t, size_t, const void *) =
+     force_reg (__memalign_hook);
+   if (__builtin_expect (hook != NULL, 0))
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 3148c5f..f7718a9 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -3015,6 +3015,13 @@ __libc_memalign(size_t alignment, size_t bytes)
+   /* Otherwise, ensure that it is at least a minimum chunk size */
+   if (alignment <  MINSIZE) alignment = MINSIZE;
+ 
++  /* Check for overflow.  */
++  if (bytes > SIZE_MAX - alignment - MINSIZE)
++    {
++      __set_errno (ENOMEM);
++      return 0;
++    }
++
+   arena_get(ar_ptr, bytes + alignment + MINSIZE);
+   if(!ar_ptr)
+     return 0;
diff --git a/pkgs/development/libraries/glibc/2.18/cve-2013-4458.patch b/pkgs/development/libraries/glibc/2.18/cve-2013-4458.patch
new file mode 100644
index 000000000000..bec4acde7548
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.18/cve-2013-4458.patch
@@ -0,0 +1,50 @@
+commit 7cbcdb3699584db8913ca90f705d6337633ee10f
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Fri Oct 25 10:22:12 2013 +0530
+
+    Fix stack overflow due to large AF_INET6 requests
+    
+    Resolves #16072 (CVE-2013-4458).
+    
+    This patch fixes another stack overflow in getaddrinfo when it is
+    called with AF_INET6.  The AF_UNSPEC case was fixed as CVE-2013-1914,
+    but the AF_INET6 case went undetected back then.
+
+diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+index e6ce4cf..8ff74b4 100644
+--- a/sysdeps/posix/getaddrinfo.c
++++ b/sysdeps/posix/getaddrinfo.c
+@@ -197,7 +197,22 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
+ 				&rc, &herrno, NULL, &localcanon));	      \
+     if (rc != ERANGE || herrno != NETDB_INTERNAL)			      \
+       break;								      \
+-    tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);		      \
++    if (!malloc_tmpbuf && __libc_use_alloca (alloca_used + 2 * tmpbuflen))    \
++      tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, 2 * tmpbuflen,	      \
++				      alloca_used);			      \
++    else								      \
++      {									      \
++	char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,		      \
++			      2 * tmpbuflen);				      \
++	if (newp == NULL)						      \
++	  {								      \
++	    result = -EAI_MEMORY;					      \
++	    goto free_and_return;					      \
++	  }								      \
++	tmpbuf = newp;							      \
++	malloc_tmpbuf = true;						      \
++	tmpbuflen = 2 * tmpbuflen;					      \
++      }									      \
+   }									      \
+   if (status == NSS_STATUS_SUCCESS && rc == 0)				      \
+     h = &th;								      \
+@@ -209,7 +224,8 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
+ 	{								      \
+ 	  __set_h_errno (herrno);					      \
+ 	  _res.options |= old_res_options & RES_USE_INET6;		      \
+-	  return -EAI_SYSTEM;						      \
++	  result = -EAI_SYSTEM;						      \
++	  goto free_and_return;						      \
+ 	}								      \
+       if (herrno == TRY_AGAIN)						      \
+ 	no_data = EAI_AGAIN;						      \
diff --git a/pkgs/development/libraries/glibc/2.18/cve-2013-4788.patch b/pkgs/development/libraries/glibc/2.18/cve-2013-4788.patch
new file mode 100644
index 000000000000..cf8c7911f68a
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.18/cve-2013-4788.patch
@@ -0,0 +1,222 @@
+commit c61b4d41c9647a54a329aa021341c0eb032b793e
+Author: Carlos O'Donell <carlos@redhat.com>
+Date:   Mon Sep 23 00:52:09 2013 -0400
+
+    BZ #15754: CVE-2013-4788
+    
+    The pointer guard used for pointer mangling was not initialized for
+    static applications resulting in the security feature being disabled.
+    The pointer guard is now correctly initialized to a random value for
+    static applications. Existing static applications need to be
+    recompiled to take advantage of the fix.
+    
+    The test tst-ptrguard1-static and tst-ptrguard1 add regression
+    coverage to ensure the pointer guards are sufficiently random
+    and initialized to a default value.
+
+diff --git a/csu/libc-start.c b/csu/libc-start.c
+index e5da3ef..c898d06 100644
+--- a/csu/libc-start.c
++++ b/csu/libc-start.c
+@@ -37,6 +37,12 @@ extern void __pthread_initialize_minimal (void);
+    in thread local area.  */
+ uintptr_t __stack_chk_guard attribute_relro;
+ # endif
++# ifndef  THREAD_SET_POINTER_GUARD
++/* Only exported for architectures that don't store the pointer guard
++   value in thread local area.  */
++uintptr_t __pointer_chk_guard_local
++	attribute_relro attribute_hidden __attribute__ ((nocommon));
++# endif
+ #endif
+ 
+ #ifdef HAVE_PTR_NTHREADS
+@@ -195,6 +201,16 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
+ # else
+   __stack_chk_guard = stack_chk_guard;
+ # endif
++
++  /* Set up the pointer guard value.  */
++  uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
++							 stack_chk_guard);
++# ifdef THREAD_SET_POINTER_GUARD
++  THREAD_SET_POINTER_GUARD (pointer_chk_guard);
++# else
++  __pointer_chk_guard_local = pointer_chk_guard;
++# endif
++
+ #endif
+ 
+   /* Register the destructor of the dynamic linker if there is any.  */
+diff --git a/ports/sysdeps/ia64/stackguard-macros.h b/ports/sysdeps/ia64/stackguard-macros.h
+index dc683c2..3907293 100644
+--- a/ports/sysdeps/ia64/stackguard-macros.h
++++ b/ports/sysdeps/ia64/stackguard-macros.h
+@@ -2,3 +2,6 @@
+ 
+ #define STACK_CHK_GUARD \
+   ({ uintptr_t x; asm ("adds %0 = -8, r13;; ld8 %0 = [%0]" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++  ({ uintptr_t x; asm ("adds %0 = -16, r13;; ld8 %0 = [%0]" : "=r" (x)); x; })
+diff --git a/ports/sysdeps/tile/stackguard-macros.h b/ports/sysdeps/tile/stackguard-macros.h
+index 589ea2b..f2e041b 100644
+--- a/ports/sysdeps/tile/stackguard-macros.h
++++ b/ports/sysdeps/tile/stackguard-macros.h
+@@ -4,11 +4,17 @@
+ # if __WORDSIZE == 64
+ #  define STACK_CHK_GUARD \
+   ({ uintptr_t x; asm ("addi %0, tp, -16; ld %0, %0" : "=r" (x)); x; })
++#  define POINTER_CHK_GUARD \
++  ({ uintptr_t x; asm ("addi %0, tp, -24; ld %0, %0" : "=r" (x)); x; })
+ # else
+ #  define STACK_CHK_GUARD \
+   ({ uintptr_t x; asm ("addi %0, tp, -8; ld4s %0, %0" : "=r" (x)); x; })
++#  define POINTER_CHK_GUARD \
++  ({ uintptr_t x; asm ("addi %0, tp, -12; ld4s %0, %0" : "=r" (x)); x; })
+ # endif
+ #else
+ # define STACK_CHK_GUARD \
+   ({ uintptr_t x; asm ("addi %0, tp, -8; lw %0, %0" : "=r" (x)); x; })
++# define POINTER_CHK_GUARD \
++  ({ uintptr_t x; asm ("addi %0, tp, -12; lw %0, %0" : "=r" (x)); x; })
+ #endif
+diff --git a/sysdeps/generic/stackguard-macros.h b/sysdeps/generic/stackguard-macros.h
+index ababf65..4fa3d96 100644
+--- a/sysdeps/generic/stackguard-macros.h
++++ b/sysdeps/generic/stackguard-macros.h
+@@ -2,3 +2,6 @@
+ 
+ extern uintptr_t __stack_chk_guard;
+ #define STACK_CHK_GUARD __stack_chk_guard
++
++extern uintptr_t __pointer_chk_guard_local;
++#define POINTER_CHK_GUARD __pointer_chk_guard_local
+diff --git a/sysdeps/i386/stackguard-macros.h b/sysdeps/i386/stackguard-macros.h
+index 8c31e19..0397629 100644
+--- a/sysdeps/i386/stackguard-macros.h
++++ b/sysdeps/i386/stackguard-macros.h
+@@ -2,3 +2,11 @@
+ 
+ #define STACK_CHK_GUARD \
+   ({ uintptr_t x; asm ("movl %%gs:0x14, %0" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++  ({							\
++     uintptr_t x;					\
++     asm ("movl %%gs:%c1, %0" : "=r" (x)		\
++	  : "i" (offsetof (tcbhead_t, pointer_guard)));	\
++     x;							\
++   })
+diff --git a/sysdeps/powerpc/powerpc32/stackguard-macros.h b/sysdeps/powerpc/powerpc32/stackguard-macros.h
+index 839f6a4..b3d0af8 100644
+--- a/sysdeps/powerpc/powerpc32/stackguard-macros.h
++++ b/sysdeps/powerpc/powerpc32/stackguard-macros.h
+@@ -2,3 +2,13 @@
+ 
+ #define STACK_CHK_GUARD \
+   ({ uintptr_t x; asm ("lwz %0,-28680(2)" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++  ({												\
++     uintptr_t x;										\
++     asm ("lwz %0,%1(2)"									\
++	  : "=r" (x)										\
++	  : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t))	\
++         );											\
++     x;												\
++   })
+diff --git a/sysdeps/powerpc/powerpc64/stackguard-macros.h b/sysdeps/powerpc/powerpc64/stackguard-macros.h
+index 9da879c..4620f96 100644
+--- a/sysdeps/powerpc/powerpc64/stackguard-macros.h
++++ b/sysdeps/powerpc/powerpc64/stackguard-macros.h
+@@ -2,3 +2,13 @@
+ 
+ #define STACK_CHK_GUARD \
+   ({ uintptr_t x; asm ("ld %0,-28688(13)" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++  ({												\
++     uintptr_t x;										\
++     asm ("ld %0,%1(2)"										\
++	  : "=r" (x)										\
++	  : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t))	\
++         );											\
++     x;												\
++   })
+diff --git a/sysdeps/s390/s390-32/stackguard-macros.h b/sysdeps/s390/s390-32/stackguard-macros.h
+index b74c579..449e8d4 100644
+--- a/sysdeps/s390/s390-32/stackguard-macros.h
++++ b/sysdeps/s390/s390-32/stackguard-macros.h
+@@ -2,3 +2,14 @@
+ 
+ #define STACK_CHK_GUARD \
+   ({ uintptr_t x; asm ("ear %0,%%a0; l %0,0x14(%0)" : "=a" (x)); x; })
++
++/* On s390/s390x there is no unique pointer guard, instead we use the
++   same value as the stack guard.  */
++#define POINTER_CHK_GUARD \
++  ({							\
++     uintptr_t x;					\
++     asm ("ear %0,%%a0; l %0,%1(%0)"			\
++	  : "=a" (x)					\
++	  : "i" (offsetof (tcbhead_t, stack_guard)));	\
++     x;							\
++   })
+diff --git a/sysdeps/s390/s390-64/stackguard-macros.h b/sysdeps/s390/s390-64/stackguard-macros.h
+index 0cebb5f..c8270fb 100644
+--- a/sysdeps/s390/s390-64/stackguard-macros.h
++++ b/sysdeps/s390/s390-64/stackguard-macros.h
+@@ -2,3 +2,17 @@
+ 
+ #define STACK_CHK_GUARD \
+   ({ uintptr_t x; asm ("ear %0,%%a0; sllg %0,%0,32; ear %0,%%a1; lg %0,0x28(%0)" : "=a" (x)); x; })
++
++/* On s390/s390x there is no unique pointer guard, instead we use the
++   same value as the stack guard.  */
++#define POINTER_CHK_GUARD \
++  ({							\
++     uintptr_t x;					\
++     asm ("ear %0,%%a0;"				\
++	  "sllg %0,%0,32;"				\
++	  "ear %0,%%a1;"				\
++	  "lg %0,%1(%0)"				\
++	 : "=a" (x)					\
++	 : "i" (offsetof (tcbhead_t, stack_guard)));	\
++     x;							\
++   })
+diff --git a/sysdeps/sparc/sparc32/stackguard-macros.h b/sysdeps/sparc/sparc32/stackguard-macros.h
+index c0b02b0..1eef0f1 100644
+--- a/sysdeps/sparc/sparc32/stackguard-macros.h
++++ b/sysdeps/sparc/sparc32/stackguard-macros.h
+@@ -2,3 +2,6 @@
+ 
+ #define STACK_CHK_GUARD \
+   ({ uintptr_t x; asm ("ld [%%g7+0x14], %0" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++  ({ uintptr_t x; asm ("ld [%%g7+0x18], %0" : "=r" (x)); x; })
+diff --git a/sysdeps/sparc/sparc64/stackguard-macros.h b/sysdeps/sparc/sparc64/stackguard-macros.h
+index 80f0635..cc0c12c 100644
+--- a/sysdeps/sparc/sparc64/stackguard-macros.h
++++ b/sysdeps/sparc/sparc64/stackguard-macros.h
+@@ -2,3 +2,6 @@
+ 
+ #define STACK_CHK_GUARD \
+   ({ uintptr_t x; asm ("ldx [%%g7+0x28], %0" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++  ({ uintptr_t x; asm ("ldx [%%g7+0x30], %0" : "=r" (x)); x; })
+diff --git a/sysdeps/x86_64/stackguard-macros.h b/sysdeps/x86_64/stackguard-macros.h
+index d7fedb3..1948800 100644
+--- a/sysdeps/x86_64/stackguard-macros.h
++++ b/sysdeps/x86_64/stackguard-macros.h
+@@ -4,3 +4,8 @@
+   ({ uintptr_t x;						\
+      asm ("mov %%fs:%c1, %0" : "=r" (x)				\
+ 	  : "i" (offsetof (tcbhead_t, stack_guard))); x; })
++
++#define POINTER_CHK_GUARD \
++  ({ uintptr_t x;						\
++     asm ("mov %%fs:%c1, %0" : "=r" (x)				\
++	  : "i" (offsetof (tcbhead_t, pointer_guard))); x; })