1 This patch copied/pasted from this link: |
|
2 http://git.gnome.org/browse/libxml2/patch/?id=8973d58b7498fa5100a876815476b81fd1a2412a |
|
3 ---------------------------------------------------------------------- |
|
4 From 8973d58b7498fa5100a876815476b81fd1a2412a Mon Sep 17 00:00:00 2001 |
|
5 From: Daniel Veillard <[email protected]> |
|
6 Date: Sat, 04 Feb 2012 11:07:44 +0000 |
|
7 Subject: Add hash randomization to hash and dict structures |
|
8 |
|
9 Following http://www.ocert.org/advisories/ocert-2011-003.html |
|
10 it seems that having hash randomization might be a good idea |
|
11 when using XML with untrusted data |
|
12 * configure.in: lookup for rand, srand and time |
|
13 * dict.c: add randomization to dictionaries hash tables |
|
14 * hash.c: add randomization to normal hash tables |
|
15 --- |
|
16 diff --git a/configure.in b/configure.in |
|
17 index fa80375..828b66a 100644 |
|
18 --- a/configure.in |
|
19 +++ b/configure.in |
|
20 @@ -512,6 +512,7 @@ AC_CHECK_FUNCS(strdup strndup strerror) |
|
21 AC_CHECK_FUNCS(finite isnand fp_class class fpclass) |
|
22 AC_CHECK_FUNCS(strftime localtime gettimeofday ftime) |
|
23 AC_CHECK_FUNCS(stat _stat signal) |
|
24 +AC_CHECK_FUNCS(rand srand time) |
|
25 |
|
26 dnl Checking the standard string functions availability |
|
27 AC_CHECK_FUNCS(printf sprintf fprintf snprintf vfprintf vsprintf vsnprintf sscanf,, |
|
28 diff --git a/dict.c b/dict.c |
|
29 index 3eff231..ae4966b 100644 |
|
30 --- a/dict.c |
|
31 +++ b/dict.c |
|
32 @@ -2,7 +2,7 @@ |
|
33 * dict.c: dictionary of reusable strings, just used to avoid allocation |
|
34 * and freeing operations. |
|
35 * |
|
36 - * Copyright (C) 2003 Daniel Veillard. |
|
37 + * Copyright (C) 2003-2012 Daniel Veillard. |
|
38 * |
|
39 * Permission to use, copy, modify, and distribute this software for any |
|
40 * purpose with or without fee is hereby granted, provided that the above |
|
41 @@ -19,6 +19,28 @@ |
|
42 #define IN_LIBXML |
|
43 #include "libxml.h" |
|
44 |
|
45 +#ifdef HAVE_STDLIB_H |
|
46 +#include <stdlib.h> |
|
47 +#endif |
|
48 +#ifdef HAVE_TIME_H |
|
49 +#include <time.h> |
|
50 +#endif |
|
51 + |
|
52 +/* |
|
53 + * Following http://www.ocert.org/advisories/ocert-2011-003.html |
|
54 + * it seems that having hash randomization might be a good idea |
|
55 + * when using XML with untrusted data |
|
56 + * Note1: that it works correctly only if compiled with WITH_BIG_KEY |
|
57 + * which is the default. |
|
58 + * Note2: the fast function used for a small dict won't protect very |
|
59 + * well but since the attack is based on growing a very big hash |
|
60 + * list we will use the BigKey algo as soon as the hash size grows |
|
61 + * over MIN_DICT_SIZE so this actually works |
|
62 + */ |
|
63 +#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME) |
|
64 +#define DICT_RANDOMIZATION |
|
65 +#endif |
|
66 + |
|
67 #include <string.h> |
|
68 #ifdef HAVE_STDINT_H |
|
69 #include <stdint.h> |
|
70 @@ -44,23 +66,23 @@ typedef unsigned __int32 uint32_t; |
|
71 #define WITH_BIG_KEY |
|
72 |
|
73 #ifdef WITH_BIG_KEY |
|
74 -#define xmlDictComputeKey(dict, name, len) \ |
|
75 - (((dict)->size == MIN_DICT_SIZE) ? \ |
|
76 - xmlDictComputeFastKey(name, len) : \ |
|
77 - xmlDictComputeBigKey(name, len)) |
|
78 - |
|
79 -#define xmlDictComputeQKey(dict, prefix, plen, name, len) \ |
|
80 - (((prefix) == NULL) ? \ |
|
81 - (xmlDictComputeKey(dict, name, len)) : \ |
|
82 - (((dict)->size == MIN_DICT_SIZE) ? \ |
|
83 - xmlDictComputeFastQKey(prefix, plen, name, len) : \ |
|
84 - xmlDictComputeBigQKey(prefix, plen, name, len))) |
|
85 +#define xmlDictComputeKey(dict, name, len) \ |
|
86 + (((dict)->size == MIN_DICT_SIZE) ? \ |
|
87 + xmlDictComputeFastKey(name, len, (dict)->seed) : \ |
|
88 + xmlDictComputeBigKey(name, len, (dict)->seed)) |
|
89 + |
|
90 +#define xmlDictComputeQKey(dict, prefix, plen, name, len) \ |
|
91 + (((prefix) == NULL) ? \ |
|
92 + (xmlDictComputeKey(dict, name, len)) : \ |
|
93 + (((dict)->size == MIN_DICT_SIZE) ? \ |
|
94 + xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed) : \ |
|
95 + xmlDictComputeBigQKey(prefix, plen, name, len, (dict)->seed))) |
|
96 |
|
97 #else /* !WITH_BIG_KEY */ |
|
98 -#define xmlDictComputeKey(dict, name, len) \ |
|
99 - xmlDictComputeFastKey(name, len) |
|
100 -#define xmlDictComputeQKey(dict, prefix, plen, name, len) \ |
|
101 - xmlDictComputeFastQKey(prefix, plen, name, len) |
|
102 +#define xmlDictComputeKey(dict, name, len) \ |
|
103 + xmlDictComputeFastKey(name, len, (dict)->seed) |
|
104 +#define xmlDictComputeQKey(dict, prefix, plen, name, len) \ |
|
105 + xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed) |
|
106 #endif /* WITH_BIG_KEY */ |
|
107 |
|
108 /* |
|
109 @@ -98,6 +120,8 @@ struct _xmlDict { |
|
110 xmlDictStringsPtr strings; |
|
111 |
|
112 struct _xmlDict *subdict; |
|
113 + /* used for randomization */ |
|
114 + int seed; |
|
115 }; |
|
116 |
|
117 /* |
|
118 @@ -125,6 +149,9 @@ static int xmlInitializeDict(void) { |
|
119 if ((xmlDictMutex = xmlNewRMutex()) == NULL) |
|
120 return(0); |
|
121 |
|
122 +#ifdef DICT_RANDOMIZATION |
|
123 + srand(time(NULL)); |
|
124 +#endif |
|
125 xmlDictInitialized = 1; |
|
126 return(1); |
|
127 } |
|
128 @@ -277,13 +304,13 @@ found_pool: |
|
129 */ |
|
130 |
|
131 static uint32_t |
|
132 -xmlDictComputeBigKey(const xmlChar* data, int namelen) { |
|
133 +xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) { |
|
134 uint32_t hash; |
|
135 int i; |
|
136 |
|
137 if (namelen <= 0 || data == NULL) return(0); |
|
138 |
|
139 - hash = 0; |
|
140 + hash = seed; |
|
141 |
|
142 for (i = 0;i < namelen; i++) { |
|
143 hash += data[i]; |
|
144 @@ -310,12 +337,12 @@ xmlDictComputeBigKey(const xmlChar* data, int namelen) { |
|
145 */ |
|
146 static unsigned long |
|
147 xmlDictComputeBigQKey(const xmlChar *prefix, int plen, |
|
148 - const xmlChar *name, int len) |
|
149 + const xmlChar *name, int len, int seed) |
|
150 { |
|
151 uint32_t hash; |
|
152 int i; |
|
153 |
|
154 - hash = 0; |
|
155 + hash = seed; |
|
156 |
|
157 for (i = 0;i < plen; i++) { |
|
158 hash += prefix[i]; |
|
159 @@ -346,8 +373,8 @@ xmlDictComputeBigQKey(const xmlChar *prefix, int plen, |
|
160 * for low hash table fill. |
|
161 */ |
|
162 static unsigned long |
|
163 -xmlDictComputeFastKey(const xmlChar *name, int namelen) { |
|
164 - unsigned long value = 0L; |
|
165 +xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) { |
|
166 + unsigned long value = seed; |
|
167 |
|
168 if (name == NULL) return(0); |
|
169 value = *name; |
|
170 @@ -381,9 +408,9 @@ xmlDictComputeFastKey(const xmlChar *name, int namelen) { |
|
171 */ |
|
172 static unsigned long |
|
173 xmlDictComputeFastQKey(const xmlChar *prefix, int plen, |
|
174 - const xmlChar *name, int len) |
|
175 + const xmlChar *name, int len, int seed) |
|
176 { |
|
177 - unsigned long value = 0L; |
|
178 + unsigned long value = (unsigned long) seed; |
|
179 |
|
180 if (plen == 0) |
|
181 value += 30 * (unsigned long) ':'; |
|
182 @@ -460,6 +487,11 @@ xmlDictCreate(void) { |
|
183 dict->subdict = NULL; |
|
184 if (dict->dict) { |
|
185 memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry)); |
|
186 +#ifdef DICT_RANDOMIZATION |
|
187 + dict->seed = rand(); |
|
188 +#else |
|
189 + dict->seed = 0; |
|
190 +#endif |
|
191 return(dict); |
|
192 } |
|
193 xmlFree(dict); |
|
194 @@ -486,6 +518,7 @@ xmlDictCreateSub(xmlDictPtr sub) { |
|
195 #ifdef DICT_DEBUG_PATTERNS |
|
196 fprintf(stderr, "R"); |
|
197 #endif |
|
198 + dict->seed = sub->seed; |
|
199 dict->subdict = sub; |
|
200 xmlDictReference(dict->subdict); |
|
201 } |
|
202 diff --git a/hash.c b/hash.c |
|
203 index b78bc2d..fe1424f 100644 |
|
204 --- a/hash.c |
|
205 +++ b/hash.c |
|
206 @@ -3,7 +3,7 @@ |
|
207 * |
|
208 * Reference: Your favorite introductory book on algorithms |
|
209 * |
|
210 - * Copyright (C) 2000 Bjorn Reese and Daniel Veillard. |
|
211 + * Copyright (C) 2000,2012 Bjorn Reese and Daniel Veillard. |
|
212 * |
|
213 * Permission to use, copy, modify, and distribute this software for any |
|
214 * purpose with or without fee is hereby granted, provided that the above |
|
215 @@ -21,6 +21,22 @@ |
|
216 #include "libxml.h" |
|
217 |
|
218 #include <string.h> |
|
219 +#ifdef HAVE_STDLIB_H |
|
220 +#include <stdlib.h> |
|
221 +#endif |
|
222 +#ifdef HAVE_TIME_H |
|
223 +#include <time.h> |
|
224 +#endif |
|
225 + |
|
226 +/* |
|
227 + * Following http://www.ocert.org/advisories/ocert-2011-003.html |
|
228 + * it seems that having hash randomization might be a good idea |
|
229 + * when using XML with untrusted data |
|
230 + */ |
|
231 +#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME) |
|
232 +#define HASH_RANDOMIZATION |
|
233 +#endif |
|
234 + |
|
235 #include <libxml/parser.h> |
|
236 #include <libxml/hash.h> |
|
237 #include <libxml/xmlmemory.h> |
|
238 @@ -31,6 +47,10 @@ |
|
239 |
|
240 /* #define DEBUG_GROW */ |
|
241 |
|
242 +#ifdef HASH_RANDOMIZATION |
|
243 +static int hash_initialized = 0; |
|
244 +#endif |
|
245 + |
|
246 /* |
|
247 * A single entry in the hash table |
|
248 */ |
|
249 @@ -53,6 +73,9 @@ struct _xmlHashTable { |
|
250 int size; |
|
251 int nbElems; |
|
252 xmlDictPtr dict; |
|
253 +#ifdef HASH_RANDOMIZATION |
|
254 + int random_seed; |
|
255 +#endif |
|
256 }; |
|
257 |
|
258 /* |
|
259 @@ -65,6 +88,9 @@ xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name, |
|
260 unsigned long value = 0L; |
|
261 char ch; |
|
262 |
|
263 +#ifdef HASH_RANDOMIZATION |
|
264 + value = table->random_seed; |
|
265 +#endif |
|
266 if (name != NULL) { |
|
267 value += 30 * (*name); |
|
268 while ((ch = *name++) != 0) { |
|
269 @@ -92,6 +118,9 @@ xmlHashComputeQKey(xmlHashTablePtr table, |
|
270 unsigned long value = 0L; |
|
271 char ch; |
|
272 |
|
273 +#ifdef HASH_RANDOMIZATION |
|
274 + value = table->random_seed; |
|
275 +#endif |
|
276 if (prefix != NULL) |
|
277 value += 30 * (*prefix); |
|
278 else |
|
279 @@ -156,6 +185,13 @@ xmlHashCreate(int size) { |
|
280 table->table = xmlMalloc(size * sizeof(xmlHashEntry)); |
|
281 if (table->table) { |
|
282 memset(table->table, 0, size * sizeof(xmlHashEntry)); |
|
283 +#ifdef HASH_RANDOMIZATION |
|
284 + if (!hash_initialized) { |
|
285 + srand(time(NULL)); |
|
286 + hash_initialized = 1; |
|
287 + } |
|
288 + table->random_seed = rand(); |
|
289 +#endif |
|
290 return(table); |
|
291 } |
|
292 xmlFree(table); |
|
293 -- |
|
294 cgit v0.9.0.2 |
|