Skip to content

Commit

Permalink
More sanity checks on matter_ota data
Browse files Browse the repository at this point in the history
  • Loading branch information
rhilseth committed Jan 7, 2025
1 parent e9d690f commit 1d01a5f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/extractors/matter_ota.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub fn extract_matter_ota(
let total_header_size =
MAGIC_SIZE + TOTAL_SIZE_SIZE + HEADER_SIZE_SIZE + ota_header.header_size;

result.success = true;
result.size = Some(ota_header.total_size);

let payload_start = offset + total_header_size;
Expand Down
43 changes: 32 additions & 11 deletions src/structures/matter_ota.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashMap;

use crate::common::get_cstring;
use crate::common::{get_cstring, is_offset_safe};
use crate::structures::common::{self, StructureError};

/// Struct to store Matter OTA header info
Expand Down Expand Up @@ -46,7 +46,9 @@ pub fn parse_matter_ota_header(ota_data: &[u8]) -> Result<MatterOTAHeader, Struc
// Header starts after the magic, total size and header size fields
let header_start = common::size(&ota_structure);
let header_end = header_start + header_size;
let header_data = &ota_data[header_start..header_end];
let header_data = ota_data
.get(header_start..header_end)
.ok_or(StructureError)?;

let header = parse_tlv_header(header_data)?;

Expand Down Expand Up @@ -111,7 +113,7 @@ fn parse_tlv_element(data: &[u8]) -> Result<(Element, usize), StructureError> {
_ => return Err(StructureError),
};

let field_data = &data[field_offset..];
let field_data = data.get(field_offset..).ok_or(StructureError)?;

match element_type {
0b1_0101 => Ok((
Expand Down Expand Up @@ -147,8 +149,14 @@ fn parse_tlv_element(data: &[u8]) -> Result<(Element, usize), StructureError> {
let structure = &vec![("string_length", field_width_type)];
let result = common::parse(field_data, structure, "little")?;
let string_length = result["string_length"] as usize;
let string_data = &field_data[common::size(structure)..];
let string = get_cstring(&string_data[..string_length]);
let string_data = field_data
.get(common::size(structure)..)
.ok_or(StructureError)?;
// The string buffer isn't null-terminated, so use the explicit length
let string = string_data
.get(..string_length)
.map(get_cstring)
.ok_or(StructureError)?;
Ok((
Element {
tag,
Expand All @@ -162,11 +170,18 @@ fn parse_tlv_element(data: &[u8]) -> Result<(Element, usize), StructureError> {
let structure = &vec![("octet_string_length", field_width_type)];
let result = common::parse(field_data, structure, "little")?;
let octet_string_length = result["octet_string_length"] as usize;
let octet_string_data = &field_data[common::size(structure)..];
let octet_string_data = field_data
.get(common::size(structure)..)
.ok_or(StructureError)?;
Ok((
Element {
tag,
value: Value::OctetString(octet_string_data[..octet_string_length].to_vec()),
value: Value::OctetString(
octet_string_data
.get(..octet_string_length)
.ok_or(StructureError)?
.to_vec(),
),
},
field_offset + common::size(structure) + octet_string_length,
))
Expand All @@ -189,11 +204,17 @@ fn parse_tlv_header(data: &[u8]) -> Result<HashMap<String, Value>, StructureErro
"ImageDigestType",
"ImageDigest",
];
let mut offset = 0;
let mut header = HashMap::new();
while offset < data.len() {
let (element, new_offset) = parse_tlv_element(&data[offset..])?;
offset += new_offset;

let available_data: usize = data.len();

let mut last_tlv_offset: Option<usize> = None;
let mut next_tlv_offset: usize = 0;

while is_offset_safe(available_data, next_tlv_offset, last_tlv_offset) {
let (element, new_offset) = parse_tlv_element(&data[next_tlv_offset..])?;
last_tlv_offset = Some(next_tlv_offset);
next_tlv_offset += new_offset;
if let Some(tag) = element.tag {
let field_name = *fields.get(tag).ok_or(StructureError)?;
header.insert(field_name.to_string(), element.value);
Expand Down

0 comments on commit 1d01a5f

Please sign in to comment.