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