From: Evan Hunt Date: Mon, 10 Aug 2015 21:45:05 +0000 (-0700) Subject: [v9_9] add a "wire_test -d" option to read raw binary data X-Git-Tag: v9.9.8rc1~69 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=3b56383dded855048aa5c8e0e24b1dc186595f06;p=thirdparty%2Fbind9.git [v9_9] add a "wire_test -d" option to read raw binary data 4169. [test] Added a 'wire_test -d' option to read input as raw binary data, for use as a fuzzing harness. [RT #40312] --- diff --git a/CHANGES b/CHANGES index c511863ba3b..83b9276708a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +4169. [test] Added a 'wire_test -d' option to read input as + raw binary data, for use as a fuzzing harness. + [RT #40312] + 4168. [security] A buffer accounting error could trigger an assertion failure when parsing certain malformed DNSSEC keys. (CVE-2015-5722) [RT #40212] diff --git a/bin/tests/Makefile.in b/bin/tests/Makefile.in index 315cccfb0c0..43fa42c9760 100644 --- a/bin/tests/Makefile.in +++ b/bin/tests/Makefile.in @@ -49,7 +49,7 @@ SUBDIRS = atomic db dst master mem hashes names net rbt resolver \ # cfg_test is needed for regenerating doc/misc/options # Alphabetically -TARGETS = cfg_test@EXEEXT@ +TARGETS = cfg_test@EXEEXT@ wire_test@EXEEXT@ # All the other tests are optional and not built by default. @@ -93,7 +93,7 @@ XTARGETS = adb_test@EXEEXT@ \ zone_test@EXEEXT@ # Alphabetically -SRCS = cfg_test.c ${XSRCS} +SRCS = cfg_test.c wire_test.c ${XSRCS} XSRCS = adb_test.c \ byaddr_test.c \ diff --git a/bin/tests/fromhex.pl b/bin/tests/fromhex.pl new file mode 100644 index 00000000000..8099602ffc2 --- /dev/null +++ b/bin/tests/fromhex.pl @@ -0,0 +1,50 @@ +#!/usr/bin/perl +# +# Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# Converts hex ascii into raw data. +# (This can be used, for example, to construct input for "wire_data -d".) + +require 5.006.001; + +use strict; +use IO::File; + +sub usage { + print ("Usage: packet.pl [file]\n"); + exit 1; +} + +my $file = "STDIN"; +if (@ARGV >= 1) { + my $filename = shift @ARGV; + open FH, "<$filename" or die "$filename: $!"; + $file = "FH"; +} + +my $input = ""; +while (defined(my $line = <$file>) ) { + chomp $line; + $line =~ s/#.*$//; + $input .= $line; +} + +$input =~ s/\s+//g; +my $data = pack("H*", $input); +my $len = length $data; + +binmode(STDOUT); +print($data); +exit(0); diff --git a/bin/tests/wire_test.c b/bin/tests/wire_test.c index af0c6f7fbf1..7362c6f3ffd 100644 --- a/bin/tests/wire_test.c +++ b/bin/tests/wire_test.c @@ -58,18 +58,19 @@ fromhex(char c) { else if (c >= 'A' && c <= 'F') return (c - 'A' + 10); - printf("bad input format: %02x\n", c); + fprintf(stderr, "bad input format: %02x\n", c); exit(3); /* NOTREACHED */ } static void usage(void) { - fprintf(stderr, "wire_test [-p] [-b] [-s] [-r]\n"); - fprintf(stderr, "\t-p\tPreserve order of the records in messages\n"); + fprintf(stderr, "wire_test [-b] [-d] [-p] [-r] [-s] [filename]\n"); fprintf(stderr, "\t-b\tBest-effort parsing (ignore some errors)\n"); - fprintf(stderr, "\t-s\tPrint memory statistics\n"); + fprintf(stderr, "\t-d\tRead input as raw binary data\n"); + fprintf(stderr, "\t-p\tPreserve order of the records in messages\n"); fprintf(stderr, "\t-r\tAfter parsing, re-render the message\n"); + fprintf(stderr, "\t-s\tPrint memory statistics\n"); fprintf(stderr, "\t-t\tTCP mode - ignore the first 2 bytes\n"); } @@ -85,25 +86,29 @@ main(int argc, char *argv[]) { unsigned char b[64 * 1024]; char s[4000]; isc_boolean_t tcp = ISC_FALSE; + isc_boolean_t rawdata = ISC_FALSE; int ch; mctx = NULL; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); - while ((ch = isc_commandline_parse(argc, argv, "pbsrt")) != -1) { + while ((ch = isc_commandline_parse(argc, argv, "bdprst")) != -1) { switch (ch) { - case 'p': - parseflags |= DNS_MESSAGEPARSE_PRESERVEORDER; - break; case 'b': parseflags |= DNS_MESSAGEPARSE_BESTEFFORT; break; - case 's': - printmemstats = ISC_TRUE; + case 'd': + rawdata = ISC_TRUE; + break; + case 'p': + parseflags |= DNS_MESSAGEPARSE_PRESERVEORDER; break; case 'r': dorender = ISC_TRUE; break; + case 's': + printmemstats = ISC_TRUE; + break; case 't': tcp = ISC_TRUE; break; @@ -116,10 +121,10 @@ main(int argc, char *argv[]) { argc -= isc_commandline_index; argv += isc_commandline_index; - if (argc > 1) { - f = fopen(argv[1], "r"); + if (argc >= 1) { + f = fopen(argv[0], "r"); if (f == NULL) { - printf("fopen failed\n"); + fprintf(stderr, "%s: fopen failed\n", argv[0]); exit(1); } need_close = ISC_TRUE; @@ -127,36 +132,42 @@ main(int argc, char *argv[]) { f = stdin; bp = b; - while (fgets(s, sizeof(s), f) != NULL) { - rp = s; - wp = s; - len = 0; - while (*rp != '\0') { - if (*rp == '#') + if (rawdata) { + while (fread(bp, 1, 1, f) != 0) + bp++; + } else { + while (fgets(s, sizeof(s), f) != NULL) { + rp = s; + wp = s; + len = 0; + while (*rp != '\0') { + if (*rp == '#') + break; + if (*rp != ' ' && *rp != '\t' && + *rp != '\r' && *rp != '\n') { + *wp++ = *rp; + len++; + } + rp++; + } + if (len == 0U) break; - if (*rp != ' ' && *rp != '\t' && - *rp != '\r' && *rp != '\n') { - *wp++ = *rp; - len++; + if (len % 2 != 0U) { + fprintf(stderr, "bad input format: %lu\n", + (unsigned long)len); + exit(1); + } + if (len > sizeof(b) * 2) { + fprintf(stderr, "input too long\n"); + exit(2); + } + rp = s; + for (i = 0; i < len; i += 2) { + n = fromhex(*rp++); + n *= 16; + n += fromhex(*rp++); + *bp++ = n; } - rp++; - } - if (len == 0U) - break; - if (len % 2 != 0U) { - printf("bad input format: %lu\n", (unsigned long)len); - exit(1); - } - if (len > sizeof(b) * 2) { - printf("input too long\n"); - exit(2); - } - rp = s; - for (i = 0; i < len; i += 2) { - n = fromhex(*rp++); - n *= 16; - n += fromhex(*rp++); - *bp++ = n; } } @@ -169,13 +180,13 @@ main(int argc, char *argv[]) { unsigned int len; if (p + 2 > bp) { - printf("premature end of packet\n"); + fprintf(stderr, "premature end of packet\n"); exit(1); } len = p[0] << 8 | p[1]; if (p + 2 + len > bp) { - printf("premature end of packet\n"); + fprintf(stderr, "premature end of packet\n"); exit(1); } isc_buffer_init(&source, p + 2, len);