Merge "Fix failures when eng_dyn scans multiple directories"
diff --git a/crypto/dso/dso_lib.c b/crypto/dso/dso_lib.c
index 8a15b79..7801529 100644
--- a/crypto/dso/dso_lib.c
+++ b/crypto/dso/dso_lib.c
@@ -237,11 +237,19 @@
if(ret->meth->dso_load == NULL)
{
DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED);
+ /* Make sure we unset the filename on failure, because we use
+ * this to determine when the DSO has been loaded above. */
+ OPENSSL_free(ret->filename);
+ ret->filename = NULL;
goto err;
}
if(!ret->meth->dso_load(ret))
{
DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED);
+ /* Make sure we unset the filename on failure, because we use
+ * this to determine when the DSO has been loaded above. */
+ OPENSSL_free(ret->filename);
+ ret->filename = NULL;
goto err;
}
/* Load succeeded */
diff --git a/crypto/engine/eng_dyn.c b/crypto/engine/eng_dyn.c
index 807da7a..8fb8634 100644
--- a/crypto/engine/eng_dyn.c
+++ b/crypto/engine/eng_dyn.c
@@ -408,7 +408,7 @@
int num, loop;
/* Unless told not to, try a direct load */
if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
- ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
+ ctx->DYNAMIC_LIBNAME, NULL, 0) != NULL))
return 1;
/* If we're not allowed to use 'dirs' or we have none, fail */
if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
@@ -423,6 +423,9 @@
{
/* Found what we're looking for */
OPENSSL_free(merge);
+ /* Previous failed loop iterations, if any, will have resulted in
+ * errors. Clear them out before returning success. */
+ ERR_clear_error();
return 1;
}
OPENSSL_free(merge);
diff --git a/patches/README b/patches/README
index 6e2af83..1fcf68f 100644
--- a/patches/README
+++ b/patches/README
@@ -18,3 +18,7 @@
Implements TLS Channel ID support as both a client and a server.
See http://tools.ietf.org/html/draft-balfanz-tls-channelid-00.
+
+eng_dyn_dirs.patch
+
+Fixes the case of having multiple DIR_ADD commands sent to eng_dyn
diff --git a/patches/eng_dyn_dirs.patch b/patches/eng_dyn_dirs.patch
new file mode 100644
index 0000000..ad137e5
--- /dev/null
+++ b/patches/eng_dyn_dirs.patch
@@ -0,0 +1,72 @@
+From b53cd994adaff887ec126de259e37d769ad585cb Mon Sep 17 00:00:00 2001
+From: Kenny Root <kroot@google.com>
+Date: Fri, 8 Feb 2013 11:22:25 -0800
+Subject: [PATCH] Fix failures when eng_dyn scans multiple directories
+
+If DIR_ADD is called with multiple directories, and the target file
+does not exist in the first directory scanned, the DSO object will still
+be considered "loaded" for the next call of DSO_load(...) and cause
+subsequent calls to DSO_load(...) fail with the reason code of "already
+loaded" even though the load failed.
+
+Additionally, with multiple directories used in eng_dyn, another problem
+manifests because the errors pushed onto the error stack will linger even
+if another library is loaded successfully on subsequent calls to
+DSO_load(...) in the directory scanning loop.
+
+Change-Id: I4ddd24f7b39bd88663e1783f30914870a907acfa
+---
+ crypto/dso/dso_lib.c | 8 ++++++++
+ crypto/engine/eng_dyn.c | 5 ++++-
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/crypto/dso/dso_lib.c b/crypto/dso/dso_lib.c
+index 8a15b79..7801529 100644
+--- a/crypto/dso/dso_lib.c
++++ b/crypto/dso/dso_lib.c
+@@ -237,11 +237,19 @@ DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
+ if(ret->meth->dso_load == NULL)
+ {
+ DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED);
++ /* Make sure we unset the filename on failure, because we use
++ * this to determine when the DSO has been loaded above. */
++ OPENSSL_free(ret->filename);
++ ret->filename = NULL;
+ goto err;
+ }
+ if(!ret->meth->dso_load(ret))
+ {
+ DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED);
++ /* Make sure we unset the filename on failure, because we use
++ * this to determine when the DSO has been loaded above. */
++ OPENSSL_free(ret->filename);
++ ret->filename = NULL;
+ goto err;
+ }
+ /* Load succeeded */
+diff --git a/crypto/engine/eng_dyn.c b/crypto/engine/eng_dyn.c
+index 807da7a..8fb8634 100644
+--- a/crypto/engine/eng_dyn.c
++++ b/crypto/engine/eng_dyn.c
+@@ -408,7 +408,7 @@ static int int_load(dynamic_data_ctx *ctx)
+ int num, loop;
+ /* Unless told not to, try a direct load */
+ if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
+- ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
++ ctx->DYNAMIC_LIBNAME, NULL, 0) != NULL))
+ return 1;
+ /* If we're not allowed to use 'dirs' or we have none, fail */
+ if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
+@@ -423,6 +423,9 @@ static int int_load(dynamic_data_ctx *ctx)
+ {
+ /* Found what we're looking for */
+ OPENSSL_free(merge);
++ /* Previous failed loop iterations, if any, will have resulted in
++ * errors. Clear them out before returning success. */
++ ERR_clear_error();
+ return 1;
+ }
+ OPENSSL_free(merge);
+--
+1.7.12.3-x20-1
+