gnu: Add lci.
[jackhill/guix/guix.git] / gnu / packages / patches / expat-CVE-2012-6702-and-CVE-2016-5300.patch
CommitLineData
436dd046
LF
1Fix CVE-2012-6702 and CVE-2016-5300.
2
3https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-6702
4https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5300
5
6Patch copied from:
7https://sources.debian.net/src/expat/2.1.0-6%2Bdeb8u3/debian/patches/cve-2012-6702-plus-cve-2016-5300-v1.patch/
8
9From cb31522769d11a375078a073cba94e7176cb48a4 Mon Sep 17 00:00:00 2001
10From: Sebastian Pipping <sebastian@pipping.org>
11Date: Wed, 16 Mar 2016 15:30:12 +0100
12Subject: [PATCH] Resolve call to srand, use more entropy (patch version 1.0)
13
14Squashed backport against vanilla Expat 2.1.1, addressing:
15* CVE-2012-6702 -- unanticipated internal calls to srand
16* CVE-2016-5300 -- use of too little entropy
17
18Since commit e3e81a6d9f0885ea02d3979151c358f314bf3d6d
19(released with Expat 2.1.0) Expat called srand by itself
20from inside generate_hash_secret_salt for an instance
21of XML_Parser if XML_SetHashSalt was either (a) not called
22for that instance or if (b) salt 0 was passed to XML_SetHashSalt
23prior to parsing. That call to srand passed (rather litle)
24entropy extracted from the current time as a seed for srand.
25
26That call to srand (1) broke repeatability for code calling
27srand with a non-random seed prior to parsing with Expat,
28and (2) resulted in a rather small set of hashing salts in
29Expat in total.
30
31For a short- to mid-term fix, the new approach avoids calling
32srand altogether, extracts more entropy out of the clock and
33other sources, too.
34
35For a long term fix, we may want to read sizeof(long) bytes
36from a source like getrandom(..) on Linux, and from similar
37sources on other supported architectures.
38
39https://bugzilla.redhat.com/show_bug.cgi?id=1197087
40---
41 CMakeLists.txt | 3 +++
42 lib/xmlparse.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
43 2 files changed, 44 insertions(+), 7 deletions(-)
44
45diff --git a/CMakeLists.txt b/CMakeLists.txt
46index 353627e..524d514 100755
47--- a/CMakeLists.txt
48+++ b/CMakeLists.txt
49@@ -41,6 +41,9 @@ include_directories(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/lib)
50 if(MSVC)\r
51 add_definitions(-D_CRT_SECURE_NO_WARNINGS -wd4996)\r
52 endif(MSVC)\r
53+if(WIN32)\r
54+ add_definitions(-DCOMPILED_FROM_DSP)\r
55+endif(WIN32)\r
56 \r
57 set(expat_SRCS\r
58 lib/xmlparse.c\r
59diff --git a/lib/xmlparse.c b/lib/xmlparse.c
60index e308c79..c5f942f 100644
61--- a/lib/xmlparse.c
62+++ b/lib/xmlparse.c
63@@ -6,7 +6,14 @@
64 #include <string.h> /* memset(), memcpy() */
65 #include <assert.h>
66 #include <limits.h> /* UINT_MAX */
67-#include <time.h> /* time() */
68+
69+#ifdef COMPILED_FROM_DSP
70+#define getpid GetCurrentProcessId
71+#else
72+#include <sys/time.h> /* gettimeofday() */
73+#include <sys/types.h> /* getpid() */
74+#include <unistd.h> /* getpid() */
75+#endif
76
77 #define XML_BUILDING_EXPAT 1
78
79@@ -432,7 +439,7 @@ static ELEMENT_TYPE *
80 getElementType(XML_Parser parser, const ENCODING *enc,
81 const char *ptr, const char *end);
82
83-static unsigned long generate_hash_secret_salt(void);
84+static unsigned long generate_hash_secret_salt(XML_Parser parser);
85 static XML_Bool startParsing(XML_Parser parser);
86
87 static XML_Parser
88@@ -691,11 +698,38 @@ static const XML_Char implicitContext[] = {
89 };
90
91 static unsigned long
92-generate_hash_secret_salt(void)
93+gather_time_entropy(void)
94 {
95- unsigned int seed = time(NULL) % UINT_MAX;
96- srand(seed);
97- return rand();
98+#ifdef COMPILED_FROM_DSP
99+ FILETIME ft;
100+ GetSystemTimeAsFileTime(&ft); /* never fails */
101+ return ft.dwHighDateTime ^ ft.dwLowDateTime;
102+#else
103+ struct timeval tv;
104+ int gettimeofday_res;
105+
106+ gettimeofday_res = gettimeofday(&tv, NULL);
107+ assert (gettimeofday_res == 0);
108+
109+ /* Microseconds time is <20 bits entropy */
110+ return tv.tv_usec;
111+#endif
112+}
113+
114+static unsigned long
115+generate_hash_secret_salt(XML_Parser parser)
116+{
117+ /* Process ID is 0 bits entropy if attacker has local access
118+ * XML_Parser address is few bits of entropy if attacker has local access */
119+ const unsigned long entropy =
120+ gather_time_entropy() ^ getpid() ^ (unsigned long)parser;
121+
122+ /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
123+ if (sizeof(unsigned long) == 4) {
124+ return entropy * 2147483647;
125+ } else {
126+ return entropy * 2305843009213693951;
127+ }
128 }
129
130 static XML_Bool /* only valid for root parser */
131@@ -703,7 +737,7 @@ startParsing(XML_Parser parser)
132 {
133 /* hash functions must be initialized before setContext() is called */
134 if (hash_secret_salt == 0)
135- hash_secret_salt = generate_hash_secret_salt();
136+ hash_secret_salt = generate_hash_secret_salt(parser);
137 if (ns) {
138 /* implicit context only set for root parser, since child
139 parsers (i.e. external entity parsers) will inherit it
140--
1412.8.2
142