From 7ab2d0e7505330bd31d3c5b2485dab56a13a095b Mon Sep 17 00:00:00 2001 From: XananasX Date: Tue, 26 May 2026 21:35:33 +0100 Subject: [PATCH 1/2] flexbuffers Rust: fix OOB panic in get_bool() and read_usize() on crafted input --- rust/flexbuffers/src/reader/mod.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/rust/flexbuffers/src/reader/mod.rs b/rust/flexbuffers/src/reader/mod.rs index 5035dea6c6..d44b6b20bb 100644 --- a/rust/flexbuffers/src/reader/mod.rs +++ b/rust/flexbuffers/src/reader/mod.rs @@ -323,7 +323,12 @@ impl Reader { /// Otherwise Returns error. pub fn get_bool(&self) -> Result { self.expect_type(FlexBufferType::Bool)?; - Ok(self.buffer[self.address..self.address + self.width.n_bytes()].iter().any(|&b| b != 0)) + Ok(self + .buffer + .get(self.address..self.address + self.width.n_bytes()) + .ok_or(Error::FlexbufferOutOfBounds)? + .iter() + .any(|&b| b != 0)) } /// Gets the length of the key if this type is a key. @@ -601,9 +606,9 @@ fn f64_from_le_bytes(bytes: [u8; 8]) -> f64 { } fn read_usize(buffer: &[u8], address: usize, width: BitWidth) -> usize { - let cursor = &buffer[address..]; + let cursor = buffer.get(address..).unwrap_or_default(); match width { - BitWidth::W8 => cursor[0] as usize, + BitWidth::W8 => cursor.first().copied().unwrap_or_default() as usize, BitWidth::W16 => cursor .get(0..2) .and_then(|s| s.try_into().ok()) From 6b866e397716f6e52f27e625dcd99abe976a7938 Mon Sep 17 00:00:00 2001 From: XananasX Date: Tue, 26 May 2026 21:35:34 +0100 Subject: [PATCH 2/2] Fix use-after-free in SymbolTable::Add() via reordering emplace_back after duplicate check --- include/flatbuffers/idl.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 9e58d4be95..dc47c7a9c6 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -245,9 +245,11 @@ class SymbolTable { } bool Add(const std::string& name, T* e) { - vec.emplace_back(e); + // Check for duplicate before adding to vec to avoid use-after-free: + // if caller deletes `e` on duplicate, the pointer must not remain in vec. auto it = dict.find(name); if (it != dict.end()) return true; + vec.emplace_back(e); dict[name] = e; return false; }