Skip to content

Commit

Permalink
Add maximum value check for edns_size parameter in Zonemaster::Engine…
Browse files Browse the repository at this point in the history
…::Nameserver->query()

The maximum value for this parameter, set either by "edns_size" or "edns_details->size", is a 16-bit value,
thus it should not exceed 65535. Documentation and unit tests are updated too.
  • Loading branch information
tgreenx committed Nov 21, 2024
1 parent 7eee392 commit fbc7570
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
14 changes: 8 additions & 6 deletions lib/Zonemaster/Engine/Nameserver.pm
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ sub query {
$dnssec = $href->{edns_details}{do};
}

my $edns_size = $href->{edns_size} // ( $dnssec ? $UDP_DNSSEC_QUERY_DEFAULT : 0 );

# Fake a DS answer
if ( $type eq 'DS' and $class eq 'IN' and $self->fake_ds->{ lc( $name ) } ) {
my $p = Zonemaster::LDNS::Packet->new( $name, $type, $class );
Expand Down Expand Up @@ -292,8 +294,6 @@ sub query {
$md5->add( q{USEVC} , $usevc );
$md5->add( q{RECURSE} , $recurse );

my $edns_size = $href->{edns_size} // ( $dnssec ? $UDP_DNSSEC_QUERY_DEFAULT : 0 );

if ( exists $href->{edns_details} ) {
$md5->add( q{EDNS_VERSION} , $href->{edns_details}{version} // 0 );
$md5->add( q{EDNS_Z} , $href->{edns_details}{z} // 0 );
Expand All @@ -302,6 +302,8 @@ sub query {
$edns_size = $href->{edns_details}{size} // ( $href->{edns_size} // ( $dnssec ? $UDP_DNSSEC_QUERY_DEFAULT : $UDP_EDNS_QUERY_DEFAULT ) );
}

croak "edns_size (or edns_details->size) parameter cannot exceed 65535" if $edns_size > 65535;

$md5->add( q{EDNS_UDP_SIZE} , $edns_size );

my $idx = $md5->b64digest();
Expand Down Expand Up @@ -768,7 +770,7 @@ Remove all cached nameserver objects and queries.
Send a DNS query to the nameserver the object represents. C<$name> and C<$type> are the name and type that will be queried for (C<$type> defaults
to 'A' if it's left undefined). C<$flagref> is a reference to a hash, the keys of which are flags and the values are their corresponding values.
The available flags are as follows. All but 'class' and 'edns_details' directly correspond to methods in the L<Zonemaster::LDNS::Resolver> object.
The available flags are as follows. All but 'class' and 'edns_details' directly correspond to methods in the L<Zonemaster::LDNS> object.
=over
Expand Down Expand Up @@ -821,15 +823,15 @@ If set to true, prevents a server to be black-listed on a query in case there is
=item edns_size
Set the EDNS0 UDP maximum size. Defaults to 0, or 512 if the query is an non-DNSSEC EDNS query,
or 1232 if the query is a DNSSEC EDNS query.
Set the EDNS0 UDP maximum size. Defaults to 0, or 512 if the query is a non-DNSSEC EDNS query,
or 1232 if the query is a DNSSEC query. Cannot be set higher than 65535.
Setting a value other than 0 will also implicitly enable EDNS for the query.
Value overridden by C<edns_details-E<gt>{size}> (if also given). More details in L<edns_details> below.
=item edns_details
A hash. An empty hash or a hash with any keys below will enable the query to be an EDNS query.
A hash. An empty hash or a hash with any keys below will enable EDNS for the query.
The currently supported keys are 'version', 'z', 'do', 'rcode', 'size' and 'data'.
See L<Zonemaster::LDNS::Packet> for more details (key names prefixed with 'edns_').
Expand Down
4 changes: 4 additions & 0 deletions t/nameserver.t
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use Test::More;
use Test::Exception;

BEGIN { use_ok( 'Zonemaster::Engine::Nameserver' ); }
use Zonemaster::Engine;
Expand Down Expand Up @@ -212,6 +213,9 @@ subtest 'dnssec, edns_size and edns_details{do, size} flags behavior for queries
is( $ns->dns->dnssec, 1, 'dnssec flag is set' );
is( $ns->dns->edns_size, 0, 'edns_size is unset' );
ok( $p->has_edns and $p->do, 'DNSSEC response received on query with dnssec set by edns_details{do} and even with edns_details{size} set to 0' );

dies_ok { $p = $ns->query( 'fr', 'SOA', { "edns_size" => 65536 } ); } "dies when edns_size exceeds 65535";
dies_ok { $p = $ns->query( 'fr', 'SOA', { "edns_details" => { "size" => 65536 } } ); } "dies when edns_size (set with edns_details->size) exceeds 65535";
};

if ( $ENV{ZONEMASTER_RECORD} ) {
Expand Down

0 comments on commit fbc7570

Please sign in to comment.