Skip to content

[Bug] GGML_ASSERT crash in SafeTensors loader on inconsistent tensor metadata #1396

@professor-moody

Description

@professor-moody

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

  1. 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)
  1. 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_ASSERTggml_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 causesrc/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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions