From c9dbbbdfc87a948418e4b0b2cc2af2ab896db537 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 3 Jun 2020 16:21:04 +0200 Subject: [PATCH] BUG/MEDIUM: http-htx: Duplicate error messages as raw data instead of string When the parsing of a proxy starts, the error messages are duplicated from the default proxy. chunk_dup() function is used to do so. But this function handles the source buffer as a string and try to add a null-terminated byte to the destination buffer after the data copy. Since the 2.1, The error messages are only HTX messages. So the buffer must not be handled as string but as raw data. When the HTX message is not empty, it is not a problem because the underlying buffer is considered as full. null-terminated byte cannot be added and an exact copy is performed. But when the error message is set to /dev/null, the source buffer as a null size. In this case, size of the destination buffer is incremented by one. At the end, the destination buffer has a size of 1. It is an unexpected and undefined state. In http_reply_and_close(), these buffers are erroneously casted to junk HTX messages leading to undefined behaviors, most probably to crashes. This bug is specific to the 2.1. Other versions are not affected. Thus, there is no upstream commit ID for this patch. And it should not be backported. it should fix the issue #648 and probably the issue #658. --- src/cfgparse-listen.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index 5a37d12..8ec49fb 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -262,8 +262,23 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) } /* initialize error relocations */ - for (rc = 0; rc < HTTP_ERR_SIZE; rc++) - chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]); + for (rc = 0; rc < HTTP_ERR_SIZE; rc++) { + struct buffer *dst = &curproxy->errmsg[rc]; + const struct buffer *src = &defproxy.errmsg[rc]; + + if (b_orig(src)) { + dst->head = src->head; + dst->data = src->data; + dst->size = src->size; + dst->area = malloc(src->size); + if (!dst->area) { + dst->head = 0; + dst->data = 0; + dst->size = 0; + continue; + } + } + } if (curproxy->cap & PR_CAP_FE) { curproxy->maxconn = defproxy.maxconn; -- 1.7.10.4