Home | History | Annotate | Line # | Download | only in fuzz
      1 /*	$NetBSD: dns_rdata_fromtext.c,v 1.3 2025/01/26 16:25:20 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #include <stdbool.h>
     17 #include <stdlib.h>
     18 
     19 #include <isc/attributes.h>
     20 #include <isc/buffer.h>
     21 #include <isc/commandline.h>
     22 #include <isc/lex.h>
     23 #include <isc/mem.h>
     24 #include <isc/string.h>
     25 #include <isc/util.h>
     26 
     27 #include <dns/fixedname.h>
     28 #include <dns/name.h>
     29 #include <dns/rdata.h>
     30 #include <dns/rdataclass.h>
     31 #include <dns/rdatatype.h>
     32 #include <dns/result.h>
     33 
     34 #include "fuzz.h"
     35 
     36 bool debug = false;
     37 
     38 int
     39 LLVMFuzzerInitialize(int *argc, char ***argv) {
     40 	UNUSED(argc);
     41 	UNUSED(argv);
     42 	return 0;
     43 }
     44 
     45 /* following code was copied from named-rrchecker */
     46 isc_lexspecials_t specials = { ['('] = 1, [')'] = 1, ['"'] = 1 };
     47 
     48 int
     49 LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
     50 	isc_mem_t *mctx = NULL;
     51 	isc_mem_create(&mctx);
     52 
     53 	isc_lex_t *lex = NULL;
     54 	isc_token_t token;
     55 
     56 	isc_result_t result;
     57 	unsigned int options = 0;
     58 	dns_rdatatype_t rdtype;
     59 	dns_rdataclass_t rdclass;
     60 
     61 	char wiredata[64 * 1024];
     62 	isc_buffer_t wirebuf;
     63 	isc_buffer_init(&wirebuf, wiredata, sizeof(wiredata));
     64 
     65 	dns_rdata_t rdata = DNS_RDATA_INIT;
     66 	dns_name_t *name = NULL;
     67 
     68 	isc_buffer_t inbuf;
     69 	isc_buffer_constinit(&inbuf, data, size);
     70 	isc_buffer_add(&inbuf, size);
     71 	isc_buffer_setactive(&inbuf, size);
     72 
     73 	isc_lex_create(mctx, 256, &lex);
     74 
     75 	/*
     76 	 * Set up to lex DNS master file.
     77 	 */
     78 	isc_lex_setspecials(lex, specials);
     79 	options = ISC_LEXOPT_EOL;
     80 	isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE);
     81 
     82 	RUNTIME_CHECK(isc_lex_openbuffer(lex, &inbuf) == ISC_R_SUCCESS);
     83 
     84 	result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER, &token);
     85 	if (result != ISC_R_SUCCESS) {
     86 		goto cleanup;
     87 	}
     88 	if (token.type == isc_tokentype_eof) {
     89 		goto cleanup;
     90 	}
     91 	if (token.type == isc_tokentype_eol) {
     92 		goto cleanup;
     93 	}
     94 	/*
     95 	 * Get class.
     96 	 */
     97 	if (token.type == isc_tokentype_number) {
     98 		if (token.value.as_ulong > 0xffff) {
     99 			goto cleanup;
    100 		}
    101 		rdclass = (dns_rdataclass_t)token.value.as_ulong;
    102 	} else if (token.type == isc_tokentype_string) {
    103 		result = dns_rdataclass_fromtext(&rdclass,
    104 						 &token.value.as_textregion);
    105 		if (result != ISC_R_SUCCESS) {
    106 			goto cleanup;
    107 		}
    108 	} else {
    109 		goto cleanup;
    110 	}
    111 	result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER, &token);
    112 	if (result != ISC_R_SUCCESS) {
    113 		goto cleanup;
    114 	}
    115 	if (token.type == isc_tokentype_eol) {
    116 		goto cleanup;
    117 	}
    118 	if (token.type == isc_tokentype_eof) {
    119 		goto cleanup;
    120 	}
    121 
    122 	/*
    123 	 * Get type.
    124 	 */
    125 	if (token.type == isc_tokentype_number) {
    126 		if (token.value.as_ulong > 0xffff) {
    127 			goto cleanup;
    128 		}
    129 		rdtype = (dns_rdatatype_t)token.value.as_ulong;
    130 	} else if (token.type == isc_tokentype_string) {
    131 		result = dns_rdatatype_fromtext(&rdtype,
    132 						&token.value.as_textregion);
    133 		if (result != ISC_R_SUCCESS) {
    134 			goto cleanup;
    135 		}
    136 	} else {
    137 		goto cleanup;
    138 	}
    139 
    140 	result = dns_rdata_fromtext(&rdata, rdclass, rdtype, lex, name, 0, mctx,
    141 				    &wirebuf, NULL);
    142 	if (debug) {
    143 		fprintf(stderr, "dns_rdata_fromtext: %s\n",
    144 			isc_result_totext(result));
    145 	}
    146 
    147 cleanup:
    148 	isc_lex_close(lex);
    149 	isc_lex_destroy(&lex);
    150 	isc_mem_destroy(&mctx);
    151 	return 0;
    152 }
    153