Skip to content

split-mixtral: grow tensors[] array instead of assert() (fixes heap OOB write)#32

Open
gigioneggiando wants to merge 1 commit into
antirez:mainfrom
gigioneggiando:fix-split-mixtral-tensor-array-overflow
Open

split-mixtral: grow tensors[] array instead of assert() (fixes heap OOB write)#32
gigioneggiando wants to merge 1 commit into
antirez:mainfrom
gigioneggiando:fix-split-mixtral-tensor-array-overflow

Conversation

@gigioneggiando

Copy link
Copy Markdown

Problem

The split-mixtral subcommand allocates a fixed-size array:

uint32_t max_tensors = 2048;
struct tensor_to_copy *tensors = malloc(sizeof(struct tensor_to_copy)*max_tensors);
...
while (gguf_get_tensor(mixtral,&tensor_info)) {
    assert(num_tensors < max_tensors);   // only guard
    ...
    tensors[num_tensors].dest_name = sdsnew(tn);   // gguf-tools.c:295
    ...
    num_tensors++;
}

The only bound on tensors[num_tensors] is assert(), which is compiled out under -DNDEBUG (the usual release build). A source model that declares more than 2048 tensors then overflows the array with model-file-controlled data, a heap out-of-bounds write. The tensor count is read straight from the input .gguf, so this is attacker-controlled for any untrusted model.

Reproduction

A crafted 2049-tensor .gguf fed to the real split-mixtral binary, release build (-DNDEBUG) under AddressSanitizer:

==ERROR: AddressSanitizer: heap-buffer-overflow
WRITE of size 8 ...
    #0 gguf_tools_split_mixtral gguf-tools.c:295
SUMMARY: AddressSanitizer: heap-buffer-overflow gguf-tools.c:295 in gguf_tools_split_mixtral

Fix

Replace the assert with a real runtime check that doubles the array via realloc when it fills, matching the existing malloc-failure handling (perror + exit). This closes the overflow and, as a bonus, lets a legitimate model with more than 2048 tensors be processed instead of aborting.

Verified with the same ASan build after the patch: all 2049 tensors are processed and written, no out-of-bounds write.

Part of a small local audit of the GGUF read path against untrusted model files. No CVE or public advisory from my side.

The split-mixtral subcommand allocates a fixed tensors[] array of
max_tensors (2048) entries and guards the per-tensor write only with
assert(num_tensors < max_tensors). assert() is compiled out under
-DNDEBUG (the usual release build), so a source model declaring more
than 2048 tensors overflows the array with model-file-controlled data:
a heap out-of-bounds write.

Replace the assert with a real runtime check that doubles the array via
realloc when it fills up, matching the existing malloc-failure handling
(perror + exit). This both closes the overflow and lets a legitimate
model with more than 2048 tensors be processed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant