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.
This commit is contained in:
Xiang Chen
2026-10-06 10:38:11 +03:00
committed by Georgi Gerganov
parent 14423995ba
commit 6e48a365f3
+10 -1
View File
@@ -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);