diff options
author | agl@chromium.org <agl@chromium.org@4ff67af0-8c30-449e-8e8b-ad334ec8d88c> | 2013-11-05 19:42:31 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@4ff67af0-8c30-449e-8e8b-ad334ec8d88c> | 2013-11-05 19:42:31 +0000 |
commit | cf2eb320f09318966c9ae11c565615a16b453fff (patch) | |
tree | 228aa3c6f8b55aa7f7b58bfc6b8a7654d9590c61 /patches.chromium | |
parent | 2365a8a9a3b43f6f8c93f638aa6dc61aa8577f45 (diff) | |
download | openssl-cf2eb320f09318966c9ae11c565615a16b453fff.tar.gz |
Fix the patch file from r233053.
The patch file should be a patch that adds a patch, and that patch should do
the actual patching, except for openssl.config, which should be patched
directly.
git-svn-id: http://src.chromium.org/svn/trunk/deps/third_party/openssl@233061 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
Diffstat (limited to 'patches.chromium')
-rw-r--r-- | patches.chromium/0006-lhashfix | 343 | ||||
-rw-r--r-- | patches.chromium/0006-lhashfix.patch | 347 |
2 files changed, 347 insertions, 343 deletions
diff --git a/patches.chromium/0006-lhashfix b/patches.chromium/0006-lhashfix deleted file mode 100644 index eb3ac1d..0000000 --- a/patches.chromium/0006-lhashfix +++ /dev/null @@ -1,343 +0,0 @@ -diff -burN android-openssl.orig/crypto/conf/conf_api.c android-openssl-lhash/crypto/conf/conf_api.c ---- android-openssl.orig/crypto/conf/conf_api.c 2013-02-11 10:26:04.000000000 -0500 -+++ android-openssl-lhash/crypto/conf/conf_api.c 2013-11-05 14:16:49.500027656 -0500 -@@ -225,9 +225,6 @@ - { - if (conf == NULL || conf->data == NULL) return; - -- lh_CONF_VALUE_down_load(conf->data)=0; /* evil thing to make -- * sure the 'OPENSSL_free()' works as -- * expected */ - lh_CONF_VALUE_doall_arg(conf->data, - LHASH_DOALL_ARG_FN(value_free_hash), - LHASH_OF(CONF_VALUE), conf->data); -diff -burN android-openssl.orig/crypto/lhash/lhash.c android-openssl-lhash/crypto/lhash/lhash.c ---- android-openssl.orig/crypto/lhash/lhash.c 2013-02-11 10:26:04.000000000 -0500 -+++ android-openssl-lhash/crypto/lhash/lhash.c 2013-11-05 14:16:49.500027656 -0500 -@@ -94,6 +94,7 @@ - * - * 1.0 eay - First version - */ -+#include <limits.h> - #include <stdio.h> - #include <string.h> - #include <stdlib.h> -@@ -107,6 +108,113 @@ - #define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ - #define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ - -+/* Maximum number of nodes to guarantee the load computations don't overflow */ -+#define MAX_LOAD_ITEMS (UINT_MAX / LH_LOAD_MULT) -+ -+/* The field 'iteration_state' is used to hold data to ensure that a hash -+ * table is not resized during an 'insert' or 'delete' operation performed -+ * within a lh_doall/lh_doall_arg call. -+ * -+ * Conceptually, this records two things: -+ * -+ * - A 'depth' count, which is incremented at the start of lh_doall*, -+ * and decremented just before it returns. -+ * -+ * - A 'mutated' boolean flag, which is set in lh_insert() or lh_delete() -+ * when the operation is performed with a non-0 depth. -+ * -+ * The following are helper macros to handle this state in a more explicit -+ * way. -+ */ -+ -+/* Reset the iteration state to its defaults. */ -+#define LH_ITERATION_RESET(lh) do { \ -+ (lh)->iteration_state = 0; \ -+ } while (0) -+ -+/* Returns 1 if the hash table is currently being iterated on, 0 otherwise. */ -+#define LH_ITERATION_IS_ACTIVE(lh) ((lh)->iteration_state >= 2) -+ -+/* Increment iteration depth. This should always be followed by a paired call -+ * to LH_ITERATION_DECREMENT_DEPTH(). */ -+#define LH_ITERATION_INCREMENT_DEPTH(lh) do { \ -+ (lh)->iteration_state += 2; \ -+ } while (0) -+ -+/* Decrement iteration depth. This should always be called after a paired call -+ * to LH_ITERATION_INCREMENT_DEPTH(). */ -+#define LH_ITERATION_DECREMENT_DEPTH(lh) do { \ -+ (lh)->iteration_state -= 2; \ -+ } while (0) -+ -+/* Return 1 if the iteration 'mutated' flag is set, 0 otherwise. */ -+#define LH_ITERATION_IS_MUTATED(lh) (((lh)->iteration_state & 1) != 0) -+ -+/* Set the iteration 'mutated' flag to 1. LH_ITERATION_RESET() to reset it. */ -+#define LH_ITERATION_SET_MUTATED(lh) do { \ -+ (lh)->iteration_state |= 1; \ -+ } while (0) -+ -+/* This macro returns 1 if the hash table should be expanded due to its current -+ * load, or 0 otherwise. The exact comparison to be performed is expressed by -+ * the mathematical expression (where '//' denotes division over real numbers): -+ * -+ * (num_items // num_nodes) >= (up_load // LOAD_MULT) or -+ * (num_items * LOAD_MULT // num_nodes) >= up_load. -+ * -+ * Given that the C language operator '/' implements integer division, i.e: -+ * a // b == (a / b) + epsilon (with 0 <= epsilon < 1, for positive a & b) -+ * -+ * This can be rewritten as: -+ * (num_items * LOAD_MULT / num_nodes) + epsilon >= up_load -+ * (num_items * LOAD_MULT / num_nodes) - up_load >= - epsilon -+ * -+ * Let's call 'A' the left-hand side of the equation above, it is an integer -+ * and: -+ * - If A >= 0, the expression is true for any value of epsilon. -+ * - If A <= -1, the expression is also true for any value of epsilon. -+ * -+ * In other words, this is equivalent to 'A >= 0', or: -+ * (num_items * LOAD_MULT / num_nodes) >= up_load -+ */ -+#define LH_SHOULD_EXPAND(lh) \ -+ ((lh)->num_items < MAX_LOAD_ITEMS && \ -+ (((lh)->num_items*LH_LOAD_MULT/(lh)->num_nodes) >= (lh)->up_load)) -+ -+/* This macro returns 1 if the hash table should be contracted due to its -+ * current load, or 0 otherwise. Abbreviated computations are: -+ * -+ * (num_items // num_nodes) <= (down_load // LOAD_MULT) -+ * (num_items * LOAD_MULT // num_nodes) <= down_load -+ * (num_items * LOAD_MULT / num_nodes) + epsilon <= down_load -+ * (num_items * LOAD_MULT / num_nodes) - down_load <= -epsilon -+ * -+ * Let's call 'B' the left-hand side of the equation above: -+ * - If B <= -1, the expression is true for any value of epsilon. -+ * - If B >= 1, the expression is false for any value of epsilon. -+ * - If B == 0, the expression is true for 'epsilon == 0', and false -+ * otherwise, which is problematic. -+ * -+ * To work around this problem, while keeping the code simple, just change -+ * the initial expression to use a strict inequality, i.e.: -+ * -+ * (num_items // num_nodes) < (down_load // LOAD_MULT) -+ * -+ * Which leads to: -+ * (num_items * LOAD_MULT / num_nodes) - down_load < -epsilon -+ * -+ * Then: -+ * - If 'B <= -1', the expression is true for any value of epsilon. -+ * - If 'B' >= 0, the expression is false for any value of epsilon, -+ * -+ * In other words, this is equivalent to 'B < 0', or: -+ * (num_items * LOAD_MULT / num_nodes) < down_load -+ */ -+#define LH_SHOULD_CONTRACT(lh) \ -+ (((lh)->num_nodes > MIN_NODES) && \ -+ ((lh)->num_items < MAX_LOAD_ITEMS && \ -+ ((lh)->num_items*LH_LOAD_MULT/(lh)->num_nodes) < (lh)->down_load)) -+ - static void expand(_LHASH *lh); - static void contract(_LHASH *lh); - static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); -@@ -147,6 +255,7 @@ - ret->num_hash_comps=0; - - ret->error=0; -+ LH_ITERATION_RESET(ret); - return(ret); - err1: - OPENSSL_free(ret); -@@ -183,7 +292,10 @@ - void *ret; - - lh->error=0; -- if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)) -+ /* Do not expand the array if the table is being iterated on. */ -+ if (LH_ITERATION_IS_ACTIVE(lh)) -+ LH_ITERATION_SET_MUTATED(lh); -+ else if (LH_SHOULD_EXPAND(lh)) - expand(lh); - - rn=getrn(lh,data,&hash); -@@ -238,8 +350,10 @@ - } - - lh->num_items--; -- if ((lh->num_nodes > MIN_NODES) && -- (lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))) -+ /* Do not contract the array if the table is being iterated on. */ -+ if (LH_ITERATION_IS_ACTIVE(lh)) -+ LH_ITERATION_SET_MUTATED(lh); -+ else if (LH_SHOULD_CONTRACT(lh)) - contract(lh); - - return(ret); -@@ -276,6 +390,7 @@ - if (lh == NULL) - return; - -+ LH_ITERATION_INCREMENT_DEPTH(lh); - /* reverse the order so we search from 'top to bottom' - * We were having memory leaks otherwise */ - for (i=lh->num_nodes-1; i>=0; i--) -@@ -283,10 +398,7 @@ - a=lh->b[i]; - while (a != NULL) - { -- /* 28/05/91 - eay - n added so items can be deleted -- * via lh_doall */ -- /* 22/05/08 - ben - eh? since a is not passed, -- * this should not be needed */ -+ /* note that 'a' can be deleted by the callback */ - n=a->next; - if(use_arg) - func_arg(a->data,arg); -@@ -295,6 +407,19 @@ - a=n; - } - } -+ -+ LH_ITERATION_DECREMENT_DEPTH(lh); -+ if (!LH_ITERATION_IS_ACTIVE(lh) && LH_ITERATION_IS_MUTATED(lh)) -+ { -+ LH_ITERATION_RESET(lh); -+ /* Resize the buckets array if necessary. Each expand() or -+ * contract() call will double/halve the size of the array, -+ * respectively, so call them in a loop. */ -+ while (LH_SHOULD_EXPAND(lh)) -+ expand(lh); -+ while (LH_SHOULD_CONTRACT(lh)) -+ contract(lh); -+ } - } - - void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func) -diff -burN android-openssl.orig/crypto/lhash/lhash.h android-openssl-lhash/crypto/lhash/lhash.h ---- android-openssl.orig/crypto/lhash/lhash.h 2013-02-11 10:26:04.000000000 -0500 -+++ android-openssl-lhash/crypto/lhash/lhash.h 2013-11-05 14:16:49.500027656 -0500 -@@ -163,6 +163,7 @@ - unsigned long num_hash_comps; - - int error; -+ int iteration_state; - } _LHASH; /* Do not use _LHASH directly, use LHASH_OF - * and friends */ - -diff -burN android-openssl.orig/crypto/objects/o_names.c android-openssl-lhash/crypto/objects/o_names.c ---- android-openssl.orig/crypto/objects/o_names.c 2013-02-11 10:26:04.000000000 -0500 -+++ android-openssl-lhash/crypto/objects/o_names.c 2013-11-05 14:16:49.500027656 -0500 -@@ -350,13 +350,9 @@ - - void OBJ_NAME_cleanup(int type) - { -- unsigned long down_load; -- - if (names_lh == NULL) return; - - free_type=type; -- down_load=lh_OBJ_NAME_down_load(names_lh); -- lh_OBJ_NAME_down_load(names_lh)=0; - - lh_OBJ_NAME_doall(names_lh,LHASH_DOALL_FN(names_lh_free)); - if (type < 0) -@@ -366,7 +362,5 @@ - names_lh=NULL; - name_funcs_stack = NULL; - } -- else -- lh_OBJ_NAME_down_load(names_lh)=down_load; - } - -diff -burN android-openssl.orig/crypto/objects/obj_dat.c android-openssl-lhash/crypto/objects/obj_dat.c ---- android-openssl.orig/crypto/objects/obj_dat.c 2013-02-11 10:26:04.000000000 -0500 -+++ android-openssl-lhash/crypto/objects/obj_dat.c 2013-11-05 14:16:49.500027656 -0500 -@@ -227,7 +227,6 @@ - return ; - } - if (added == NULL) return; -- lh_ADDED_OBJ_down_load(added) = 0; - lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */ - lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */ - lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */ -diff -burN android-openssl.orig/include/openssl/lhash.h android-openssl-lhash/include/openssl/lhash.h ---- android-openssl.orig/include/openssl/lhash.h 2013-11-05 14:11:20.903223251 -0500 -+++ android-openssl-lhash/include/openssl/lhash.h 2013-11-05 14:16:49.500027656 -0500 -@@ -163,6 +163,7 @@ - unsigned long num_hash_comps; - - int error; -+ int iteration_state; - } _LHASH; /* Do not use _LHASH directly, use LHASH_OF - * and friends */ - -diff -burN android-openssl.orig/include/openssl/ssl.h android-openssl-lhash/include/openssl/ssl.h ---- android-openssl.orig/include/openssl/ssl.h 2013-11-05 14:11:21.013222124 -0500 -+++ android-openssl-lhash/include/openssl/ssl.h 2013-11-05 14:16:49.500027656 -0500 -@@ -1681,10 +1681,10 @@ - SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) - - /* SSL_enable_tls_channel_id either configures a TLS server to accept TLS client -- * IDs from clients, or configure a client to send TLS client IDs to server. -+ * IDs from clients, or configures a client to send TLS client IDs to server. - * Returns 1 on success. */ --#define SSL_enable_tls_channel_id(s) \ -- SSL_ctrl(s,SSL_CTRL_CHANNEL_ID,0,NULL) -+#define SSL_enable_tls_channel_id(ssl) \ -+ SSL_ctrl(ssl,SSL_CTRL_CHANNEL_ID,0,NULL) - /* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to - * compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on - * success. */ -diff -burN android-openssl.orig/openssl.config android-openssl-lhash/openssl.config ---- android-openssl.orig/openssl.config 2013-11-05 14:11:10.833326408 -0500 -+++ android-openssl-lhash/openssl.config 2013-11-05 14:16:49.500027656 -0500 -@@ -997,6 +997,7 @@ - fix_clang_build.patch \ - x509_hash_name_algorithm_change.patch \ - reduce_client_hello_size.patch \ -+fix_lhash_iteration.patch \ - " - - OPENSSL_PATCHES_progs_SOURCES="\ -@@ -1060,3 +1061,13 @@ - OPENSSL_PATCHES_reduce_client_hello_size_SOURCES="\ - ssl/t1_lib.c \ - " -+ -+OPENSSL_PATCHES_fix_lhash_iteration_SOURCES="\ -+crypto/conf/conf_api.c -+crypto/lhash/lhash.c -+crypto/lhash/lhash.h -+crypto/objects/o_names.c -+crypto/objects/obj_dat.c -+include/openssl/lhash.h -+ssl/ssl_sess.c -+" -diff -burN android-openssl.orig/ssl/ssl.h android-openssl-lhash/ssl/ssl.h ---- android-openssl.orig/ssl/ssl.h 2013-11-05 14:11:18.363249269 -0500 -+++ android-openssl-lhash/ssl/ssl.h 2013-11-05 14:16:49.510027563 -0500 -@@ -1681,10 +1681,10 @@ - SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) - - /* SSL_enable_tls_channel_id either configures a TLS server to accept TLS client -- * IDs from clients, or configure a client to send TLS client IDs to server. -+ * IDs from clients, or configures a client to send TLS client IDs to server. - * Returns 1 on success. */ --#define SSL_enable_tls_channel_id(s) \ -- SSL_ctrl(s,SSL_CTRL_CHANNEL_ID,0,NULL) -+#define SSL_enable_tls_channel_id(ssl) \ -+ SSL_ctrl(ssl,SSL_CTRL_CHANNEL_ID,0,NULL) - /* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to - * compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on - * success. */ -diff -burN android-openssl.orig/ssl/ssl_sess.c android-openssl-lhash/ssl/ssl_sess.c ---- android-openssl.orig/ssl/ssl_sess.c 2013-11-05 14:11:18.363249269 -0500 -+++ android-openssl-lhash/ssl/ssl_sess.c 2013-11-05 14:16:49.510027563 -0500 -@@ -999,11 +999,8 @@ - if (tp.cache == NULL) return; - tp.time=t; - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); -- i=CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; -- CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=0; - lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), - TIMEOUT_PARAM, &tp); -- CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=i; - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - } - diff --git a/patches.chromium/0006-lhashfix.patch b/patches.chromium/0006-lhashfix.patch new file mode 100644 index 0000000..f8e6119 --- /dev/null +++ b/patches.chromium/0006-lhashfix.patch @@ -0,0 +1,347 @@ +diff -burN android-openssl.orig/openssl.config android-openssl-lhash2/openssl.config +--- android-openssl.orig/openssl.config 2013-11-05 14:11:10.833326408 -0500 ++++ android-openssl-lhash2/openssl.config 2013-11-05 14:38:31.187575574 -0500 +@@ -997,6 +997,7 @@ + fix_clang_build.patch \ + x509_hash_name_algorithm_change.patch \ + reduce_client_hello_size.patch \ ++fix_lhash_iteration.patch \ + " + + OPENSSL_PATCHES_progs_SOURCES="\ +@@ -1060,3 +1061,13 @@ + OPENSSL_PATCHES_reduce_client_hello_size_SOURCES="\ + ssl/t1_lib.c \ + " ++ ++OPENSSL_PATCHES_fix_lhash_iteration_SOURCES="\ ++crypto/conf/conf_api.c ++crypto/lhash/lhash.c ++crypto/lhash/lhash.h ++crypto/objects/o_names.c ++crypto/objects/obj_dat.c ++include/openssl/lhash.h ++ssl/ssl_sess.c ++" +diff -burN android-openssl.orig/patches/fix_lhash_iteration.patch android-openssl-lhash2/patches/fix_lhash_iteration.patch +--- android-openssl.orig/patches/fix_lhash_iteration.patch 1969-12-31 19:00:00.000000000 -0500 ++++ android-openssl-lhash2/patches/fix_lhash_iteration.patch 2013-11-05 14:38:15.067738011 -0500 +@@ -0,0 +1,318 @@ ++diff -burN android-openssl.orig/crypto/conf/conf_api.c android-openssl-lhash/crypto/conf/conf_api.c ++--- android-openssl.orig/crypto/conf/conf_api.c 2013-02-11 10:26:04.000000000 -0500 +++++ android-openssl-lhash/crypto/conf/conf_api.c 2013-11-05 14:16:49.500027656 -0500 ++@@ -225,9 +225,6 @@ ++ { ++ if (conf == NULL || conf->data == NULL) return; ++ ++- lh_CONF_VALUE_down_load(conf->data)=0; /* evil thing to make ++- * sure the 'OPENSSL_free()' works as ++- * expected */ ++ lh_CONF_VALUE_doall_arg(conf->data, ++ LHASH_DOALL_ARG_FN(value_free_hash), ++ LHASH_OF(CONF_VALUE), conf->data); ++diff -burN android-openssl.orig/crypto/lhash/lhash.c android-openssl-lhash/crypto/lhash/lhash.c ++--- android-openssl.orig/crypto/lhash/lhash.c 2013-02-11 10:26:04.000000000 -0500 +++++ android-openssl-lhash/crypto/lhash/lhash.c 2013-11-05 14:16:49.500027656 -0500 ++@@ -94,6 +94,7 @@ ++ * ++ * 1.0 eay - First version ++ */ +++#include <limits.h> ++ #include <stdio.h> ++ #include <string.h> ++ #include <stdlib.h> ++@@ -107,6 +108,113 @@ ++ #define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ ++ #define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ ++ +++/* Maximum number of nodes to guarantee the load computations don't overflow */ +++#define MAX_LOAD_ITEMS (UINT_MAX / LH_LOAD_MULT) +++ +++/* The field 'iteration_state' is used to hold data to ensure that a hash +++ * table is not resized during an 'insert' or 'delete' operation performed +++ * within a lh_doall/lh_doall_arg call. +++ * +++ * Conceptually, this records two things: +++ * +++ * - A 'depth' count, which is incremented at the start of lh_doall*, +++ * and decremented just before it returns. +++ * +++ * - A 'mutated' boolean flag, which is set in lh_insert() or lh_delete() +++ * when the operation is performed with a non-0 depth. +++ * +++ * The following are helper macros to handle this state in a more explicit +++ * way. +++ */ +++ +++/* Reset the iteration state to its defaults. */ +++#define LH_ITERATION_RESET(lh) do { \ +++ (lh)->iteration_state = 0; \ +++ } while (0) +++ +++/* Returns 1 if the hash table is currently being iterated on, 0 otherwise. */ +++#define LH_ITERATION_IS_ACTIVE(lh) ((lh)->iteration_state >= 2) +++ +++/* Increment iteration depth. This should always be followed by a paired call +++ * to LH_ITERATION_DECREMENT_DEPTH(). */ +++#define LH_ITERATION_INCREMENT_DEPTH(lh) do { \ +++ (lh)->iteration_state += 2; \ +++ } while (0) +++ +++/* Decrement iteration depth. This should always be called after a paired call +++ * to LH_ITERATION_INCREMENT_DEPTH(). */ +++#define LH_ITERATION_DECREMENT_DEPTH(lh) do { \ +++ (lh)->iteration_state -= 2; \ +++ } while (0) +++ +++/* Return 1 if the iteration 'mutated' flag is set, 0 otherwise. */ +++#define LH_ITERATION_IS_MUTATED(lh) (((lh)->iteration_state & 1) != 0) +++ +++/* Set the iteration 'mutated' flag to 1. LH_ITERATION_RESET() to reset it. */ +++#define LH_ITERATION_SET_MUTATED(lh) do { \ +++ (lh)->iteration_state |= 1; \ +++ } while (0) +++ +++/* This macro returns 1 if the hash table should be expanded due to its current +++ * load, or 0 otherwise. The exact comparison to be performed is expressed by +++ * the mathematical expression (where '//' denotes division over real numbers): +++ * +++ * (num_items // num_nodes) >= (up_load // LOAD_MULT) or +++ * (num_items * LOAD_MULT // num_nodes) >= up_load. +++ * +++ * Given that the C language operator '/' implements integer division, i.e: +++ * a // b == (a / b) + epsilon (with 0 <= epsilon < 1, for positive a & b) +++ * +++ * This can be rewritten as: +++ * (num_items * LOAD_MULT / num_nodes) + epsilon >= up_load +++ * (num_items * LOAD_MULT / num_nodes) - up_load >= - epsilon +++ * +++ * Let's call 'A' the left-hand side of the equation above, it is an integer +++ * and: +++ * - If A >= 0, the expression is true for any value of epsilon. +++ * - If A <= -1, the expression is also true for any value of epsilon. +++ * +++ * In other words, this is equivalent to 'A >= 0', or: +++ * (num_items * LOAD_MULT / num_nodes) >= up_load +++ */ +++#define LH_SHOULD_EXPAND(lh) \ +++ ((lh)->num_items < MAX_LOAD_ITEMS && \ +++ (((lh)->num_items*LH_LOAD_MULT/(lh)->num_nodes) >= (lh)->up_load)) +++ +++/* This macro returns 1 if the hash table should be contracted due to its +++ * current load, or 0 otherwise. Abbreviated computations are: +++ * +++ * (num_items // num_nodes) <= (down_load // LOAD_MULT) +++ * (num_items * LOAD_MULT // num_nodes) <= down_load +++ * (num_items * LOAD_MULT / num_nodes) + epsilon <= down_load +++ * (num_items * LOAD_MULT / num_nodes) - down_load <= -epsilon +++ * +++ * Let's call 'B' the left-hand side of the equation above: +++ * - If B <= -1, the expression is true for any value of epsilon. +++ * - If B >= 1, the expression is false for any value of epsilon. +++ * - If B == 0, the expression is true for 'epsilon == 0', and false +++ * otherwise, which is problematic. +++ * +++ * To work around this problem, while keeping the code simple, just change +++ * the initial expression to use a strict inequality, i.e.: +++ * +++ * (num_items // num_nodes) < (down_load // LOAD_MULT) +++ * +++ * Which leads to: +++ * (num_items * LOAD_MULT / num_nodes) - down_load < -epsilon +++ * +++ * Then: +++ * - If 'B <= -1', the expression is true for any value of epsilon. +++ * - If 'B' >= 0, the expression is false for any value of epsilon, +++ * +++ * In other words, this is equivalent to 'B < 0', or: +++ * (num_items * LOAD_MULT / num_nodes) < down_load +++ */ +++#define LH_SHOULD_CONTRACT(lh) \ +++ (((lh)->num_nodes > MIN_NODES) && \ +++ ((lh)->num_items < MAX_LOAD_ITEMS && \ +++ ((lh)->num_items*LH_LOAD_MULT/(lh)->num_nodes) < (lh)->down_load)) +++ ++ static void expand(_LHASH *lh); ++ static void contract(_LHASH *lh); ++ static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); ++@@ -147,6 +255,7 @@ ++ ret->num_hash_comps=0; ++ ++ ret->error=0; +++ LH_ITERATION_RESET(ret); ++ return(ret); ++ err1: ++ OPENSSL_free(ret); ++@@ -183,7 +292,10 @@ ++ void *ret; ++ ++ lh->error=0; ++- if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)) +++ /* Do not expand the array if the table is being iterated on. */ +++ if (LH_ITERATION_IS_ACTIVE(lh)) +++ LH_ITERATION_SET_MUTATED(lh); +++ else if (LH_SHOULD_EXPAND(lh)) ++ expand(lh); ++ ++ rn=getrn(lh,data,&hash); ++@@ -238,8 +350,10 @@ ++ } ++ ++ lh->num_items--; ++- if ((lh->num_nodes > MIN_NODES) && ++- (lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))) +++ /* Do not contract the array if the table is being iterated on. */ +++ if (LH_ITERATION_IS_ACTIVE(lh)) +++ LH_ITERATION_SET_MUTATED(lh); +++ else if (LH_SHOULD_CONTRACT(lh)) ++ contract(lh); ++ ++ return(ret); ++@@ -276,6 +390,7 @@ ++ if (lh == NULL) ++ return; ++ +++ LH_ITERATION_INCREMENT_DEPTH(lh); ++ /* reverse the order so we search from 'top to bottom' ++ * We were having memory leaks otherwise */ ++ for (i=lh->num_nodes-1; i>=0; i--) ++@@ -283,10 +398,7 @@ ++ a=lh->b[i]; ++ while (a != NULL) ++ { ++- /* 28/05/91 - eay - n added so items can be deleted ++- * via lh_doall */ ++- /* 22/05/08 - ben - eh? since a is not passed, ++- * this should not be needed */ +++ /* note that 'a' can be deleted by the callback */ ++ n=a->next; ++ if(use_arg) ++ func_arg(a->data,arg); ++@@ -295,6 +407,19 @@ ++ a=n; ++ } ++ } +++ +++ LH_ITERATION_DECREMENT_DEPTH(lh); +++ if (!LH_ITERATION_IS_ACTIVE(lh) && LH_ITERATION_IS_MUTATED(lh)) +++ { +++ LH_ITERATION_RESET(lh); +++ /* Resize the buckets array if necessary. Each expand() or +++ * contract() call will double/halve the size of the array, +++ * respectively, so call them in a loop. */ +++ while (LH_SHOULD_EXPAND(lh)) +++ expand(lh); +++ while (LH_SHOULD_CONTRACT(lh)) +++ contract(lh); +++ } ++ } ++ ++ void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func) ++diff -burN android-openssl.orig/crypto/lhash/lhash.h android-openssl-lhash/crypto/lhash/lhash.h ++--- android-openssl.orig/crypto/lhash/lhash.h 2013-02-11 10:26:04.000000000 -0500 +++++ android-openssl-lhash/crypto/lhash/lhash.h 2013-11-05 14:16:49.500027656 -0500 ++@@ -163,6 +163,7 @@ ++ unsigned long num_hash_comps; ++ ++ int error; +++ int iteration_state; ++ } _LHASH; /* Do not use _LHASH directly, use LHASH_OF ++ * and friends */ ++ ++diff -burN android-openssl.orig/crypto/objects/o_names.c android-openssl-lhash/crypto/objects/o_names.c ++--- android-openssl.orig/crypto/objects/o_names.c 2013-02-11 10:26:04.000000000 -0500 +++++ android-openssl-lhash/crypto/objects/o_names.c 2013-11-05 14:16:49.500027656 -0500 ++@@ -350,13 +350,9 @@ ++ ++ void OBJ_NAME_cleanup(int type) ++ { ++- unsigned long down_load; ++- ++ if (names_lh == NULL) return; ++ ++ free_type=type; ++- down_load=lh_OBJ_NAME_down_load(names_lh); ++- lh_OBJ_NAME_down_load(names_lh)=0; ++ ++ lh_OBJ_NAME_doall(names_lh,LHASH_DOALL_FN(names_lh_free)); ++ if (type < 0) ++@@ -366,7 +362,5 @@ ++ names_lh=NULL; ++ name_funcs_stack = NULL; ++ } ++- else ++- lh_OBJ_NAME_down_load(names_lh)=down_load; ++ } ++ ++diff -burN android-openssl.orig/crypto/objects/obj_dat.c android-openssl-lhash/crypto/objects/obj_dat.c ++--- android-openssl.orig/crypto/objects/obj_dat.c 2013-02-11 10:26:04.000000000 -0500 +++++ android-openssl-lhash/crypto/objects/obj_dat.c 2013-11-05 14:16:49.500027656 -0500 ++@@ -227,7 +227,6 @@ ++ return ; ++ } ++ if (added == NULL) return; ++- lh_ADDED_OBJ_down_load(added) = 0; ++ lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */ ++ lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */ ++ lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */ ++diff -burN android-openssl.orig/include/openssl/lhash.h android-openssl-lhash/include/openssl/lhash.h ++--- android-openssl.orig/include/openssl/lhash.h 2013-11-05 14:11:20.903223251 -0500 +++++ android-openssl-lhash/include/openssl/lhash.h 2013-11-05 14:16:49.500027656 -0500 ++@@ -163,6 +163,7 @@ ++ unsigned long num_hash_comps; ++ ++ int error; +++ int iteration_state; ++ } _LHASH; /* Do not use _LHASH directly, use LHASH_OF ++ * and friends */ ++ ++diff -burN android-openssl.orig/include/openssl/ssl.h android-openssl-lhash/include/openssl/ssl.h ++--- android-openssl.orig/include/openssl/ssl.h 2013-11-05 14:11:21.013222124 -0500 +++++ android-openssl-lhash/include/openssl/ssl.h 2013-11-05 14:16:49.500027656 -0500 ++@@ -1681,10 +1681,10 @@ ++ SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) ++ ++ /* SSL_enable_tls_channel_id either configures a TLS server to accept TLS client ++- * IDs from clients, or configure a client to send TLS client IDs to server. +++ * IDs from clients, or configures a client to send TLS client IDs to server. ++ * Returns 1 on success. */ ++-#define SSL_enable_tls_channel_id(s) \ ++- SSL_ctrl(s,SSL_CTRL_CHANNEL_ID,0,NULL) +++#define SSL_enable_tls_channel_id(ssl) \ +++ SSL_ctrl(ssl,SSL_CTRL_CHANNEL_ID,0,NULL) ++ /* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to ++ * compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on ++ * success. */ ++diff -burN android-openssl.orig/ssl/ssl.h android-openssl-lhash/ssl/ssl.h ++--- android-openssl.orig/ssl/ssl.h 2013-11-05 14:11:18.363249269 -0500 +++++ android-openssl-lhash/ssl/ssl.h 2013-11-05 14:16:49.510027563 -0500 ++@@ -1681,10 +1681,10 @@ ++ SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) ++ ++ /* SSL_enable_tls_channel_id either configures a TLS server to accept TLS client ++- * IDs from clients, or configure a client to send TLS client IDs to server. +++ * IDs from clients, or configures a client to send TLS client IDs to server. ++ * Returns 1 on success. */ ++-#define SSL_enable_tls_channel_id(s) \ ++- SSL_ctrl(s,SSL_CTRL_CHANNEL_ID,0,NULL) +++#define SSL_enable_tls_channel_id(ssl) \ +++ SSL_ctrl(ssl,SSL_CTRL_CHANNEL_ID,0,NULL) ++ /* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to ++ * compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on ++ * success. */ ++diff -burN android-openssl.orig/ssl/ssl_sess.c android-openssl-lhash/ssl/ssl_sess.c ++--- android-openssl.orig/ssl/ssl_sess.c 2013-11-05 14:11:18.363249269 -0500 +++++ android-openssl-lhash/ssl/ssl_sess.c 2013-11-05 14:16:49.510027563 -0500 ++@@ -999,11 +999,8 @@ ++ if (tp.cache == NULL) return; ++ tp.time=t; ++ CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); ++- i=CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; ++- CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=0; ++ lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), ++ TIMEOUT_PARAM, &tp); ++- CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=i; ++ CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); ++ } ++ |