mirror of
https://github.com/NLnetLabs/domain.git
synced 2026-09-07 02:17:44 +02:00
Check remaining length when parsing open-ended RDATA. (#664)
This PR adds checks to the parse functions of open-ended RDATA types to make sure they will not exceed the maximum RDATA length of 65,535 bytes. Specifically, these checks are added to all types that return an error-result of LongRecordData in their new function. I hope that covers all such types.
This commit is contained in:
+8
-4
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -529,6 +529,12 @@ impl LongRecordData {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LongRecordData> 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())
|
||||
|
||||
@@ -137,6 +137,7 @@ impl<Octs> Cdnskey<Octs> {
|
||||
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<Octs> Cds<Octs> {
|
||||
Some(len) => len,
|
||||
None => return Err(ParseError::ShortInput),
|
||||
};
|
||||
LongRecordData::check_len(len)?;
|
||||
Ok(unsafe {
|
||||
Self::new_unchecked(
|
||||
u16::parse(parser)?,
|
||||
|
||||
@@ -245,6 +245,7 @@ impl<Octs> Dnskey<Octs> {
|
||||
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<Octs> Rrsig<Octs, ParsedName<Octs>> {
|
||||
pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized + 'a>(
|
||||
parser: &mut Parser<'a, Src>,
|
||||
) -> Result<Self, ParseError> {
|
||||
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<Octs> Ds<Octs> {
|
||||
Some(len) => len,
|
||||
None => return Err(ParseError::ShortInput),
|
||||
};
|
||||
LongRecordData::check_len(parser.remaining())?;
|
||||
Ok(unsafe {
|
||||
Self::new_unchecked(
|
||||
u16::parse(parser)?,
|
||||
|
||||
@@ -137,6 +137,7 @@ impl<Octs> Null<Octs> {
|
||||
parser: &mut Parser<'a, Src>,
|
||||
) -> Result<Self, ParseError> {
|
||||
let len = parser.remaining();
|
||||
LongRecordData::check_len(len)?;
|
||||
parser
|
||||
.parse_octets(len)
|
||||
.map(|res| unsafe { Self::from_octets_unchecked(res) })
|
||||
|
||||
@@ -185,6 +185,7 @@ impl<Octs> Txt<Octs> {
|
||||
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 {
|
||||
|
||||
@@ -175,6 +175,7 @@ impl<Variant, Octs: AsRef<[u8]>> SvcbRdata<Variant, Octs, ParsedName<Octs>> {
|
||||
pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized + 'a>(
|
||||
parser: &mut Parser<'a, Src>,
|
||||
) -> Result<Self, ParseError> {
|
||||
LongRecordData::check_len(parser.remaining())?;
|
||||
let priority = u16::parse(parser)?;
|
||||
let target = ParsedName::parse(parser)?;
|
||||
let params = SvcParams::parse(parser)?;
|
||||
|
||||
@@ -307,6 +307,7 @@ impl<Octs> Tsig<Octs, ParsedName<Octs>> {
|
||||
pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized + 'a>(
|
||||
parser: &mut Parser<'a, Src>,
|
||||
) -> Result<Self, ParseError> {
|
||||
LongRecordData::check_len(parser.remaining())?;
|
||||
let algorithm = ParsedName::parse(parser)?;
|
||||
let time_signed = Time48::parse(parser)?;
|
||||
let fudge = u16::parse(parser)?;
|
||||
|
||||
Reference in New Issue
Block a user