Skip to content

Fix unsigned underflow in buffer_check_limits() bounds check#273

Open
kodareef5 wants to merge 1 commit intodovecot:mainfrom
kodareef5:fix-buffer-check-underflow
Open

Fix unsigned underflow in buffer_check_limits() bounds check#273
kodareef5 wants to merge 1 commit intodovecot:mainfrom
kodareef5:fix-buffer-check-underflow

Conversation

@kodareef5
Copy link
Copy Markdown

When pos > buf->max_size, the unsigned subtraction buf->max_size - pos wraps to a large value instead of triggering the panic. This causes the bounds check to pass when it should fail.

Add pos > buf->max_size before the subtraction so the check correctly catches out-of-range positions.

@cmouse
Copy link
Copy Markdown
Contributor

cmouse commented Mar 23, 2026

Thank you for your pull request, we'll take a look.

size_t new_size;

if (unlikely(buf->max_size - pos < data_size))
if (unlikely(pos > buf->max_size || buf->max_size - pos < data_size))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good fix, although commit message could say that this doesn't affect buffers created with buffer_create_dynamic(), which are most buffers, since then max_size == SIZE_MAX. Also commit title needs a lib: prefix.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Added lib: prefix and noted the buffer_create_dynamic() / SIZE_MAX scope in the commit message.

src/lib/buffer.c Outdated
it's going to be filled with the newly appended data. */
#ifndef DEBUG_FAST
if (buf->writable_size - buf->used < data_size)
if (buf->used > buf->writable_size ||
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unnecessary check, because used cannot be larger than writable_size. I guess an assert could be added here to be sure.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Replaced the conditional guard with i_assert(buf->used <= buf->writable_size) instead.

When pos > buf->max_size, the unsigned subtraction buf->max_size - pos
wraps to a large value instead of triggering the panic. Add an explicit
check before the subtraction so out-of-range positions are caught.

This does not affect buffers created with buffer_create_dynamic(), which
use max_size == SIZE_MAX.

Also add an i_assert in buffer_check_append_limits() to verify the
invariant that used <= writable_size.
@kodareef5 kodareef5 force-pushed the fix-buffer-check-underflow branch from 4737b87 to 47e2e0b Compare March 24, 2026 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants