conf has the ability to expand variables in config files. Repeatedly doing
this can lead to an exponential increase in the amount of memory required.
This places a limit on the length of a value that can result from an
expansion.
Credit to OSS-Fuzz for finding this problem.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2894)
(cherry picked from commit
8a585601fea1091022034dd14b961c1ecd5916c3)
# define CONF_R_NO_VALUE 108
# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103
# define CONF_R_UNKNOWN_MODULE_NAME 113
+# define CONF_R_VARIABLE_EXPANSION_TOO_LONG 116
# define CONF_R_VARIABLE_HAS_NO_VALUE 104
#ifdef __cplusplus
#include <openssl/buffer.h>
#include <openssl/err.h>
+/*
+ * The maximum length we can grow a value to after variable expansion. 64k
+ * should be more than enough for all reasonable uses.
+ */
+#define MAX_CONF_VALUE_LENGTH 65536
+
static char *eat_ws(CONF *conf, char *p);
static char *eat_alpha_numeric(CONF *conf, char *p);
static void clear_comments(CONF *conf, char *p);
} else if (IS_EOF(conf, *from))
break;
else if (*from == '$') {
+ size_t newsize;
+
/* try to expand it */
rrp = NULL;
s = &(from[1]);
CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE);
goto err;
}
- if (!BUF_MEM_grow_clean(buf,
- (strlen(p) + buf->length - (e - from)))) {
+ newsize = strlen(p) + buf->length - (e - from);
+ if (newsize > MAX_CONF_VALUE_LENGTH) {
+ CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_EXPANSION_TOO_LONG);
+ goto err;
+ }
+ if (!BUF_MEM_grow_clean(buf, newsize)) {
CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE);
goto err;
}
{ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION),
"unable to create new section"},
{ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME), "unknown module name"},
+ {ERR_REASON(CONF_R_VARIABLE_EXPANSION_TOO_LONG),
+ "variable expansion too long"},
{ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE), "variable has no value"},
{0, NULL}
};
variables can be substituted. It is also possible to assign values to
environment variables by using the name B<ENV::name>, this will work
if the program looks up environment variables using the B<CONF> library
-instead of calling B<getenv()> directly.
+instead of calling B<getenv()> directly. The value string must not exceed 64k in
+length after variable expansion. Otherwise an error will occur.
It is possible to escape certain characters by using any kind of quote
or the B<\> character. By making the last character of a line a B<\>