Multiple panics in `DnsQuery::get_qname_parsed` on malformed DNS data
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 2.6k
- Forks
- 329
- PR merge metrics
- No merged PRs in 30d
Description
Description:
Hi, I encountered multiple panics when invoking the DnsQuery::get_qname_parsed method with malformed DNS packet data. The function has two distinct crash paths due to missing input validation, both reachable through normal DnsPacket parsing. As a network packet parsing library, these functions should handle arbitrary/malformed input gracefully instead of panicking. The related source code is shown below:
https://github.com/libpnet/libpnet/blob/49428d3da6d60b506261269a329ca8e6be79b241/pnet_packet/src/dns.rs#L431-L453
Crash 1: Label length exceeds available data — slice out of bounds (line 445)
When a label length byte claims more bytes than are available, the slice name[offset + 1..offset + 1 + label_len] exceeds the vector length.
This panic is reachable through normal DnsPacket parsing: a malformed DNS packet where the query section contains e.g. [0x05, 0x41, 0x00, ...] would produce a qname of [0x05, 0x41, 0x00] (label_len=5, but only 1 data byte follows before the null terminator). Calling get_qname_parsed() on this parsed query will panic.
Panic: range end index 133 out of range for slice of length 5
Location: pnet_packet/src/dns.rs:445:37
stack backtrace:
0: __rustc::rust_begin_unwind
1: core::panicking::panic_fmt
2: core::slice::index::slice_index_fail::do_panic::runtime
3: core::slice::index::slice_index_fail
4: <core::ops::range::Range<usize> as core::slice::index::SliceIndex<[T]>>::index
5: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
6: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
7: pnet_packet::dns::DnsQuery::get_qname_parsed
at pnet_packet/src/dns.rs:445:37
Crash 2: Non-UTF-8 bytes — unwrap on None (line 447)
DNS labels are binary data (RFC 1035 specifies octets, not UTF-8). When qname bytes contain non-UTF-8 data, str::from_utf8 returns Err, .ok() converts to None, and .unwrap() panics.
This panic is also reachable through normal DnsPacket parsing: a DNS packet with a qname like [0x01, 0xFF, 0x00] (a 1-byte label containing 0xFF, which is not valid UTF-8) will trigger it when get_qname_parsed() is called.
Panic: called `Option::unwrap()` on a `None` value
Location: pnet_packet/src/dns.rs:447:22
stack backtrace:
0: __rustc::rust_begin_unwind
1: core::panicking::panic_fmt
2: core::panicking::panic
3: core::option::unwrap_failed
4: core::option::Option<T>::unwrap
5: pnet_packet::dns::DnsQuery::get_qname_parsed
at pnet_packet/src/dns.rs:447:22
Both crashes can be triggered through normal DnsPacket parsing of a malformed DNS packet followed by calling get_qname_parsed(). For programs that use this method to process DNS packets from untrusted sources, a crafted packet can crash the process (denial-of-service). In safe Rust, panics do not cause memory corruption — only a process abort or thread unwind.
How to reproduce it:
The PoC program is:
use pnet_packet::dns::{DnsQuery, DnsType, DnsClass};
fn main() {
// Crash 1: label_len exceeds available data
let query = DnsQuery {
qname: vec![0x80, 0x01, 0x02, 0x03, 0x04],
qtype: DnsType(0),
qclass: DnsClass(0),
payload: vec![],
};
let _ = query.get_qname_parsed(); // panics: range end index out of range
// Crash 2: non-UTF-8 bytes
let query = DnsQuery {
qname: vec![0x02, 0xFF, 0xFE, 0x00],
qtype: DnsType(0),
qclass: DnsClass(0),
payload: vec![],
};
let _ = query.get_qname_parsed(); // panics: unwrap on None
}
Environment:
- Discovered via fuzz testing
- OS / distro: Ubuntu 24.04
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in pnet_packet/src/dns.rs at DnsQuery::get_qname_parsed, around lines 431-453, and reproduce both malformed-input cases from the issue. Add focused coverage for truncated labels and non-UTF-8 label bytes, then verify the method no longer panics when those inputs are parsed and queried.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100