Git commit
$git rev-parse HEAD
8afbeb6
Operating System & Version
Fedora 43
GGML backends
CPU, HIP
Command-line arguments used
sd -m crash-029.safetensors --mode txt2img
Steps to reproduce
Steps to reproduce
- Create a minimal 91-byte SafeTensors file with mismatched shape/dtype vs data_offsets:
import struct, json
header = json.dumps({
"weight": {"dtype": "F64", "shape": [4], "data_offsets": [0, 16]}
})
buf = struct.pack('<Q', len(header)) + header.encode() + b'\x00' * 16
with open('crash-029.safetensors', 'wb') as f:
f.write(buf)
- Run:
sd -m crash-029.safetensors --mode txt2img
What you expected to happen
What you expected to happen
The process should reject the file with an error message when tensor metadata is internally inconsistent (shape/dtype imply a different byte count than data_offsets).
What actually happened
What actually happened
The process crashes with GGML_ASSERT → ggml_abort() → abort().
init_from_safetensors_file() (src/model.cpp:588-595) uses GGML_ASSERT to check tensor size consistency. When dtype is "F64" with shape [4], the expected size is 32 bytes (4 × 8), but data_offsets says 16. The assertion tensor_storage.nbytes() * 2 == tensor_data_size fails → unconditional abort (not affected by -DNDEBUG).
Logs / error messages / stack trace
Logs / error messages / stack trace
GGML_ASSERT(tensor_storage.nbytes() * 2 == tensor_data_size) failed
at src/model.cpp:589 in init_from_safetensors_file()
Aborted (core dumped)
Additional context / environment details
Additional context / environment details
Root cause — src/model.cpp:588-595:
} else if (dtype == "F64") {
tensor_storage.is_f64 = true;
GGML_ASSERT(tensor_storage.nbytes() * 2 == tensor_data_size); // line 589 — crashes here
} else {
GGML_ASSERT(tensor_storage.nbytes() == tensor_data_size); // line 595
}
Suggested fix — replace GGML_ASSERT with error returns:
} else if (dtype == "F64") {
tensor_storage.is_f64 = true;
- GGML_ASSERT(tensor_storage.nbytes() * 2 == tensor_data_size);
+ if (tensor_storage.nbytes() * 2 != tensor_data_size) {
+ LOG_ERROR("SafeTensors: size mismatch for tensor '%s' (F64)\n", name.c_str());
+ return false;
+ }
} else {
- GGML_ASSERT(tensor_storage.nbytes() == tensor_data_size);
+ if (tensor_storage.nbytes() != tensor_data_size) {
+ LOG_ERROR("SafeTensors: size mismatch for tensor '%s'\n", name.c_str());
+ return false;
+ }
}
- x86_64, clang 19
- Reproduces on both sanitizer and release builds
- Found via fuzz testing with crafted SafeTensors files
Git commit
Operating System & Version
Fedora 43
GGML backends
CPU, HIP
Command-line arguments used
sd -m crash-029.safetensors --mode txt2img
Steps to reproduce
Steps to reproduce
sd -m crash-029.safetensors --mode txt2imgWhat you expected to happen
What you expected to happen
The process should reject the file with an error message when tensor metadata is internally inconsistent (shape/dtype imply a different byte count than data_offsets).
What actually happened
What actually happened
The process crashes with
GGML_ASSERT→ggml_abort()→abort().init_from_safetensors_file()(src/model.cpp:588-595) usesGGML_ASSERTto check tensor size consistency. When dtype is "F64" with shape [4], the expected size is 32 bytes (4 × 8), butdata_offsetssays 16. The assertiontensor_storage.nbytes() * 2 == tensor_data_sizefails → unconditional abort (not affected by-DNDEBUG).Logs / error messages / stack trace
Logs / error messages / stack trace
Additional context / environment details
Additional context / environment details
Root cause —
src/model.cpp:588-595:Suggested fix — replace
GGML_ASSERTwith error returns:} else if (dtype == "F64") { tensor_storage.is_f64 = true; - GGML_ASSERT(tensor_storage.nbytes() * 2 == tensor_data_size); + if (tensor_storage.nbytes() * 2 != tensor_data_size) { + LOG_ERROR("SafeTensors: size mismatch for tensor '%s' (F64)\n", name.c_str()); + return false; + } } else { - GGML_ASSERT(tensor_storage.nbytes() == tensor_data_size); + if (tensor_storage.nbytes() != tensor_data_size) { + LOG_ERROR("SafeTensors: size mismatch for tensor '%s'\n", name.c_str()); + return false; + } }