summaryrefslogtreecommitdiffstats
path: root/crypto/err
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2019-01-28 17:17:59 +0000
committerMatt Caswell <matt@openssl.org>2019-01-29 11:12:26 +0000
commit9ed9875f0599babfb34bc52c17455765dfc0ac42 (patch)
treef10994705d77904ff0e05ee6991c2d2069cbbc87 /crypto/err
parent6b4f989233c7eb22e40106cc77e3007eb223bf4c (diff)
Don't leak memory from ERR_add_error_vdata()
If the call the ERR_set_error_data() in ERR_add_error_vdata() fails then a mem leak can occur. This commit checks that we successfully added the error data, and if not frees the buffer. Fixes #8085 Reviewed-by: Paul Yang <yang.yang@baishancloud.com> (Merged from https://github.com/openssl/openssl/pull/8105) (cherry picked from commit fa6b1ee1115c1e5e3a8286d833dcbaa2c1ce2b77)
Diffstat (limited to 'crypto/err')
-rw-r--r--crypto/err/err.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/crypto/err/err.c b/crypto/err/err.c
index 7bac6776c8..48d8cfabf2 100644
--- a/crypto/err/err.c
+++ b/crypto/err/err.c
@@ -790,20 +790,31 @@ int ERR_get_next_error_library(void)
return ret;
}
-void ERR_set_error_data(char *data, int flags)
+static int err_set_error_data_int(char *data, int flags)
{
ERR_STATE *es;
int i;
es = ERR_get_state();
if (es == NULL)
- return;
+ return 0;
i = es->top;
err_clear_data(es, i);
es->err_data[i] = data;
es->err_data_flags[i] = flags;
+
+ return 1;
+}
+
+void ERR_set_error_data(char *data, int flags)
+{
+ /*
+ * This function is void so we cannot propagate the error return. Since it
+ * is also in the public API we can't change the return type.
+ */
+ err_set_error_data_int(data, flags);
}
void ERR_add_error_data(int num, ...)
@@ -843,7 +854,8 @@ void ERR_add_error_vdata(int num, va_list args)
}
OPENSSL_strlcat(str, a, (size_t)s + 1);
}
- ERR_set_error_data(str, ERR_TXT_MALLOCED | ERR_TXT_STRING);
+ if (!err_set_error_data_int(str, ERR_TXT_MALLOCED | ERR_TXT_STRING))
+ OPENSSL_free(str);
}
int ERR_set_mark(void)