Skip to content

Commit e76f18e

Browse files
authored
fix(parsing): Handling bad addresses in dsntap (#23071)
* fix(parsing): Handling bad addresses in dsntap * Fix clippy warning
1 parent 968f3c9 commit e76f18e

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Added checks to avoid possible panic while parsing address in `dnstap-parser::DnstapParser::parse_dnstap_message_socket_family`.
2+
3+
authors: wooffie

lib/dnstap-parser/src/parser.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,15 @@ impl DnstapParser {
438438

439439
if let Some(query_address) = dnstap_message.query_address.as_ref() {
440440
let source_address = if socket_family == 1 {
441+
if query_address.len() < 4 {
442+
return Err(Error::from("Cannot parse query_address"));
443+
}
441444
let address_buffer: [u8; 4] = query_address[0..4].try_into()?;
442445
IpAddr::V4(Ipv4Addr::from(address_buffer))
443446
} else {
447+
if query_address.len() < 16 {
448+
return Err(Error::from("Cannot parse query_address"));
449+
}
444450
let address_buffer: [u8; 16] = query_address[0..16].try_into()?;
445451
IpAddr::V6(Ipv6Addr::from(address_buffer))
446452
};
@@ -464,9 +470,15 @@ impl DnstapParser {
464470

465471
if let Some(response_address) = dnstap_message.response_address.as_ref() {
466472
let response_addr = if socket_family == 1 {
473+
if response_address.len() < 4 {
474+
return Err(Error::from("Cannot parse response_address"));
475+
}
467476
let address_buffer: [u8; 4] = response_address[0..4].try_into()?;
468477
IpAddr::V4(Ipv4Addr::from(address_buffer))
469478
} else {
479+
if response_address.len() < 16 {
480+
return Err(Error::from("Cannot parse response_address"));
481+
}
470482
let address_buffer: [u8; 16] = response_address[0..16].try_into()?;
471483
IpAddr::V6(Ipv6Addr::from(address_buffer))
472484
};
@@ -1038,7 +1050,7 @@ mod tests {
10381050
use super::*;
10391051
use chrono::DateTime;
10401052
use dnsmsg_parser::dns_message_parser::DnsParserOptions;
1041-
use std::collections::BTreeMap;
1053+
use std::{collections::BTreeMap, vec};
10421054

10431055
#[test]
10441056
fn test_parse_dnstap_data_with_query_message() {
@@ -1365,6 +1377,46 @@ mod tests {
13651377
)
13661378
}
13671379

1380+
#[test]
1381+
fn test_parse_dnstap_message_socket_family_bad_addr() {
1382+
// while parsing address is optional, but in this function assume otherwise
1383+
fn test_one_input(socket_family: i32, msg: DnstapMessage) -> Result<()> {
1384+
let mut event = LogEvent::default();
1385+
let root = owned_value_path!();
1386+
DnstapParser::parse_dnstap_message_socket_family(&mut event, &root, socket_family, &msg)
1387+
}
1388+
// all bad cases which can panic
1389+
{
1390+
let message = DnstapMessage {
1391+
query_address: Some(vec![]),
1392+
..Default::default()
1393+
};
1394+
assert!(test_one_input(1, message).is_err());
1395+
}
1396+
{
1397+
let message = DnstapMessage {
1398+
query_address: Some(vec![]),
1399+
..Default::default()
1400+
};
1401+
assert!(test_one_input(2, message).is_err());
1402+
}
1403+
1404+
{
1405+
let message = DnstapMessage {
1406+
response_address: Some(vec![]),
1407+
..Default::default()
1408+
};
1409+
assert!(test_one_input(1, message).is_err());
1410+
}
1411+
{
1412+
let message = DnstapMessage {
1413+
response_address: Some(vec![]),
1414+
..Default::default()
1415+
};
1416+
assert!(test_one_input(2, message).is_err());
1417+
}
1418+
}
1419+
13681420
#[test]
13691421
fn test_get_socket_family_name() {
13701422
assert_eq!("INET", to_socket_family_name(1).unwrap());

0 commit comments

Comments
 (0)