Commit 8a585601 authored by Matt Caswell's avatar Matt Caswell
Browse files

Fix out-of-memory condition in conf



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: default avatarRich Salz <rsalz@openssl.org>
Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2894)
parent a3b0d466
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -20,6 +20,12 @@
#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);
@@ -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;
            }
+3 −1
Original line number Diff line number Diff line
/*
 * 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}
};
+2 −1
Original line number Diff line number Diff line
@@ -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<ENV::name>, this will work
if the program looks up environment variables using the B<CONF> 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<\>
+0 −0

File added.

Preview suppressed by a .gitattributes entry or the file's encoding is unsupported.

+1 −0
Original line number Diff line number Diff line
@@ -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