Triaged during the 7.14.2 residual pass and deferred out of 7.14.2 as medium. Still present at release/7.14.2 head.
Evidence
lib/firmware/solana.c:586 (inspect advances past the 0x00 prefix) vs lib/firmware/solana.c:661 (sign uses msg->raw_tx.bytes/.size unshifted), called from lib/firmware/fsm_msg_solana.h:389 and :454
Assessment
Still present. Five commits touched Solana on this branch (the TransferChecked decimals fix, the token-symbol removal, the confirm-screen rework at fsm_msg_solana.h) and none of them addressed the offset. At HEAD solana_inspectTx still does if (raw[0] == 0 && raw_len > 1) { raw++; raw_len--; } at solana.c:586, and every downstream decision — instruction decode, the per-instruction confirm screens, the VERIFIED/OPAQUE/MALFORMED verdict, and solana_signerInTx at fsm_msg_solana.h:300 — runs on the shifted slice, while solana_signTx at solana.c:661 Ed25519-signs the unshifted buffer. Both parsers pin exact consumption (if (pos != raw_len) return MALFORMED), so the divergence is exactly the one leading byte.
So the device literally displays a parse of M and signs 0x00||M. I nevertheless hold this at medium rather than promoting it to the rubric's 'signs materially different bytes' high band, because I traced the artifact and it is inert. Solana verifies signatures over the message bytes, so sig(0x00||M) does not verify against M — the approved transaction is simply unbroadcastable while the device reports success. The reverse direction also dead-ends: for an attacker to obtain a signature over some M_evil this way, M_evil must itself begin with 0x00, which as a legacy message header means num_required_signatures = 0; the Solana runtime rejects that at sanitize (no fee payer, no signature slot), and for a v0 payload the 0x00 lead byte is not a valid version prefix either. I could construct no path where the emitted signature moves funds or forges anything an honest verifier would accept. The residual is a narrow oracle: a signature over 0x00||M, dangerous only to an off-chain verifier that accepts a bare signature without rejecting a 0x00 lead byte.
File it. Worth noting for the owner that the fix is cheap and already written on ORPHAN 4895b81 as solana_message_slice() used by both the inspect and sign paths, plus an ed25519_sign_open self-check; the even smaller option is to reject a leading 0x00 outright and fail closed. If the owner wants a correctness-only backport in this tag it is a low-risk candidate, but it does not meet the bar to block.
Deferred because 7.14.2 is a minimal security release; this did not clear the bar for a late change. Filed so it is not lost.
Triaged during the 7.14.2 residual pass and deferred out of 7.14.2 as
medium. Still present atrelease/7.14.2head.Evidence
lib/firmware/solana.c:586 (inspect advances past the 0x00 prefix) vs lib/firmware/solana.c:661 (sign uses msg->raw_tx.bytes/.size unshifted), called from lib/firmware/fsm_msg_solana.h:389 and :454
Assessment
Still present. Five commits touched Solana on this branch (the TransferChecked decimals fix, the token-symbol removal, the confirm-screen rework at fsm_msg_solana.h) and none of them addressed the offset. At HEAD solana_inspectTx still does
if (raw[0] == 0 && raw_len > 1) { raw++; raw_len--; }at solana.c:586, and every downstream decision — instruction decode, the per-instruction confirm screens, the VERIFIED/OPAQUE/MALFORMED verdict, and solana_signerInTx at fsm_msg_solana.h:300 — runs on the shifted slice, while solana_signTx at solana.c:661 Ed25519-signs the unshifted buffer. Both parsers pin exact consumption (if (pos != raw_len) return MALFORMED), so the divergence is exactly the one leading byte.So the device literally displays a parse of M and signs 0x00||M. I nevertheless hold this at medium rather than promoting it to the rubric's 'signs materially different bytes' high band, because I traced the artifact and it is inert. Solana verifies signatures over the message bytes, so sig(0x00||M) does not verify against M — the approved transaction is simply unbroadcastable while the device reports success. The reverse direction also dead-ends: for an attacker to obtain a signature over some M_evil this way, M_evil must itself begin with 0x00, which as a legacy message header means num_required_signatures = 0; the Solana runtime rejects that at sanitize (no fee payer, no signature slot), and for a v0 payload the 0x00 lead byte is not a valid version prefix either. I could construct no path where the emitted signature moves funds or forges anything an honest verifier would accept. The residual is a narrow oracle: a signature over 0x00||M, dangerous only to an off-chain verifier that accepts a bare signature without rejecting a 0x00 lead byte.
File it. Worth noting for the owner that the fix is cheap and already written on ORPHAN 4895b81 as solana_message_slice() used by both the inspect and sign paths, plus an ed25519_sign_open self-check; the even smaller option is to reject a leading 0x00 outright and fail closed. If the owner wants a correctness-only backport in this tag it is a low-risk candidate, but it does not meet the bar to block.
Deferred because 7.14.2 is a minimal security release; this did not clear the bar for a late change. Filed so it is not lost.