From d5040a8b2b8b7b4377fcec7f79f3d4dc35f628fc Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 24 Jun 2026 10:23:06 +0200 Subject: [PATCH] reftable/basics: fix OOB read on binary search of empty range `binsearch()` performs a binary search over a range of `sz` elements by repeatedly calling the comparison function with indices into that range. When the range is empty though, there is no valid index to call the comparison function with. We still end up executing the comparison function though with an index of 0, which of course will cause an out-of-bounds read. Return early when the range is empty. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- reftable/basics.c | 3 +++ t/unit-tests/u-reftable-basics.c | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/reftable/basics.c b/reftable/basics.c index e969927b61..f0442a46cf 100644 --- a/reftable/basics.c +++ b/reftable/basics.c @@ -152,6 +152,9 @@ size_t binsearch(size_t sz, int (*f)(size_t k, void *args), void *args) size_t lo = 0; size_t hi = sz; + if (!sz) + return 0; + /* Invariants: * * (hi == sz) || f(hi) == true diff --git a/t/unit-tests/u-reftable-basics.c b/t/unit-tests/u-reftable-basics.c index 73566ed0eb..c5d83b6714 100644 --- a/t/unit-tests/u-reftable-basics.c +++ b/t/unit-tests/u-reftable-basics.c @@ -60,6 +60,17 @@ void test_reftable_basics__binsearch(void) } } +static int unreachable_lesseq(size_t i UNUSED, void *args UNUSED) +{ + cl_fail("comparison function called for empty range"); + return 0; +} + +void test_reftable_basics__binsearch_empty(void) +{ + cl_assert_equal_i(binsearch(0, &unreachable_lesseq, NULL), 0); +} + void test_reftable_basics__names_length(void) { const char *a[] = { "a", "b", NULL };