From 56bde14e0db1a1df41386bc94aeead58c3e6d653 Mon Sep 17 00:00:00 2001 From: SebastiaanYN Date: Thu, 23 Jul 2026 16:19:57 +0200 Subject: [PATCH] Fix overflow in `Message::canonical_name` when ancount is u16::MAX Use `saturating_add(1)` for the CNAME loop bound. The +1 exists only for loop detection (one more iteration than answer records), so capping at u16::MAX is harmless. --- src/base/message.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/base/message.rs b/src/base/message.rs index 00817bd38..b22cd27d8 100644 --- a/src/base/message.rs +++ b/src/base/message.rs @@ -524,7 +524,7 @@ impl Message { Err(_) => return None, }; - for _ in 0..self.header_counts().ancount() + 1 { + for _ in 0..self.header_counts().ancount().saturating_add(1) { let mut found = false; for record in answer.clone() { let record = match record { @@ -1444,6 +1444,19 @@ mod test { assert!(msg.as_message().canonical_name().is_none()); } + #[test] + #[cfg(feature = "alloc")] + fn canonical_name_max_ancount() { + // Must not panic with arithmetic overflow. + let mut msg = MessageBuilder::new_vec().question(); + msg.push((Name::root_vec(), Rtype::A)).unwrap(); + let mut buf = msg.finish(); + HeaderCounts::for_message_slice_mut(buf.as_mut()) + .set_ancount(u16::MAX); + let msg = Message::from_octets(buf.as_slice()).unwrap(); + let _ = msg.canonical_name(); + } + #[test] #[cfg(feature = "alloc")] fn message_iterator() {