All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 11/11] reftable/table: fix OOB read on truncated table
  2026-06-24  8:23 [PATCH 00/11] reftable: harden against corrupted tables Patrick Steinhardt
@ 2026-06-24  8:23 ` Patrick Steinhardt
  0 siblings, 0 replies; 2+ messages in thread
From: Patrick Steinhardt @ 2026-06-24  8:23 UTC (permalink / raw)
  To: git; +Cc: oxsignal

When opening a table we compute the size of its data section by
subtracting the footer size from the file size. We do not verify that
the file is actually large enough to contain both the header and the
footer though. With a truncated table the subtraction can thus
underflow, causing us to read the footer out of bounds:

  SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/pks/Development/git/build/t/unit-tests+0x2479a4) in __asan_memcpy
  Shadow bytes around the buggy address:
    0x7ccff6e0de80: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
    0x7ccff6e0df00: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa
    0x7ccff6e0df80: fa fa fd fd fd fd fd fd fd fd fd fd fd fd fd fd
    0x7ccff6e0e000: fd fd fd fd fa fa fa fa fa fa fa fa fd fd fd fd
    0x7ccff6e0e080: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa
  =>0x7ccff6e0e100: fa fa fa fa fa[fa]00 00 00 00 00 00 00 00 00 00
    0x7ccff6e0e180: 00 00 00 00 00 00 00 04 fa fa fa fa fa fa fa fa
    0x7ccff6e0e200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x7ccff6e0e280: 00 00 fa fa fa fa fa fa fa fa fa fa fa fa fa fa
    0x7ccff6e0e300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
    0x7ccff6e0e380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  Shadow byte legend (one shadow byte represents 8 application bytes):
    Addressable:           00
    Partially addressable: 01 02 03 04 05 06 07
    Heap left redzone:       fa
    Freed heap region:       fd
    Stack left redzone:      f1
    Stack mid redzone:       f2
    Stack right redzone:     f3
    Stack after return:      f5
    Stack use after scope:   f8
    Global redzone:          f9
    Global init order:       f6
    Poisoned by user:        f7
    Container overflow:      fc
    Array cookie:            ac
    Intra object redzone:    bb
    ASan internal:           fe
    Left alloca redzone:     ca
    Right alloca redzone:    cb
  ==1500371==ABORTING

Verify that the file is large enough to contain both the header and the
footer before computing the table size.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 reftable/table.c                |  5 +++++
 t/unit-tests/u-reftable-table.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/reftable/table.c b/reftable/table.c
index f4bc86a29d..b4d3f9e211 100644
--- a/reftable/table.c
+++ b/reftable/table.c
@@ -562,6 +562,11 @@ int reftable_table_new(struct reftable_table **out,
 		goto done;
 	}
 
+	if (file_size < header_size(t->version) + footer_size(t->version)) {
+		err = REFTABLE_FORMAT_ERROR;
+		goto done;
+	}
+
 	t->size = file_size - footer_size(t->version);
 	t->source = *source;
 	t->name = reftable_strdup(name);
diff --git a/t/unit-tests/u-reftable-table.c b/t/unit-tests/u-reftable-table.c
index c7dca45e70..28b0ef5258 100644
--- a/t/unit-tests/u-reftable-table.c
+++ b/t/unit-tests/u-reftable-table.c
@@ -262,3 +262,31 @@ void test_reftable_table__seek_invalid_log_offset(void)
 	reftable_table_decref(table);
 	reftable_buf_release(&buf);
 }
+
+void test_reftable_table__new_with_truncated_table(void)
+{
+	struct reftable_ref_record refs[] = {
+		{
+			.refname = (char *) "refs/heads/main",
+			.value_type = REFTABLE_REF_VAL1,
+			.value.val1 = { 42 },
+		},
+	};
+	struct reftable_block_source source = { 0 };
+	struct reftable_table *table;
+	struct reftable_buf buf = REFTABLE_BUF_INIT;
+
+	cl_reftable_write_to_buf(&buf, refs, ARRAY_SIZE(refs), NULL, 0, NULL);
+
+	/*
+	 * Truncate the table so that it is large enough to read the header, but
+	 * too small to also contain the footer.
+	 */
+	buf.len = footer_size(1) - 1;
+	block_source_from_buf(&source, &buf);
+
+	cl_assert_equal_i(reftable_table_new(&table, &source, "name"),
+			  REFTABLE_FORMAT_ERROR);
+
+	reftable_buf_release(&buf);
+}

-- 
2.55.0.rc1.745.g43192e7977.dirty


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH 11/11] reftable/table: fix OOB read on truncated table
       [not found] <20260624181426.NJDNpVd1RE-qJjBVh5jtQg@awo.kakao.com>
@ 2026-06-24  9:46 ` Patrick Steinhardt
  0 siblings, 0 replies; 2+ messages in thread
From: Patrick Steinhardt @ 2026-06-24  9:46 UTC (permalink / raw)
  To: oxsignal; +Cc: git

On Wed, Jun 24, 2026 at 06:14:26PM +0900, oxsignal wrote:
> Hi Patrick,
> 
> Thanks for the patch series, for adding the dedicated reftable fuzzer, and for
> the credit.
> 
> I reviewed the cover letter and the reftable hardening patches. Patch 05/11
> matches the OOB write case I reported:
> the new minimum block-size validation before handling the log block prevents
> the bogus inflated-size underflow from reaching the inflate/copy path.
> 
> The rest of the series also looks like a good cleanup of the corrupted reftable
> parser surface, especially the restart-count/restart-offset and truncated-table
> checks.
> If I find any remaining malformed-table case that is not covered by this
> series, I will follow up with the reproducer.
> 
> Thanks again for handling this so quickly.

Perfect, thanks for the report and reading through the patches!

Patrick

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-06-24  9:46 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20260624181426.NJDNpVd1RE-qJjBVh5jtQg@awo.kakao.com>
2026-06-24  9:46 ` [PATCH 11/11] reftable/table: fix OOB read on truncated table Patrick Steinhardt
2026-06-24  8:23 [PATCH 00/11] reftable: harden against corrupted tables Patrick Steinhardt
2026-06-24  8:23 ` [PATCH 11/11] reftable/table: fix OOB read on truncated table Patrick Steinhardt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.