diff --git a/Changelog.md b/Changelog.md index 6ff26067..3cfdf057 100644 --- a/Changelog.md +++ b/Changelog.md @@ -13,10 +13,13 @@ Improvements Bug fixes -* Detect when an attempt is made to create an dnssec::sign::records::Rrset - with records that have different TTLs. Unfortuantely error handling is - poor so the code currently panics. At least this prevents bad signatures - but the error handling needs to be fixed later. ([#660]) +* Added a length check when parsing open-ended record types like + `Dnskey<_>` which are supposed to never be too large. ([#664]) +* Detect when an attempt is made to create a + `dnssec::sign::records::Rrset` with records that have different TTLs. + Unfortuantely error handling is poor so the code currently panics. At + least this prevents bad signatures but the error handling needs to be + fixed later. ([#660]) Unstable features @@ -28,6 +31,7 @@ Other changes [#641]: https://github.com/NLnetLabs/domain/pull/641 [#659]: https://github.com/NLnetLabs/domain/pull/659 [#660]: https://github.com/NLnetLabs/domain/pull/660 +[#664]: https://github.com/NLnetLabs/domain/pull/664 [@soywod]: https://github.com/soywod diff --git a/src/base/rdata.rs b/src/base/rdata.rs index 0a0fd29a..e3fd301d 100644 --- a/src/base/rdata.rs +++ b/src/base/rdata.rs @@ -529,6 +529,12 @@ impl LongRecordData { } } +impl From for ParseError { + fn from(src: LongRecordData) -> ParseError { + ParseError::form_error(src.as_str()) + } +} + impl fmt::Display for LongRecordData { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.as_str()) diff --git a/src/rdata/cds.rs b/src/rdata/cds.rs index 98908a29..dd488e00 100644 --- a/src/rdata/cds.rs +++ b/src/rdata/cds.rs @@ -137,6 +137,7 @@ impl Cdnskey { Some(len) => len, None => return Err(ParseError::ShortInput), }; + LongRecordData::check_len(len)?; Ok(unsafe { Self::new_unchecked( u16::parse(parser)?, @@ -470,6 +471,7 @@ impl Cds { Some(len) => len, None => return Err(ParseError::ShortInput), }; + LongRecordData::check_len(len)?; Ok(unsafe { Self::new_unchecked( u16::parse(parser)?, diff --git a/src/rdata/dnssec.rs b/src/rdata/dnssec.rs index 6a58ae29..2f3da3b1 100644 --- a/src/rdata/dnssec.rs +++ b/src/rdata/dnssec.rs @@ -245,6 +245,7 @@ impl Dnskey { Some(len) => len, None => return Err(ParseError::ShortInput), }; + LongRecordData::check_len(len)?; Ok(unsafe { Self::new_unchecked( u16::parse(parser)?, @@ -1042,6 +1043,7 @@ impl Rrsig> { pub fn parse<'a, Src: Octets = Octs> + ?Sized + 'a>( parser: &mut Parser<'a, Src>, ) -> Result { + LongRecordData::check_len(parser.remaining())?; let type_covered = Rtype::parse(parser)?; let algorithm = SecurityAlgorithm::parse(parser)?; let labels = u8::parse(parser)?; @@ -1826,6 +1828,7 @@ impl Ds { Some(len) => len, None => return Err(ParseError::ShortInput), }; + LongRecordData::check_len(parser.remaining())?; Ok(unsafe { Self::new_unchecked( u16::parse(parser)?, diff --git a/src/rdata/rfc1035/null.rs b/src/rdata/rfc1035/null.rs index c2897c60..11eb8408 100644 --- a/src/rdata/rfc1035/null.rs +++ b/src/rdata/rfc1035/null.rs @@ -137,6 +137,7 @@ impl Null { parser: &mut Parser<'a, Src>, ) -> Result { let len = parser.remaining(); + LongRecordData::check_len(len)?; parser .parse_octets(len) .map(|res| unsafe { Self::from_octets_unchecked(res) }) diff --git a/src/rdata/rfc1035/txt.rs b/src/rdata/rfc1035/txt.rs index 452c804c..36479588 100644 --- a/src/rdata/rfc1035/txt.rs +++ b/src/rdata/rfc1035/txt.rs @@ -185,6 +185,7 @@ impl Txt { Octs: AsRef<[u8]>, { let len = parser.remaining(); + LongRecordData::check_len(len)?; let text = parser.parse_octets(len)?; let mut tmp = Parser::from_ref(text.as_ref()); while tmp.remaining() != 0 { diff --git a/src/rdata/svcb/rdata.rs b/src/rdata/svcb/rdata.rs index b8d44cf5..21c670a4 100644 --- a/src/rdata/svcb/rdata.rs +++ b/src/rdata/svcb/rdata.rs @@ -175,6 +175,7 @@ impl> SvcbRdata> { pub fn parse<'a, Src: Octets = Octs> + ?Sized + 'a>( parser: &mut Parser<'a, Src>, ) -> Result { + LongRecordData::check_len(parser.remaining())?; let priority = u16::parse(parser)?; let target = ParsedName::parse(parser)?; let params = SvcParams::parse(parser)?; diff --git a/src/rdata/tsig.rs b/src/rdata/tsig.rs index 62b02288..c0fd7c7c 100644 --- a/src/rdata/tsig.rs +++ b/src/rdata/tsig.rs @@ -307,6 +307,7 @@ impl Tsig> { pub fn parse<'a, Src: Octets = Octs> + ?Sized + 'a>( parser: &mut Parser<'a, Src>, ) -> Result { + LongRecordData::check_len(parser.remaining())?; let algorithm = ParsedName::parse(parser)?; let time_signed = Time48::parse(parser)?; let fudge = u16::parse(parser)?;