From 6e48a365f37822e88671dd74cadfc0927ed2f1d8 Mon Sep 17 00:00:00 2001 From: Xiang Chen <46052474+x14ngch3n@users.noreply.github.com> Date: Wed, 30 Sep 2026 04:46:20 +0800 Subject: [PATCH] gguf : reject tensor size that wraps after padding (llama/26979) GGML_PAD(nbytes, alignment) wraps to 0 when nbytes is within (alignment - 1) of SIZE_MAX, which silently bypassed the size overflow guard in gguf_init_from_reader. Reject the tensor before padding when nbytes + (alignment - 1) would overflow. Adds a test-gguf handcrafted case (F32, ne = [4, 2^30-1, 2^30+1, 1]) whose ggml_nbytes = 2^64 - 16 lands in the wrap window. Fails on master, passes with the guard. --- ggml/src/gguf.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ggml/src/gguf.cpp b/ggml/src/gguf.cpp index 5c26f751f..8e8c2f0e6 100644 --- a/ggml/src/gguf.cpp +++ b/ggml/src/gguf.cpp @@ -792,7 +792,16 @@ static struct gguf_context * gguf_init_from_reader(const struct gguf_reader & gr gguf_free(ctx); return nullptr; } - size_t padded_size = GGML_PAD(ggml_nbytes(&ti.t), ctx->alignment); + const size_t nbytes = ggml_nbytes(&ti.t); + // GGML_PAD adds (alignment - 1) to nbytes. when nbytes is near + // SIZE_MAX this wraps to 0 and makes the check below dead. + if (nbytes > SIZE_MAX - (ctx->alignment - 1)) { + GGML_LOG_ERROR("%s: tensor '%s' size %zu overflows after padding (alignment %zu)\n", + __func__, ti.t.name, nbytes, ctx->alignment); + gguf_free(ctx); + return nullptr; + } + const size_t padded_size = GGML_PAD(nbytes, ctx->alignment); if (SIZE_MAX - ctx->size < padded_size) { GGML_LOG_ERROR("%s: tensor '%s' size overflow, cannot accumulate size %zu + %zu\n", __func__, ti.t.name, ctx->size, padded_size);