diff --git a/crypto/conf/conf_def.c b/crypto/conf/conf_def.c index 8861b3a5a062dea83a2c86ab963d636ae2f19c1a..a7b11d1598fde4508eb9fa05d9289a96bce0916c 100644 --- a/crypto/conf/conf_def.c +++ b/crypto/conf/conf_def.c @@ -20,6 +20,12 @@ #include #include +/* + * 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); @@ -457,6 +463,8 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) } else if (IS_EOF(conf, *from)) break; else if (*from == '$') { + size_t newsize; + /* try to expand it */ rrp = NULL; s = &(from[1]); @@ -511,8 +519,12 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) 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; } diff --git a/crypto/conf/conf_err.c b/crypto/conf/conf_err.c index b583c057cde16df2bbe0d143cd5103c518bbaa42..0863bc4d3616f232afe627408e0f9df04b4c2134 100644 --- a/crypto/conf/conf_err.c +++ b/crypto/conf/conf_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -60,6 +60,8 @@ static ERR_STRING_DATA CONF_str_reasons[] = { {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} }; diff --git a/doc/man5/config.pod b/doc/man5/config.pod index 24ebafb5332eebb0d1112a5800f2d2b59228c650..ba9a8ab1740f14df0c2abbb3b9727b83124bde2d 100644 --- a/doc/man5/config.pod +++ b/doc/man5/config.pod @@ -44,7 +44,8 @@ or B<${section::name}>. By using the form B<$ENV::name> environment variables can be substituted. It is also possible to assign values to environment variables by using the name B, this will work if the program looks up environment variables using the B library -instead of calling getenv() directly. +instead of calling 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<\> diff --git a/fuzz/corpora/conf/0d7ad6e04c0235cdc590756ceec867a05cff5823 b/fuzz/corpora/conf/0d7ad6e04c0235cdc590756ceec867a05cff5823 new file mode 100644 index 0000000000000000000000000000000000000000..b0ed1912b28a7f3772a0be0d85560337afbaf81b Binary files /dev/null and b/fuzz/corpora/conf/0d7ad6e04c0235cdc590756ceec867a05cff5823 differ diff --git a/include/openssl/conf.h b/include/openssl/conf.h index 462e3c9d397b8f3dc293c799c514c0a35e8c5440..980a51b157f456688df3d0784b9c388f858f80b2 100644 --- a/include/openssl/conf.h +++ b/include/openssl/conf.h @@ -208,6 +208,7 @@ int ERR_load_CONF_strings(void); # 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