Skip to content

Commit dea5e86

Browse files
authored
ggml : check tensor name lengths in gguf files (ggml-org#10100)
1 parent 1329c0a commit dea5e86

File tree

2 files changed

+41
-11
lines changed

2 files changed

+41
-11
lines changed

ggml/src/ggml.c

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22102,18 +22102,46 @@ static size_t gguf_type_size(enum gguf_type type) {
2210222102
return GGUF_TYPE_SIZE[type];
2210322103
}
2210422104

22105-
static void gguf_tensor_info_sanitize(struct gguf_tensor_info * info) {
22106-
GGML_ASSERT(info->n_dims <= GGML_MAX_DIMS);
22107-
GGML_ASSERT(0 <= info->type && info->type < GGML_TYPE_COUNT);
22105+
static bool gguf_tensor_info_sanitize(struct gguf_tensor_info * info) {
22106+
if (info->n_dims > GGML_MAX_DIMS) {
22107+
fprintf(stderr, "%s: invalid number of dimensions (%" PRIu32 ")\n", __func__, info->n_dims);
22108+
return false;
22109+
}
22110+
22111+
if (info->type < 0 || info->type >= GGML_TYPE_COUNT) {
22112+
fprintf(stderr, "%s: invalid type (%d)\n", __func__, info->type);
22113+
return false;
22114+
}
22115+
22116+
if (strlen(info->name.data) >= GGML_MAX_NAME) {
22117+
fprintf(stderr, "%s: tensor '%s' name is too long\n", __func__, info->name.data);
22118+
return false;
22119+
}
2210822120

2210922121
for (uint32_t i = 0; i < info->n_dims; ++i) {
22110-
GGML_ASSERT(info->ne[i] > 0);
22122+
if (info->ne[i] <= 0) {
22123+
fprintf(stderr, "%s: invalid number of elements (%" PRIu64 ")\n", __func__, info->ne[i]);
22124+
return false;
22125+
}
2211122126
}
2211222127

2211322128
// prevent overflow for total number of elements
22114-
GGML_ASSERT(INT64_MAX/info->ne[1] > info->ne[0]);
22115-
GGML_ASSERT(INT64_MAX/info->ne[2] > info->ne[0]*info->ne[1]);
22116-
GGML_ASSERT(INT64_MAX/info->ne[3] > info->ne[0]*info->ne[1]*info->ne[2]);
22129+
if (INT64_MAX/info->ne[1] <= info->ne[0]) {
22130+
fprintf(stderr, "%s: invalid number of elements (%" PRIu64 ")\n", __func__, info->ne[1]);
22131+
return false;
22132+
}
22133+
22134+
if (INT64_MAX/info->ne[2] <= info->ne[0]*info->ne[1]) {
22135+
fprintf(stderr, "%s: invalid number of elements (%" PRIu64 ")\n", __func__, info->ne[2]);
22136+
return false;
22137+
}
22138+
22139+
if (INT64_MAX/info->ne[3] <= info->ne[0]*info->ne[1]*info->ne[2]) {
22140+
fprintf(stderr, "%s: invalid number of elements (%" PRIu64 ")\n", __func__, info->ne[3]);
22141+
return false;
22142+
}
22143+
22144+
return true;
2211722145
}
2211822146

2211922147
static bool gguf_fread_el(FILE * file, void * dst, size_t size, size_t * offset) {
@@ -22414,8 +22442,7 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
2241422442
ok = ok && gguf_fread_el (file, &info->type, sizeof(info->type), &offset);
2241522443
ok = ok && gguf_fread_el (file, &info->offset, sizeof(info->offset), &offset);
2241622444

22417-
// TODO: return an error instead of crashing with GGML_ASSERT
22418-
gguf_tensor_info_sanitize(info);
22445+
ok = ok && gguf_tensor_info_sanitize(info);
2241922446

2242022447
// make sure there is no duplicated tensor names
2242122448
for (uint64_t j = 0; j < i && ok; ++j) {

src/llama.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4273,8 +4273,11 @@ struct llama_model_loader {
42734273

42744274
llama_tensor_weight(const llama_file * file, uint16_t idx, const char * name, const struct gguf_context * gguf_ctx, ggml_tensor * tensor) : idx(idx), tensor(tensor) {
42754275
const int tensor_idx = gguf_find_tensor(gguf_ctx, name);
4276-
offs = gguf_get_data_offset(gguf_ctx) + gguf_get_tensor_offset(gguf_ctx, tensor_idx);
4276+
if (tensor_idx < 0) {
4277+
throw std::runtime_error(format("tensor '%s' not found in the model", name));
4278+
}
42774279

4280+
offs = gguf_get_data_offset(gguf_ctx) + gguf_get_tensor_offset(gguf_ctx, tensor_idx);
42784281
if (offs + ggml_nbytes(tensor) < offs || offs + ggml_nbytes(tensor) > file->size) {
42794282
throw std::runtime_error(format("tensor '%s' data is not within the file bounds, model is corrupted or incomplete", name));
42804283
}
@@ -7426,7 +7429,7 @@ static bool llm_load_tensors(
74267429
if (flags & llama_model_loader::TENSOR_NOT_REQUIRED) {
74277430
return nullptr;
74287431
}
7429-
throw std::runtime_error(format("missing tensor %s", tn.str().c_str()));
7432+
throw std::runtime_error(format("missing tensor '%s'", tn.str().c_str()));
74307433
}
74317434

74327435
// some models use the token embedding tensor as the output, but since these are used in different layers and with different ops

0 commit comments

Comments
 (0)