DEBUG: buf: add BUG_ON_HOT() to most buffer management functions
A number of tests are now performed in low-level buffer management
functions to verify that we're not appending data to a full buffer
for example, or that the buffer passed in argument is consistent in
that its data don't outweigh its size. The few functions that already
involve memcpy() or memmove() instead got a BUG_ON() that will always
be enabled, since the overhead remains minimalist.
diff --git a/include/haproxy/buf.h b/include/haproxy/buf.h
index fe6f42e..3f45ee8 100644
--- a/include/haproxy/buf.h
+++ b/include/haproxy/buf.h
@@ -81,6 +81,7 @@
/* b_room() : returns the amount of room left in the buffer */
static inline size_t b_room(const struct buffer *b)
{
+ BUG_ON_HOT(b->data > b->size);
return b->size - b_data(b);
}
@@ -210,6 +211,7 @@
static inline size_t b_next_ofs(const struct buffer *b, size_t o)
{
o++;
+ BUG_ON_HOT(o > b->size);
if (o == b->size)
o = 0;
return o;
@@ -218,6 +220,7 @@
static inline char *b_next(const struct buffer *b, const char *p)
{
p++;
+ BUG_ON_HOT(p > b_wrap(b));
if (p == b_wrap(b))
p = b_orig(b);
return (char *)p;
@@ -232,6 +235,7 @@
{
ssize_t dist = to - from;
+ BUG_ON_HOT((dist > 0 && dist > b_size(b)) || (dist < 0 && -dist > b_size(b)));
dist += dist < 0 ? b_size(b) : 0;
return dist;
}
@@ -241,6 +245,7 @@
*/
static inline int b_almost_full(const struct buffer *b)
{
+ BUG_ON_HOT(b->data > b->size);
return b_data(b) >= b_size(b) * 3 / 4;
}
@@ -259,6 +264,7 @@
*/
static inline int b_space_wraps(const struct buffer *b)
{
+ BUG_ON_HOT(b->data > b->size);
if ((ssize_t)__b_head_ofs(b) <= 0)
return 0;
if (__b_tail_ofs(b) >= b_size(b))
@@ -297,6 +303,8 @@
{
size_t left, right;
+ BUG_ON_HOT(b->data > b->size);
+
right = b_head_ofs(b);
left = right + b_data(b);
@@ -319,6 +327,10 @@
{
size_t firstblock;
+ BUG_ON(buf->data > buf->size);
+ BUG_ON(offset > buf->data);
+ BUG_ON(offset + len > buf->data);
+
if (len + offset > b_data(buf))
return 0;
@@ -351,6 +363,10 @@
{
size_t l1;
+ BUG_ON_HOT(buf->data > buf->size);
+ BUG_ON_HOT(ofs > buf->data);
+ BUG_ON_HOT(ofs + max > buf->data);
+
if (!max)
return 0;
@@ -393,18 +409,21 @@
/* b_sub() : decreases the buffer length by <count> */
static inline void b_sub(struct buffer *b, size_t count)
{
+ BUG_ON_HOT(b->data < count);
b->data -= count;
}
/* b_add() : increase the buffer length by <count> */
static inline void b_add(struct buffer *b, size_t count)
{
+ BUG_ON_HOT(b->data + count > b->size);
b->data += count;
}
/* b_set_data() : sets the buffer's length */
static inline void b_set_data(struct buffer *b, size_t len)
{
+ BUG_ON_HOT(len > b->size);
b->data = len;
}
@@ -414,6 +433,7 @@
*/
static inline void b_del(struct buffer *b, size_t del)
{
+ BUG_ON_HOT(b->data < del);
b->data -= del;
b->head += del;
if (b->head >= b->size)
@@ -443,6 +463,8 @@
size_t block1 = output;
size_t block2 = 0;
+ BUG_ON_HOT(b->data > b->size);
+
/* process output data in two steps to cover wrapping */
if (block1 > b_size(b) - b_head_ofs(b)) {
block2 = b_size(b) - b_head_ofs(b);
@@ -480,6 +502,9 @@
size_t block1 = b_data(b);
size_t block2 = 0;
+ BUG_ON_HOT(b->data > b->size);
+ BUG_ON_HOT(ofs > b->size);
+
if (__b_tail_ofs(b) >= b_size(b)) {
block2 = b_tail_ofs(b);
block1 -= block2;
@@ -638,10 +663,13 @@
size_t dst = src + size + shift;
size_t cnt;
+ BUG_ON(len > size);
+
if (dst >= size)
dst -= size;
if (shift < 0) {
+ BUG_ON(-shift >= size);
/* copy from left to right */
for (; (cnt = len); len -= cnt) {
if (cnt > size - src)
@@ -659,6 +687,7 @@
}
}
else if (shift > 0) {
+ BUG_ON(shift >= size);
/* copy from right to left */
for (; (cnt = len); len -= cnt) {
size_t src_end = src + len;
@@ -692,6 +721,8 @@
{
int delta;
+ BUG_ON(pos < b->area || pos >= b->area + b->size);
+
delta = len - (end - pos);
if (__b_tail(b) + delta > b_wrap(b))
@@ -757,6 +788,8 @@
char *wrap = b_wrap(b);
char *tail = b_tail(b);
+ BUG_ON_HOT(data >= size);
+
if (v >= 0xF0) {
/* more than one byte, first write the 4 least significant
* bits, then follow with 7 bits per byte.
@@ -777,6 +810,7 @@
/* last byte */
*tail = v;
+ BUG_ON_HOT(data >= size);
data++;
b->data = data;
}
@@ -793,6 +827,8 @@
char *tail = b_tail(b);
if (data != size && v >= 0xF0) {
+ BUG_ON_HOT(data > size);
+
/* more than one byte, first write the 4 least significant
* bits, then follow with 7 bits per byte.
*/
@@ -877,6 +913,8 @@
uint64_t v = 0;
int bits = 0;
+ BUG_ON_HOT(ofs > data);
+
if (data != 0 && (*head >= 0xF0)) {
v = *head;
bits += 4;