1 diff -burN android-openssl.orig/openssl.config android-openssl-lhash2/openssl.config 2 --- android-openssl.orig/openssl.config 2013-11-05 14:11:10.833326408 -0500 3 +++ android-openssl-lhash2/openssl.config 2013-11-05 14:38:31.187575574 -0500 4 @@ -997,6 +997,7 @@ 5 fix_clang_build.patch \ 6 x509_hash_name_algorithm_change.patch \ 7 reduce_client_hello_size.patch \ 8 +fix_lhash_iteration.patch \ 9 " 10 11 OPENSSL_PATCHES_progs_SOURCES="\ 12 @@ -1060,3 +1061,13 @@ 13 OPENSSL_PATCHES_reduce_client_hello_size_SOURCES="\ 14 ssl/t1_lib.c \ 15 " 16 + 17 +OPENSSL_PATCHES_fix_lhash_iteration_SOURCES="\ 18 +crypto/conf/conf_api.c 19 +crypto/lhash/lhash.c 20 +crypto/lhash/lhash.h 21 +crypto/objects/o_names.c 22 +crypto/objects/obj_dat.c 23 +include/openssl/lhash.h 24 +ssl/ssl_sess.c 25 +" 26 diff -burN android-openssl.orig/patches/fix_lhash_iteration.patch android-openssl-lhash2/patches/fix_lhash_iteration.patch 27 --- android-openssl.orig/patches/fix_lhash_iteration.patch 1969-12-31 19:00:00.000000000 -0500 28 +++ android-openssl-lhash2/patches/fix_lhash_iteration.patch 2013-11-05 14:38:15.067738011 -0500 29 @@ -0,0 +1,318 @@ 30 +diff -burN android-openssl.orig/crypto/conf/conf_api.c android-openssl-lhash/crypto/conf/conf_api.c 31 +--- android-openssl.orig/crypto/conf/conf_api.c 2013-02-11 10:26:04.000000000 -0500 32 ++++ android-openssl-lhash/crypto/conf/conf_api.c 2013-11-05 14:16:49.500027656 -0500 33 +@@ -225,9 +225,6 @@ 34 + { 35 + if (conf == NULL || conf->data == NULL) return; 36 + 37 +- lh_CONF_VALUE_down_load(conf->data)=0; /* evil thing to make 38 +- * sure the 'OPENSSL_free()' works as 39 +- * expected */ 40 + lh_CONF_VALUE_doall_arg(conf->data, 41 + LHASH_DOALL_ARG_FN(value_free_hash), 42 + LHASH_OF(CONF_VALUE), conf->data); 43 +diff -burN android-openssl.orig/crypto/lhash/lhash.c android-openssl-lhash/crypto/lhash/lhash.c 44 +--- android-openssl.orig/crypto/lhash/lhash.c 2013-02-11 10:26:04.000000000 -0500 45 ++++ android-openssl-lhash/crypto/lhash/lhash.c 2013-11-05 14:16:49.500027656 -0500 46 +@@ -94,6 +94,7 @@ 47 + * 48 + * 1.0 eay - First version 49 + */ 50 ++#include <limits.h> 51 + #include <stdio.h> 52 + #include <string.h> 53 + #include <stdlib.h> 54 +@@ -107,6 +108,113 @@ 55 + #define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ 56 + #define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ 57 + 58 ++/* Maximum number of nodes to guarantee the load computations don't overflow */ 59 ++#define MAX_LOAD_ITEMS (UINT_MAX / LH_LOAD_MULT) 60 ++ 61 ++/* The field 'iteration_state' is used to hold data to ensure that a hash 62 ++ * table is not resized during an 'insert' or 'delete' operation performed 63 ++ * within a lh_doall/lh_doall_arg call. 64 ++ * 65 ++ * Conceptually, this records two things: 66 ++ * 67 ++ * - A 'depth' count, which is incremented at the start of lh_doall*, 68 ++ * and decremented just before it returns. 69 ++ * 70 ++ * - A 'mutated' boolean flag, which is set in lh_insert() or lh_delete() 71 ++ * when the operation is performed with a non-0 depth. 72 ++ * 73 ++ * The following are helper macros to handle this state in a more explicit 74 ++ * way. 75 ++ */ 76 ++ 77 ++/* Reset the iteration state to its defaults. */ 78 ++#define LH_ITERATION_RESET(lh) do { \ 79 ++ (lh)->iteration_state = 0; \ 80 ++ } while (0) 81 ++ 82 ++/* Returns 1 if the hash table is currently being iterated on, 0 otherwise. */ 83 ++#define LH_ITERATION_IS_ACTIVE(lh) ((lh)->iteration_state >= 2) 84 ++ 85 ++/* Increment iteration depth. This should always be followed by a paired call 86 ++ * to LH_ITERATION_DECREMENT_DEPTH(). */ 87 ++#define LH_ITERATION_INCREMENT_DEPTH(lh) do { \ 88 ++ (lh)->iteration_state += 2; \ 89 ++ } while (0) 90 ++ 91 ++/* Decrement iteration depth. This should always be called after a paired call 92 ++ * to LH_ITERATION_INCREMENT_DEPTH(). */ 93 ++#define LH_ITERATION_DECREMENT_DEPTH(lh) do { \ 94 ++ (lh)->iteration_state -= 2; \ 95 ++ } while (0) 96 ++ 97 ++/* Return 1 if the iteration 'mutated' flag is set, 0 otherwise. */ 98 ++#define LH_ITERATION_IS_MUTATED(lh) (((lh)->iteration_state & 1) != 0) 99 ++ 100 ++/* Set the iteration 'mutated' flag to 1. LH_ITERATION_RESET() to reset it. */ 101 ++#define LH_ITERATION_SET_MUTATED(lh) do { \ 102 ++ (lh)->iteration_state |= 1; \ 103 ++ } while (0) 104 ++ 105 ++/* This macro returns 1 if the hash table should be expanded due to its current 106 ++ * load, or 0 otherwise. The exact comparison to be performed is expressed by 107 ++ * the mathematical expression (where '//' denotes division over real numbers): 108 ++ * 109 ++ * (num_items // num_nodes) >= (up_load // LOAD_MULT) or 110 ++ * (num_items * LOAD_MULT // num_nodes) >= up_load. 111 ++ * 112 ++ * Given that the C language operator '/' implements integer division, i.e: 113 ++ * a // b == (a / b) + epsilon (with 0 <= epsilon < 1, for positive a & b) 114 ++ * 115 ++ * This can be rewritten as: 116 ++ * (num_items * LOAD_MULT / num_nodes) + epsilon >= up_load 117 ++ * (num_items * LOAD_MULT / num_nodes) - up_load >= - epsilon 118 ++ * 119 ++ * Let's call 'A' the left-hand side of the equation above, it is an integer 120 ++ * and: 121 ++ * - If A >= 0, the expression is true for any value of epsilon. 122 ++ * - If A <= -1, the expression is also true for any value of epsilon. 123 ++ * 124 ++ * In other words, this is equivalent to 'A >= 0', or: 125 ++ * (num_items * LOAD_MULT / num_nodes) >= up_load 126 ++ */ 127 ++#define LH_SHOULD_EXPAND(lh) \ 128 ++ ((lh)->num_items < MAX_LOAD_ITEMS && \ 129 ++ (((lh)->num_items*LH_LOAD_MULT/(lh)->num_nodes) >= (lh)->up_load)) 130 ++ 131 ++/* This macro returns 1 if the hash table should be contracted due to its 132 ++ * current load, or 0 otherwise. Abbreviated computations are: 133 ++ * 134 ++ * (num_items // num_nodes) <= (down_load // LOAD_MULT) 135 ++ * (num_items * LOAD_MULT // num_nodes) <= down_load 136 ++ * (num_items * LOAD_MULT / num_nodes) + epsilon <= down_load 137 ++ * (num_items * LOAD_MULT / num_nodes) - down_load <= -epsilon 138 ++ * 139 ++ * Let's call 'B' the left-hand side of the equation above: 140 ++ * - If B <= -1, the expression is true for any value of epsilon. 141 ++ * - If B >= 1, the expression is false for any value of epsilon. 142 ++ * - If B == 0, the expression is true for 'epsilon == 0', and false 143 ++ * otherwise, which is problematic. 144 ++ * 145 ++ * To work around this problem, while keeping the code simple, just change 146 ++ * the initial expression to use a strict inequality, i.e.: 147 ++ * 148 ++ * (num_items // num_nodes) < (down_load // LOAD_MULT) 149 ++ * 150 ++ * Which leads to: 151 ++ * (num_items * LOAD_MULT / num_nodes) - down_load < -epsilon 152 ++ * 153 ++ * Then: 154 ++ * - If 'B <= -1', the expression is true for any value of epsilon. 155 ++ * - If 'B' >= 0, the expression is false for any value of epsilon, 156 ++ * 157 ++ * In other words, this is equivalent to 'B < 0', or: 158 ++ * (num_items * LOAD_MULT / num_nodes) < down_load 159 ++ */ 160 ++#define LH_SHOULD_CONTRACT(lh) \ 161 ++ (((lh)->num_nodes > MIN_NODES) && \ 162 ++ ((lh)->num_items < MAX_LOAD_ITEMS && \ 163 ++ ((lh)->num_items*LH_LOAD_MULT/(lh)->num_nodes) < (lh)->down_load)) 164 ++ 165 + static void expand(_LHASH *lh); 166 + static void contract(_LHASH *lh); 167 + static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); 168 +@@ -147,6 +255,7 @@ 169 + ret->num_hash_comps=0; 170 + 171 + ret->error=0; 172 ++ LH_ITERATION_RESET(ret); 173 + return(ret); 174 + err1: 175 + OPENSSL_free(ret); 176 +@@ -183,7 +292,10 @@ 177 + void *ret; 178 + 179 + lh->error=0; 180 +- if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)) 181 ++ /* Do not expand the array if the table is being iterated on. */ 182 ++ if (LH_ITERATION_IS_ACTIVE(lh)) 183 ++ LH_ITERATION_SET_MUTATED(lh); 184 ++ else if (LH_SHOULD_EXPAND(lh)) 185 + expand(lh); 186 + 187 + rn=getrn(lh,data,&hash); 188 +@@ -238,8 +350,10 @@ 189 + } 190 + 191 + lh->num_items--; 192 +- if ((lh->num_nodes > MIN_NODES) && 193 +- (lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))) 194 ++ /* Do not contract the array if the table is being iterated on. */ 195 ++ if (LH_ITERATION_IS_ACTIVE(lh)) 196 ++ LH_ITERATION_SET_MUTATED(lh); 197 ++ else if (LH_SHOULD_CONTRACT(lh)) 198 + contract(lh); 199 + 200 + return(ret); 201 +@@ -276,6 +390,7 @@ 202 + if (lh == NULL) 203 + return; 204 + 205 ++ LH_ITERATION_INCREMENT_DEPTH(lh); 206 + /* reverse the order so we search from 'top to bottom' 207 + * We were having memory leaks otherwise */ 208 + for (i=lh->num_nodes-1; i>=0; i--) 209 +@@ -283,10 +398,7 @@ 210 + a=lh->b[i]; 211 + while (a != NULL) 212 + { 213 +- /* 28/05/91 - eay - n added so items can be deleted 214 +- * via lh_doall */ 215 +- /* 22/05/08 - ben - eh? since a is not passed, 216 +- * this should not be needed */ 217 ++ /* note that 'a' can be deleted by the callback */ 218 + n=a->next; 219 + if(use_arg) 220 + func_arg(a->data,arg); 221 +@@ -295,6 +407,19 @@ 222 + a=n; 223 + } 224 + } 225 ++ 226 ++ LH_ITERATION_DECREMENT_DEPTH(lh); 227 ++ if (!LH_ITERATION_IS_ACTIVE(lh) && LH_ITERATION_IS_MUTATED(lh)) 228 ++ { 229 ++ LH_ITERATION_RESET(lh); 230 ++ /* Resize the buckets array if necessary. Each expand() or 231 ++ * contract() call will double/halve the size of the array, 232 ++ * respectively, so call them in a loop. */ 233 ++ while (LH_SHOULD_EXPAND(lh)) 234 ++ expand(lh); 235 ++ while (LH_SHOULD_CONTRACT(lh)) 236 ++ contract(lh); 237 ++ } 238 + } 239 + 240 + void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func) 241 +diff -burN android-openssl.orig/crypto/lhash/lhash.h android-openssl-lhash/crypto/lhash/lhash.h 242 +--- android-openssl.orig/crypto/lhash/lhash.h 2013-02-11 10:26:04.000000000 -0500 243 ++++ android-openssl-lhash/crypto/lhash/lhash.h 2013-11-05 14:16:49.500027656 -0500 244 +@@ -163,6 +163,7 @@ 245 + unsigned long num_hash_comps; 246 + 247 + int error; 248 ++ int iteration_state; 249 + } _LHASH; /* Do not use _LHASH directly, use LHASH_OF 250 + * and friends */ 251 + 252 +diff -burN android-openssl.orig/crypto/objects/o_names.c android-openssl-lhash/crypto/objects/o_names.c 253 +--- android-openssl.orig/crypto/objects/o_names.c 2013-02-11 10:26:04.000000000 -0500 254 ++++ android-openssl-lhash/crypto/objects/o_names.c 2013-11-05 14:16:49.500027656 -0500 255 +@@ -350,13 +350,9 @@ 256 + 257 + void OBJ_NAME_cleanup(int type) 258 + { 259 +- unsigned long down_load; 260 +- 261 + if (names_lh == NULL) return; 262 + 263 + free_type=type; 264 +- down_load=lh_OBJ_NAME_down_load(names_lh); 265 +- lh_OBJ_NAME_down_load(names_lh)=0; 266 + 267 + lh_OBJ_NAME_doall(names_lh,LHASH_DOALL_FN(names_lh_free)); 268 + if (type < 0) 269 +@@ -366,7 +362,5 @@ 270 + names_lh=NULL; 271 + name_funcs_stack = NULL; 272 + } 273 +- else 274 +- lh_OBJ_NAME_down_load(names_lh)=down_load; 275 + } 276 + 277 +diff -burN android-openssl.orig/crypto/objects/obj_dat.c android-openssl-lhash/crypto/objects/obj_dat.c 278 +--- android-openssl.orig/crypto/objects/obj_dat.c 2013-02-11 10:26:04.000000000 -0500 279 ++++ android-openssl-lhash/crypto/objects/obj_dat.c 2013-11-05 14:16:49.500027656 -0500 280 +@@ -227,7 +227,6 @@ 281 + return ; 282 + } 283 + if (added == NULL) return; 284 +- lh_ADDED_OBJ_down_load(added) = 0; 285 + lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */ 286 + lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */ 287 + lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */ 288 +diff -burN android-openssl.orig/include/openssl/lhash.h android-openssl-lhash/include/openssl/lhash.h 289 +--- android-openssl.orig/include/openssl/lhash.h 2013-11-05 14:11:20.903223251 -0500 290 ++++ android-openssl-lhash/include/openssl/lhash.h 2013-11-05 14:16:49.500027656 -0500 291 +@@ -163,6 +163,7 @@ 292 + unsigned long num_hash_comps; 293 + 294 + int error; 295 ++ int iteration_state; 296 + } _LHASH; /* Do not use _LHASH directly, use LHASH_OF 297 + * and friends */ 298 + 299 +diff -burN android-openssl.orig/include/openssl/ssl.h android-openssl-lhash/include/openssl/ssl.h 300 +--- android-openssl.orig/include/openssl/ssl.h 2013-11-05 14:11:21.013222124 -0500 301 ++++ android-openssl-lhash/include/openssl/ssl.h 2013-11-05 14:16:49.500027656 -0500 302 +@@ -1681,10 +1681,10 @@ 303 + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) 304 + 305 + /* SSL_enable_tls_channel_id either configures a TLS server to accept TLS client 306 +- * IDs from clients, or configure a client to send TLS client IDs to server. 307 ++ * IDs from clients, or configures a client to send TLS client IDs to server. 308 + * Returns 1 on success. */ 309 +-#define SSL_enable_tls_channel_id(s) \ 310 +- SSL_ctrl(s,SSL_CTRL_CHANNEL_ID,0,NULL) 311 ++#define SSL_enable_tls_channel_id(ssl) \ 312 ++ SSL_ctrl(ssl,SSL_CTRL_CHANNEL_ID,0,NULL) 313 + /* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to 314 + * compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on 315 + * success. */ 316 +diff -burN android-openssl.orig/ssl/ssl.h android-openssl-lhash/ssl/ssl.h 317 +--- android-openssl.orig/ssl/ssl.h 2013-11-05 14:11:18.363249269 -0500 318 ++++ android-openssl-lhash/ssl/ssl.h 2013-11-05 14:16:49.510027563 -0500 319 +@@ -1681,10 +1681,10 @@ 320 + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) 321 + 322 + /* SSL_enable_tls_channel_id either configures a TLS server to accept TLS client 323 +- * IDs from clients, or configure a client to send TLS client IDs to server. 324 ++ * IDs from clients, or configures a client to send TLS client IDs to server. 325 + * Returns 1 on success. */ 326 +-#define SSL_enable_tls_channel_id(s) \ 327 +- SSL_ctrl(s,SSL_CTRL_CHANNEL_ID,0,NULL) 328 ++#define SSL_enable_tls_channel_id(ssl) \ 329 ++ SSL_ctrl(ssl,SSL_CTRL_CHANNEL_ID,0,NULL) 330 + /* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to 331 + * compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on 332 + * success. */ 333 +diff -burN android-openssl.orig/ssl/ssl_sess.c android-openssl-lhash/ssl/ssl_sess.c 334 +--- android-openssl.orig/ssl/ssl_sess.c 2013-11-05 14:11:18.363249269 -0500 335 ++++ android-openssl-lhash/ssl/ssl_sess.c 2013-11-05 14:16:49.510027563 -0500 336 +@@ -999,11 +999,8 @@ 337 + if (tp.cache == NULL) return; 338 + tp.time=t; 339 + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 340 +- i=CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; 341 +- CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=0; 342 + lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), 343 + TIMEOUT_PARAM, &tp); 344 +- CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=i; 345 + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 346 + } 347 + 348