CVE-2026-78147: a pointer that arrived over the wire¶
The ggml RPC server reconstructs a tensor from a client request. Two fields survive that reconstruction unchecked: the selector that says which operation the tensor represents, and the opaque parameter block that belongs to it. Nothing constrains the selector to the set of operations that exist, and nothing constrains the parameter block's contents.
For most operations the parameter block is inert data. For a small number of them it is read back as a callback pointer and called. A client that picks one of those operations therefore chooses the address of an indirect branch, and chooses one of the values the callee is handed.
What the evidence supports¶
- The primitive is a controlled indirect call. At the branch, the target register holds a value the client supplied and an argument register holds a second value the client supplied.
- The control artifact and the crafted artifact differ by a single byte. Control runs survive, crafted runs fault, three runs each.
- The capture was reproduced on two independently built binaries of the same upstream commit, on different hosts with different compilers. The two compilers emit different instructions for the same source line, so the primitive belongs to the code rather than to one build.
- It was reproduced across an isolated network boundary against a non-loopback address, with address-space randomisation enabled.
What the public standalone evidence does not support¶
The observations on this page are the standalone CVE-2026-78147 witness. The limits below apply to those runs.
- No completed shell or arbitrary code execution was demonstrated in these runs. A branch target that is taken is not the same thing as a payload that runs.
- No information disclosure was demonstrated in these runs. No memory was read back to the client.
- No integrity impact was demonstrated in these runs. No server state was modified.
- The demonstrated consequence beyond the branch itself was process termination.
Where the classifications differ¶
Our record and the assigner's record do not agree, and both are kept rather than reconciled into one.
The witnessed primitive is a pointer taken from an untrusted source and used without validation. The assigner classified the entry as deserialization of untrusted data with improper input validation, and recorded confidentiality and integrity impact alongside availability. The standalone witness described here does not establish the confidentiality or integrity halves, and the remedy that closes this defect is a validation check rather than a change to how the request is decoded.
The canonical ledger keeps the demonstrated primitive, our submitted classification and the assigner's assessment in separate fields, so neither reading is silently overwritten by the other.
Remedy shape¶
Reject an operation selector outside its enumeration, and reject the operations that carry pointers, before the tensor is used.
Sources: the canonical CVE ledger, the public upstream issue, and the assigner's record.