diff --git a/include/haproxy/buf.h b/include/haproxy/buf.h index fe6f42e93..3f45ee849 100644 --- a/include/haproxy/buf.h +++ b/include/haproxy/buf.h @@ -81,6 +81,7 @@ static inline size_t b_data(const struct buffer *b) /* 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 char *b_tail(const struct buffer *b) 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 size_t b_next_ofs(const struct buffer *b, size_t o) 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 @@ static inline size_t b_dist(const struct buffer *b, const char *from, const char { 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 size_t b_dist(const struct buffer *b, const char *from, const char */ 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_almost_full(const struct buffer *b) */ 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 @@ static inline size_t b_contig_space(const struct buffer *b) { 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 @@ static inline size_t b_getblk(const struct buffer *buf, char *blk, size_t len, s { 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 @@ static inline size_t b_getblk_nc(const struct buffer *buf, const char **blk1, si { 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 @@ static inline struct buffer b_make(char *area, size_t size, size_t head, size_t /* b_sub() : decreases the buffer length by */ 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 */ 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_set_data(struct buffer *b, size_t len) */ 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 @@ static inline void b_slow_realign(struct buffer *b, char *swap, size_t output) 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 @@ static inline void b_slow_realign_ofs(struct buffer *b, char *swap, size_t ofs) 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 @@ static inline void b_move(const struct buffer *b, size_t src, size_t len, ssize_ 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 @@ static inline void b_move(const struct buffer *b, size_t src, size_t len, ssize_ } } 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 @@ static inline int b_rep_blk(struct buffer *b, char *pos, char *end, const char * { 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 @@ static inline void __b_put_varint(struct buffer *b, uint64_t v) 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 @@ static inline void __b_put_varint(struct buffer *b, uint64_t v) /* last byte */ *tail = v; + BUG_ON_HOT(data >= size); data++; b->data = data; } @@ -793,6 +827,8 @@ static inline int b_put_varint(struct buffer *b, uint64_t v) 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 @@ static inline int b_peek_varint(struct buffer *b, size_t ofs, uint64_t *vptr) uint64_t v = 0; int bits = 0; + BUG_ON_HOT(ofs > data); + if (data != 0 && (*head >= 0xF0)) { v = *head; bits += 4;