While the range number of GENERATE is now limited, one can pass
a line with 2 $GENERATE directive that will exponentially increase the
time spent generating RRs.
Limit to only one per line.
Fixes#1020
* Limit $GENERATE range to 65535 steps
Having these checks means all test in TestCrasherString() are not
reached because we bail out earlier - removed that test all together.
Fixes#1019
Signed-off-by: Miek Gieben <miek@miek.nl>
* bring back testcase
Signed-off-by: Miek Gieben <miek@miek.nl>
* bring back crash test
Signed-off-by: Miek Gieben <miek@miek.nl>
* [fuzz] Fix crashes when parsing GENERATE
Running the fuzzer on NewRR, some crashes came up that could be
prevented by checking that the token after the range is a Blank.
This diff checks that and return an error when the blank is not found.
* * s/Expect blank /garbage /
* get rid of if/else
* Improve ParseZone tests
* Add new ZoneParser API
* Use the ZoneParser API directly in ReadRR
* Merge parseZoneHelper into ParseZone
* Make generate string building slightly more efficient
* Add SetDefaultTTL method to ZoneParser
This makes it possible for external consumers to implement ReadRR.
* Make $INCLUDE directive opt-in
The $INCLUDE directive opens a user controlled file and parses it as
a DNS zone file. The error messages may reveal portions of sensitive
files, such as:
/etc/passwd: dns: not a TTL: "root❌0:0:root:/root:/bin/bash" at line: 1:31
/etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
Both ParseZone and ReadRR are currently opt-in for backward
compatibility.
* Disable $INCLUDE support in ReadRR
ReadRR and NewRR are often passed untrusted input. At the same time,
$INCLUDE isn't really useful for ReadRR as it only ever returns the
first record.
This is a breaking change, but it currently represents a slight
security risk.
* Document the need to drain the ParseZone chan
* Cleanup the documentation of NewRR, ReadRR and ParseZone
* Document the ZoneParser API
* Deprecated the ParseZone function
* Add whitespace to ZoneParser.Next
* Remove prevName field from ZoneParser
This doesn't track anything meaningful as both zp.prevName and h.Name
are only ever set at the same point and to the same value.
* Use uint8 for ZoneParser.include field
It has a maximum value of 7 which easily fits within uint8.
This reduces the size of ZoneParser from 160 bytes to 152 bytes.
* Add setParseError helper to ZoneParser
* Surface $INCLUDE os.Open error in error message
* Rename ZoneParser.include field to includeDepth
* Make maximum $INCLUDE depth a const
* Add ParseZone and ZoneParser benchmarks
* Parse $GENERATE directive with a single ZoneParser
This should be more efficient than calling NewRR for each generated
record.
* Run go fmt on generate_test.go
* Add a benchmark for $GENERATE directives
* Use a custom reader for generate
This avoids the overhead and memory usage of building the zone string.
name old time/op new time/op delta
Generate-12 165µs ± 4% 157µs ± 2% -5.06% (p=0.000 n=25+25)
name old alloc/op new alloc/op delta
Generate-12 42.1kB ± 0% 31.8kB ± 0% -24.42% (p=0.000 n=20+23)
name old allocs/op new allocs/op delta
Generate-12 1.56k ± 0% 1.55k ± 0% -0.38% (p=0.000 n=25+25)
* Return correct ParseError from generateReader
The last commit made these regular errors while they had been
ParseErrors before.
* Return error message as string from modToPrintf
This is slightly simpler and they don't need to be errors.
* Skip setting includeDepth in generate
This sub parser isn't allowed to use $INCLUDE directives anyway.
Note: If generate is ever changed to allow $INCLUDE directives, then
this line must be added back. Without doing that, it would be
be possible to exceed maxIncludeDepth.
* Make generateReader errors sticky
ReadByte should not be called after an error has been returned, but
this is cheap insurance.
* Move file and lex fields to end of generateReader
These are only used for creating a ParseError and so are unlikely to be
accessed.
* Don't return offset with error in modToPrintf
Along for the ride, are some whitespace and style changes.
* Add whitespace to generate and simplify step
* Use a for loop instead of goto in generate
* Support $INCLUDE directives inside $GENERATE directives
This was previously supported and may be useful. This is now more
rigorous as the maximum include depth is respected and relative
$INCLUDE directives are now supported from within $GENERATE.
* Don't return any lexer tokens after read error
Without this, read errors are likely to be lost and become parse errors
of the remaining str. The $GENERATE code relies on surfacing errors from
the reader.
* Support $INCLUDE in NewRR and ReadRR
Removing $INCLUDE support from these is a breaking change and should
not be included in this pull request.
* Add test to ensure $GENERATE respects $INCLUDE support
* Unify TestZoneParserIncludeDisallowed with other tests
* Remove stray whitespace from TestGenerateSurfacesErrors
* Move ZoneParser SetX methods above Err method
* $GENERATE should not accept step of 0
If step is allowed to be 0, then generateReader (and the code it
replaced) will get stuck in an infinite loop.
This is a potential DOS vulnerability.
* Fix ReadRR comment for file argument
I missed this previosuly. The file argument is also used to
resolve relative $INCLUDE directives.
* Prevent test panics on nil error
* Rework ZoneParser.subNext
This is slightly cleaner and will close the underlying *os.File even
if an error occurs.
* Make ZoneParser.generate call subNext
This also moves the calls to setParseError into generate.
* Report errors when parsing rest of $GENERATE directive
* Report proper error location in $GENERATE directive
This makes error messages much clearer.
* Simplify modToPrintf func
Note: When width is 0, the leading 0 of the fmt string is now excluded.
This should not alter the formatting of numbers in anyway.
* Add comment explaining sub field
* Remove outdated error comment from generate
Although BIND9 documentations does not specify the possible size of offset
in $GENERATE clause, it clearly says that range must be a positive integer
between 0 and (2^31)-1. Moreover, BIND perfectly supports large offsets
which might be really handy when you're dealing with large intranets. I.e.
consider following case
```
$GENERATE 0-255 dhcp-${0,4,d} A 10.0.0.$
$GENERATE 0-255 dhcp-${256,4,d} A 10.0.1.$
$GENERATE 0-255 dhcp-${512,4,d} A 10.0.2.$
...
```
This change removes offset size check and introduces check that
0 >= (start + offset) and (end + offset) < (2^31)-1.
* Add a ParseZone test for $GENERATE.
* Add a test for modToPrintf used by $GENERATE.
* Correctly handle $GENERATE modifiers.
As per http://www.zytrax.com/books/dns/ch8/generate.html, the width and type (aka base)
components of a modifier are optional. This means that ${2,0,d}, ${2,0} and ${2} are
valid modifiers, however only the first format was previously permitted. Use default
values for the width and/or type if they are unspecified in the modifier.