btintel: fix F22 ECDSA firmware blob out-of-bounds slice panic
CRITICAL F22 from NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md §3.5: redbear-btusb/src/btintel.rs:178-187 sliced fw_data[644+128..644+224] and [644+224..644+320] on the ECDSA branch with only 'if fw_data.len() < 644' bounds-check. A 645..963 byte ECDSA firmware blob would panic with 'range start index 772 out of range for slice of length N'. Fix: introduce ECDSA_FULL_LEN = ECDSA_HEADER_LEN + 128 + 96 + 96 (= 964) covering the full ECDSA header (CSS + PKEY + SIG). Update the bounds check to require fw_data.len() >= ECDSA_FULL_LEN. The payload slice now starts at ECDSA_FULL_LEN, making the slice operations guaranteed in-bounds. The error message is updated to print the actual minimum length (964) instead of the misleading 644. Also updates the existing ECDSA_HEADER_LEN = 644 constant reference: the constant is correctly used; the bug was that the check itself was under-specifying the requirement (only the header start, not the header end).
This commit is contained in:
@@ -176,14 +176,23 @@ pub fn firmware_download_commands(fw_data: &[u8]) -> Vec<HciCommand> {
|
||||
commands.extend(secure_send_commands(FRAGMENT_TYPE_PAYLOAD, payload));
|
||||
}
|
||||
CssKeyType::Ecdsa => {
|
||||
if fw_data.len() < 644 {
|
||||
warn!("btintel: ECDSA firmware too short ({} bytes)", fw_data.len());
|
||||
// ECDSA firmware layout: CSS @ 644..772, PKEY @ 772..868,
|
||||
// SIG @ 868..964. Payload starts at 964. Without the full
|
||||
// bounds check, a 645..963 byte blob would panic on the
|
||||
// PKEY/SIG slices.
|
||||
const ECDSA_FULL_LEN: usize = ECDSA_HEADER_LEN + 128 + 96 + 96;
|
||||
if fw_data.len() < ECDSA_FULL_LEN {
|
||||
warn!(
|
||||
"btintel: ECDSA firmware too short ({} bytes, need {})",
|
||||
fw_data.len(),
|
||||
ECDSA_FULL_LEN
|
||||
);
|
||||
return commands;
|
||||
}
|
||||
commands.extend(secure_send_commands(FRAGMENT_TYPE_CSS, &fw_data[644..644 + 128]));
|
||||
commands.extend(secure_send_commands(FRAGMENT_TYPE_PKEY, &fw_data[644 + 128..644 + 224]));
|
||||
commands.extend(secure_send_commands(FRAGMENT_TYPE_SIGNATURE, &fw_data[644 + 224..644 + 320]));
|
||||
let payload = &fw_data[644 + 320..];
|
||||
let payload = &fw_data[ECDSA_FULL_LEN..];
|
||||
commands.extend(secure_send_commands(FRAGMENT_TYPE_PAYLOAD, payload));
|
||||
}
|
||||
CssKeyType::Hybrid => {
|
||||
|
||||
Reference in New Issue
Block a user