1From b53cd994adaff887ec126de259e37d769ad585cb Mon Sep 17 00:00:00 2001 2From: Kenny Root <kroot@google.com> 3Date: Fri, 8 Feb 2013 11:22:25 -0800 4Subject: [PATCH] Fix failures when eng_dyn scans multiple directories 5 6If DIR_ADD is called with multiple directories, and the target file 7does not exist in the first directory scanned, the DSO object will still 8be considered "loaded" for the next call of DSO_load(...) and cause 9subsequent calls to DSO_load(...) fail with the reason code of "already 10loaded" even though the load failed. 11 12Additionally, with multiple directories used in eng_dyn, another problem 13manifests because the errors pushed onto the error stack will linger even 14if another library is loaded successfully on subsequent calls to 15DSO_load(...) in the directory scanning loop. 16 17Change-Id: I4ddd24f7b39bd88663e1783f30914870a907acfa 18--- 19 crypto/dso/dso_lib.c | 8 ++++++++ 20 crypto/engine/eng_dyn.c | 5 ++++- 21 2 files changed, 12 insertions(+), 1 deletion(-) 22 23diff --git a/crypto/dso/dso_lib.c b/crypto/dso/dso_lib.c 24index 8a15b79..7801529 100644 25--- a/crypto/dso/dso_lib.c 26+++ b/crypto/dso/dso_lib.c 27@@ -237,11 +237,19 @@ DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags) 28 if(ret->meth->dso_load == NULL) 29 { 30 DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED); 31+ /* Make sure we unset the filename on failure, because we use 32+ * this to determine when the DSO has been loaded above. */ 33+ OPENSSL_free(ret->filename); 34+ ret->filename = NULL; 35 goto err; 36 } 37 if(!ret->meth->dso_load(ret)) 38 { 39 DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED); 40+ /* Make sure we unset the filename on failure, because we use 41+ * this to determine when the DSO has been loaded above. */ 42+ OPENSSL_free(ret->filename); 43+ ret->filename = NULL; 44 goto err; 45 } 46 /* Load succeeded */ 47diff --git a/crypto/engine/eng_dyn.c b/crypto/engine/eng_dyn.c 48index 807da7a..8fb8634 100644 49--- a/crypto/engine/eng_dyn.c 50+++ b/crypto/engine/eng_dyn.c 51@@ -408,7 +408,7 @@ static int int_load(dynamic_data_ctx *ctx) 52 int num, loop; 53 /* Unless told not to, try a direct load */ 54 if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso, 55- ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL) 56+ ctx->DYNAMIC_LIBNAME, NULL, 0) != NULL)) 57 return 1; 58 /* If we're not allowed to use 'dirs' or we have none, fail */ 59 if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1) 60@@ -423,6 +423,9 @@ static int int_load(dynamic_data_ctx *ctx) 61 { 62 /* Found what we're looking for */ 63 OPENSSL_free(merge); 64+ /* Previous failed loop iterations, if any, will have resulted in 65+ * errors. Clear them out before returning success. */ 66+ ERR_clear_error(); 67 return 1; 68 } 69 OPENSSL_free(merge); 70-- 711.7.12.3-x20-1 72 73