gguf : harden loader against malformed tensor dims and metadata types (llama/25596)
* gguf : harden loader against malformed tensor dims and metadata types * gguf: address review on malformed-metadata hardening - report the expected vs. actual type when general.alignment is not u32 - use ggml_nelements() > 0 for the zero-element guard and keep the representability checks visually aligned - add test-gguf cases for a wrong-typed alignment key and a zero-dim tensor (both used to crash: assert-abort and SIGFPE respectively) Ran tests/test-gguf: 164/164 pass. Used an AI assistant to help draft these edits; reviewed and verified by me. * cont : less comments Co-authored-by: Georgi Gerganov <ggerganov@gmail.com> --------- Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
This commit is contained in:
parent
92423afd20
commit
b0e3297169
|
|
@ -611,6 +611,13 @@ static struct gguf_context * gguf_init_from_reader(const struct gguf_reader & gr
|
||||||
GGML_ASSERT(int64_t(ctx->kv.size()) == n_kv);
|
GGML_ASSERT(int64_t(ctx->kv.size()) == n_kv);
|
||||||
|
|
||||||
const int alignment_idx = gguf_find_key(ctx, GGUF_KEY_GENERAL_ALIGNMENT);
|
const int alignment_idx = gguf_find_key(ctx, GGUF_KEY_GENERAL_ALIGNMENT);
|
||||||
|
if (alignment_idx != -1 && gguf_get_kv_type(ctx, alignment_idx) != GGUF_TYPE_UINT32) {
|
||||||
|
GGML_LOG_ERROR("%s: key '%s' must be of type %s but is %s\n",
|
||||||
|
__func__, GGUF_KEY_GENERAL_ALIGNMENT, gguf_type_name(GGUF_TYPE_UINT32),
|
||||||
|
gguf_type_name(gguf_get_kv_type(ctx, alignment_idx)));
|
||||||
|
gguf_free(ctx);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
ctx->alignment = alignment_idx == -1 ? GGUF_DEFAULT_ALIGNMENT : gguf_get_val_u32(ctx, alignment_idx);
|
ctx->alignment = alignment_idx == -1 ? GGUF_DEFAULT_ALIGNMENT : gguf_get_val_u32(ctx, alignment_idx);
|
||||||
|
|
||||||
if (ctx->alignment == 0 || (ctx->alignment & (ctx->alignment - 1)) != 0) {
|
if (ctx->alignment == 0 || (ctx->alignment & (ctx->alignment - 1)) != 0) {
|
||||||
|
|
@ -682,9 +689,11 @@ static struct gguf_context * gguf_init_from_reader(const struct gguf_reader & gr
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that the total number of elements is representable
|
// check that the total number of elements is representable
|
||||||
if (ok && ((INT64_MAX/info.t.ne[1] <= info.t.ne[0]) ||
|
// (a zero-element tensor is trivially representable; the guard also avoids a division by zero below)
|
||||||
(INT64_MAX/info.t.ne[2] <= info.t.ne[0]*info.t.ne[1]) ||
|
if (ok && ggml_nelements(&info.t) > 0 &&
|
||||||
(INT64_MAX/info.t.ne[3] <= info.t.ne[0]*info.t.ne[1]*info.t.ne[2]))) {
|
((INT64_MAX/info.t.ne[1] <= info.t.ne[0]) ||
|
||||||
|
(INT64_MAX/info.t.ne[2] <= info.t.ne[0]*info.t.ne[1]) ||
|
||||||
|
(INT64_MAX/info.t.ne[3] <= info.t.ne[0]*info.t.ne[1]*info.t.ne[2]))) {
|
||||||
|
|
||||||
GGML_LOG_ERROR("%s: total number of elements in tensor '%s' with shape "
|
GGML_LOG_ERROR("%s: total number of elements in tensor '%s' with shape "
|
||||||
"(%" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ") is >= %" PRIi64 "\n",
|
"(%" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ") is >= %" PRIi64 "\n",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue