From fa6b1ee1115c1e5e3a8286d833dcbaa2c1ce2b77 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 28 Jan 2019 17:17:59 +0000 Subject: [PATCH] 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 (Merged from https://github.com/openssl/openssl/pull/8105) --- crypto/err/err.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/crypto/err/err.c b/crypto/err/err.c index 4505479772..3aa3daedfc 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -791,20 +791,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, ...) @@ -844,7 +855,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) -- 2.25.1