From 82e51554f05ba47826f1ee9afdce3add1e8b1457 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 11 Feb 2024 20:41:28 +0000 Subject: [PATCH] Limit recursion when reading name labels from other packet data This fixes an infinite recursion issue where a label can refer to itself and recurse until the stack ie exhausted. --- src/ser.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ser.rs b/src/ser.rs index 0f7da16..8829725 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -25,16 +25,16 @@ pub(crate) fn read_u32(inp: &mut &[u8]) -> Result { Ok(u32::from_be_bytes(bytes)) } -fn read_wire_packet_labels(inp: &mut &[u8], wire_packet: &[u8], name: &mut String) -> Result<(), ()> { +fn do_read_wire_packet_labels(inp: &mut &[u8], wire_packet: &[u8], name: &mut String, recursion_limit: usize) -> Result<(), ()> { loop { let len = read_u8(inp)? as usize; if len == 0 { if name.is_empty() { *name += "."; } break; - } else if len >= 0xc0 { + } else if len >= 0xc0 && recursion_limit > 0 { let offs = ((len & !0xc0) << 8) | read_u8(inp)? as usize; if offs >= wire_packet.len() { return Err(()); } - read_wire_packet_labels(&mut &wire_packet[offs..], wire_packet, name)?; + do_read_wire_packet_labels(&mut &wire_packet[offs..], wire_packet, name, recursion_limit - 1)?; break; } if inp.len() <= len { return Err(()); } @@ -46,6 +46,10 @@ fn read_wire_packet_labels(inp: &mut &[u8], wire_packet: &[u8], name: &mut Strin Ok(()) } +fn read_wire_packet_labels(inp: &mut &[u8], wire_packet: &[u8], name: &mut String) -> Result<(), ()> { + do_read_wire_packet_labels(inp, wire_packet, name, 255) +} + pub(crate) fn read_wire_packet_name(inp: &mut &[u8], wire_packet: &[u8]) -> Result { let mut name = String::with_capacity(1024); read_wire_packet_labels(inp, wire_packet, &mut name)?; -- 2.30.2