From f6dbdc14448cbba57d62b51a7762d2d1b8024841 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 17 May 2022 18:52:22 +0200 Subject: [PATCH] BUG/MINOR: ncbuf: fix ncb_is_empty() ncb_is_empty() was plainly incorrect as it directly dereferences the memory to read offset blocks instead of ncb_read_off(). The result is undefined. Also, BUG_ON() statement is wrong when the buffer starts with a data block. In this case, ncb_head() is not the first gap offset but instead just random data. The calculated sum in BUG_ON() statement has thus no meaning and may cause an abort. Adjust this by reorganizing the whole function. Only the first data block size is read. If and only if not nul, the first gap size is then checked. ncb_is_full() has been rewritten to share the same model as ncb_is_empty(). --- src/ncbuf.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/ncbuf.c b/src/ncbuf.c index 2b21a29a7a..91c070aee0 100644 --- a/src/ncbuf.c +++ b/src/ncbuf.c @@ -457,21 +457,35 @@ ncb_sz_t ncb_total_data(const struct ncbuf *buf) /* Returns true if there is no data anywhere in . */ int ncb_is_empty(const struct ncbuf *buf) { + int first_data, first_gap; + 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); + first_data = ncb_read_off(buf, ncb_reserved(buf)); + BUG_ON_HOT(first_data > ncb_size(buf)); + /* Buffer is not empty if first data block is not nul. */ + if (first_data) + return 0; + + /* Head contains the first gap size if first data block is empty. */ + first_gap = ncb_read_off(buf, ncb_head(buf)); + BUG_ON_HOT(first_gap > ncb_size(buf)); + return first_gap == ncb_size(buf); } /* Returns true if no more data can be inserted in . */ int ncb_is_full(const struct ncbuf *buf) { + int first_data; + 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); + /* First data block must cover whole buffer if full. */ + first_data = ncb_read_off(buf, ncb_reserved(buf)); + BUG_ON_HOT(first_data > ncb_size(buf)); + return first_data == ncb_size(buf); } /* Returns the number of bytes of data avaiable in starting at offset -- 2.39.5