dns_rdata_fromtext.c revision 1.3 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