]> granicus.if.org Git - libexpat/commitdiff
Resolve call to srand, use more entropy
authorSebastian Pipping <sebastian@pipping.org>
Wed, 16 Mar 2016 14:30:12 +0000 (15:30 +0100)
committerSebastian Pipping <sebastian@pipping.org>
Sun, 20 Mar 2016 19:20:57 +0000 (20:20 +0100)
Since commit e3e81a6d9f0885ea02d3979151c358f314bf3d6d
(released with Expat 2.1.0) Expat called srand by itself
from inside generate_hash_secret_salt for an instance
of XML_Parser if XML_SetHashSalt was either (a) not called
for that instance or if (b) salt 0 was passed to XML_SetHashSalt
prior to parsing.  That call to srand passed (rather litle)
entropy extracted from the current time as a seed for srand.

That call to srand (1) broke repeatability for code calling
srand with a non-random seed prior to parsing with Expat,
and (2) resulted in a rather small set of hashing salts in
Expat in total.

For a short- to mid-term fix, the new approach avoids calling
srand altogether, extracts more entropy out of the clock and
adds some additional entropy from the process ID, too.

For a long term fix, we may want to read sizeof(long) bytes
from a source like getrandom(..) on Linux, and from similar
sources on other supported architectures.

https://bugzilla.redhat.com/show_bug.cgi?id=1197087

expat/lib/xmlparse.c

index 2d0bd3b19ede1d2e23d52c107d269c9762152a2e..41299daeeb743c4d8958d3d5b5d7bcc5ce188d92 100644 (file)
@@ -6,7 +6,9 @@
 #include <string.h>                     /* memset(), memcpy() */
 #include <assert.h>
 #include <limits.h>                     /* UINT_MAX */
-#include <time.h>                       /* time() */
+#include <sys/time.h>                   /* gettimeofday() */
+#include <sys/types.h>                  /* getpid() */
+#include <unistd.h>                     /* getpid() */
 
 #define XML_BUILDING_EXPAT 1
 
@@ -693,9 +695,16 @@ static const XML_Char implicitContext[] = {
 static unsigned long
 generate_hash_secret_salt(void)
 {
-  unsigned int seed = time(NULL) % UINT_MAX;
-  srand(seed);
-  return rand();
+  struct timeval tv;
+  int gettimeofday_res;
+
+  gettimeofday_res = gettimeofday(&tv, NULL);
+  assert (gettimeofday_res == 0);
+
+  /* Microseconds time is <20 bits entropy
+   * Process ID is 0 bits entropy if attacker has local access
+   * Factor is 2^61-1 (Mersenne prime M61) */
+  return (tv.tv_usec ^ getpid()) * 2305843009213693951;
 }
 
 static XML_Bool  /* only valid for root parser */