]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: ncbuf: fix null buffer usage
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 16 May 2022 09:09:29 +0000 (11:09 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 16 May 2022 09:28:41 +0000 (11:28 +0200)
ncbuf public API functions were not ready to deal with a NCBUF_NULL as
parameter. Strenghten these functions by handling it properly.

Most of the functions will consider the buffer as empty and silently
returns. The only exception is ncb_init(buf) which cannot be called
with a NCBUF_NULL. This seems legitimate to consider this as a bug and
not silently failed in this case.

src/ncbuf.c

index 4012adcf45096519f7e880a003567f8e31099b49..bc636fa8427375bc8ff9a5dca3e0f4da909cce47 100644 (file)
@@ -127,6 +127,9 @@ static struct ncb_blk ncb_blk_first(const struct ncbuf *buf)
 {
        struct ncb_blk blk;
 
+       if (ncb_is_null(buf))
+               return NCB_BLK_NULL;
+
        blk.st = ncb_head(buf);
 
        blk.sz_ptr = ncb_reserved(buf);
@@ -198,6 +201,9 @@ static struct ncb_blk ncb_blk_find(const struct ncbuf *buf, ncb_sz_t off)
 {
        struct ncb_blk blk;
 
+       if (ncb_is_null(buf))
+               return NCB_BLK_NULL;
+
        BUG_ON_HOT(off >= ncb_size(buf));
 
        for (blk = ncb_blk_first(buf); off > blk.off + blk.sz;
@@ -373,10 +379,13 @@ int ncb_is_null(const struct ncbuf *buf)
 }
 
 /* Initialize or reset <buf> by clearing all data. Its size is untouched.
- * Buffer is positioned to <head> offset. Use 0 to realign it.
+ * Buffer is positioned to <head> offset. Use 0 to realign it. <buf> must not
+ * be NCBUF_NULL.
  */
 void ncb_init(struct ncbuf *buf, ncb_sz_t head)
 {
+       BUG_ON_HOT(ncb_is_null(buf));
+
        BUG_ON_HOT(head >= buf->size);
        buf->head = head;
 
@@ -425,6 +434,9 @@ char *ncb_wrap(const struct ncbuf *buf)
  */
 ncb_sz_t ncb_size(const struct ncbuf *buf)
 {
+       if (ncb_is_null(buf))
+               return 0;
+
        return buf->size - NCB_RESERVED_SZ;
 }
 
@@ -445,6 +457,9 @@ ncb_sz_t ncb_total_data(const struct ncbuf *buf)
 /* Returns true if there is no data anywhere in <buf>. */
 int ncb_is_empty(const struct ncbuf *buf)
 {
+       if (ncb_is_null(buf))
+               return 1;
+
        BUG_ON_HOT(*ncb_reserved(buf) + *ncb_head(buf) > ncb_size(buf));
        return *ncb_reserved(buf) == 0 && *ncb_head(buf) == ncb_size(buf);
 }
@@ -452,6 +467,9 @@ int ncb_is_empty(const struct ncbuf *buf)
 /* Returns true if no more data can be inserted in <buf>. */
 int ncb_is_full(const struct ncbuf *buf)
 {
+       if (ncb_is_null(buf))
+               return 0;
+
        BUG_ON_HOT(ncb_read_off(buf, ncb_reserved(buf)) > ncb_size(buf));
        return ncb_read_off(buf, ncb_reserved(buf)) == ncb_size(buf);
 }
@@ -465,6 +483,9 @@ ncb_sz_t ncb_data(const struct ncbuf *buf, ncb_sz_t off)
        struct ncb_blk blk = ncb_blk_find(buf, off);
        ncb_sz_t off_blk = ncb_blk_off(blk, off);
 
+       if (ncb_blk_is_null(blk))
+               return 0;
+
        /* if <off> at the frontier between two and <blk> is gap, retrieve the
         * next data block.
         */
@@ -791,13 +812,21 @@ static int ncbuf_test(ncb_sz_t head, int reset, int print_delay)
 
        bufarea = malloc(bufsize);
 
+       fprintf(stderr, "running unit tests\n");
+
+       b = NCBUF_NULL;
+       BUG_ON(!ncb_is_null(&b));
+       NCB_DATA_EQ(&b, 0, 0);
+       NCB_TOTAL_DATA_EQ(&b, 0);
+       BUG_ON(ncb_size(&b) != 0);
+       BUG_ON(!ncb_is_empty(&b));
+       BUG_ON(ncb_is_full(&b));
+
        b.area = bufarea;
        b.size = bufsize;
        b.head = head;
        NCB_INIT(&b);
 
-       fprintf(stderr, "running unit tests\n");
-
        /* insertion test suite */
        NCB_INIT(&b);
        NCB_DATA_EQ(&b, 0, 0); NCB_DATA_EQ(&b, bufsize - NCB_RESERVED_SZ - 1, 0); /* first and last offset */