Skip to content

Out-of-bounds reads in the tmfile (tm2) model loader on malformed input #1449

Description

@professor-moody

I was fuzzing the tmfile (tm2) model loader and hit a large cluster of crashes on malformed .tmfile inputs. They all trace back to one root cause: the tm2 serializer trusts the offsets and counts stored inside the file without checking them against the file size.

The loader resolves almost every table, tensor, string and buffer by doing mem_base + <offset>, or by indexing an offsets array with a count/id read from the file. None of those are bounds-checked, so a crafted file can point any of them outside the mapped buffer. The result is an out-of-bounds read or a wild-pointer segfault during create_graph(..., "tengine", file), before any inference runs.

Confirmed on current tengine-lite HEAD (5ec1c38), x86-64, ASan. A run over the shipped benchmark models produced 266 crashing inputs across about 15 distinct sites in source/serializer/tmfile/tm2_serializer.c, all the same class. A few representative ones:

  • load_graph_tensors: tm_tensor = (TM2_Tensor*)(mem_base + v_tensors->offsets[i]) then tm_tensor->data_type (line ~182) reads a wild pointer when offsets[i] is out of range.
  • buffer resolve: v_buffers->offsets[tm_tensor->buffer_id] (line ~238) indexes the offsets array with buffer_id straight from the file, with no check that buffer_id < v_buffers->v_num.
  • tensor name: strdup_name(mem_base + tm_str->offset_data, tm_str->size) (line ~196) uses both the offset and the length from the file, unchecked.

Minimal example that crashes on load: a tensor whose stored offset points past the end of the file. I have a set of small .tmfile PoCs (one per site, 10-80 KB each) and can attach them or share privately, whichever you prefer.

The fix is to validate every file-derived offset, count and index against the mapped length before dereferencing. I have a patch that adds a small bounds-checked accessor and routes the loads through it, and I'll open a PR against tengine-lite shortly. Happy to adjust it to whatever style you want.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions