diff --git a/drivers/gpu/nova-core/vbios.rs b/drivers/gpu/nova-core/vbios.rs index 79eb01dabc6f..2ff67273fdff 100644 --- a/drivers/gpu/nova-core/vbios.rs +++ b/drivers/gpu/nova-core/vbios.rs @@ -486,7 +486,7 @@ fn new(data: &[u8]) -> Result { /// BIT Token Entry: Records in the BIT table followed by the BIT header. #[derive(Debug, Clone, Copy)] -#[expect(dead_code)] +#[repr(C)] struct BitToken { /// 00h: Token identifier id: u8, @@ -498,6 +498,9 @@ struct BitToken { data_offset: u16, } +// SAFETY: all bit patterns are valid for `BitToken`. +unsafe impl FromBytes for BitToken {} + // Define the token ID for the Falcon data const BIT_TOKEN_ID_FALCON_DATA: u8 = 0x70; @@ -505,32 +508,28 @@ impl BitToken { /// Find a BIT token entry by BIT ID in a PciAtBiosImage fn from_id(image: &PciAtBiosImage, token_id: u8) -> Result { let header = &image.bit_header; + let entry_size = usize::from(header.token_size); // Offset to the first token entry let tokens_start = image.bit_offset + usize::from(header.header_size); for i in 0..usize::from(header.token_entries) { - let entry_offset = tokens_start + (i * usize::from(header.token_size)); + let entry_offset = i + .checked_mul(entry_size) + .and_then(|offset| tokens_start.checked_add(offset)) + .ok_or(EINVAL)?; + let entry = image + .base + .data + .get(entry_offset..) + .and_then(|data| data.get(..entry_size)) + .ok_or(EINVAL)?; - // Make sure we don't go out of bounds - if entry_offset + usize::from(header.token_size) > image.base.data.len() { - return Err(EINVAL); - } + let (token, _) = BitToken::from_bytes_copy_prefix(entry).ok_or(EINVAL)?; // Check if this token has the requested ID - if image.base.data[entry_offset] == token_id { - return Ok(BitToken { - id: image.base.data[entry_offset], - data_version: image.base.data[entry_offset + 1], - data_size: u16::from_le_bytes([ - image.base.data[entry_offset + 2], - image.base.data[entry_offset + 3], - ]), - data_offset: u16::from_le_bytes([ - image.base.data[entry_offset + 4], - image.base.data[entry_offset + 5], - ]), - }); + if token.id == token_id { + return Ok(token); } }