From: Thierry FOURNIER Date: Sat, 7 Mar 2015 13:38:50 +0000 (+0100) Subject: BUG/MEDIUM: lua: segfault with buffer_replace2 X-Git-Tag: v1.6-dev1~53 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d2b597aa10abdff5ec3b58bffe87fb99a9423776;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: lua: segfault with buffer_replace2 The function buffer_contig_space() returns the contiguous space avalaible to add data (at the end of the input side) while the function hlua_channel_send_yield() needs to insert data starting at p. Here we introduce a new function bi_space_for_replace() which returns the amount of space that can be inserted at the head of the input side with one of the buffer_replace* functions. This patch proposes a function that returns the space avalaible after buf->p. --- diff --git a/include/common/buffer.h b/include/common/buffer.h index 446bd1a9bb..ca90fbe4be 100644 --- a/include/common/buffer.h +++ b/include/common/buffer.h @@ -233,6 +233,32 @@ static inline int buffer_contig_space(const struct buffer *buf) return right - left; } +/* Returns the amount of byte that can be written starting from

into the + * input buffer at once, including reserved space which may be overwritten. + * This is used by Lua to insert data in the input side just before the other + * data using buffer_replace(). The goal is to transfer these new data in the + * output buffer. + */ +static inline int bi_space_for_replace(const struct buffer *buf) +{ + const char *end; + + /* If the input side data overflows, we cannot insert data contiguously. */ + if (buf->p + buf->i >= buf->data + buf->size) + return 0; + + /* Check the last byte used in the buffer, it may be a byte of the output + * side if the buffer wraps, or its the end of the buffer. + */ + end = buffer_wrap_sub(buf, buf->p - buf->o); + if (end <= buf->p) + end = buf->data + buf->size; + + /* Compute the amount of bytes which can be written. */ + return end - (buf->p + buf->i); +} + + /* Normalizes a pointer which is supposed to be relative to the beginning of a * buffer, so that wrapping is correctly handled. The intent is to use this * when increasing a pointer. Note that the wrapping test is only performed diff --git a/src/hlua.c b/src/hlua.c index 75dd07742b..3f9b90911b 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -2281,7 +2281,7 @@ __LJMP static int hlua_channel_send_yield(lua_State *L, int status, lua_KContext /* The buffer avalaible size may be not contiguous. This test * detects a non contiguous buffer and realign it. */ - if (buffer_contig_space(chn->chn->buf) < max) + if (bi_space_for_replace(chn->chn->buf) < max) buffer_slow_realign(chn->chn->buf); /* Copy input data in the buffer. */