From: Olivier Houchard Date: Tue, 29 Jan 2019 18:10:02 +0000 (+0100) Subject: BUG/MEDIUM: buffer: Make sure b_is_null handles buffers waiting for allocation. X-Git-Tag: v2.0-dev1~102 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=203d735cac55a46326c10ee36bad241cab38ee73;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: buffer: Make sure b_is_null handles buffers waiting for allocation. In b_is_null(), make sure we return 1 if the buffer is waiting for its allocation, as users assume there's memory allocated if b_is_null() returns 0. The indirect impact of not having this was that htxbuf() would not match b_is_null() for a buffer waiting for an allocation, and would thus return the value 1 for the htx pointer, causing various crashes under low memory condition. Note that this patch makes gcc versions 6 and above report two null-deref warnings in proto_htx.c since htx_is_empty() continues to check for a null pointer without knowing that this is protected by the test on b_is_null(). This is addressed by the following patches. This should be backported to 1.9. --- diff --git a/include/common/buf.h b/include/common/buf.h index d495a19cf7..ff03816bc9 100644 --- a/include/common/buf.h +++ b/include/common/buf.h @@ -42,8 +42,8 @@ struct buffer { /* A buffer may be in 3 different states : * - unallocated : size == 0, area == 0 (b_is_null() is true) - * - waiting : size == 0, area != 0 - * - allocated : size > 0, area > 0 + * - waiting : size == 0, area != 0 (b_is_null() is true) + * - allocated : size > 0, area > 0 (b_is_null() is false) */ /* initializers for certain buffer states. It is important that the NULL buffer @@ -62,11 +62,12 @@ struct buffer { /***************************************************************************/ /* b_is_null() : returns true if (and only if) the buffer is not yet allocated - * and thus points to a NULL area. + * and thus has an empty size. Its pointer may then be anything, including NULL + * (unallocated) or an invalid pointer such as (char*)1 (allocation pending). */ static inline int b_is_null(const struct buffer *buf) { - return buf->area == NULL; + return buf->size == 0; } /* b_orig() : returns the pointer to the origin of the storage, which is the