quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

ares-test-fuzz.c (10956B)


      1 /* MIT License
      2  *
      3  * Copyright (c) The c-ares project and its contributors
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a copy
      6  * of this software and associated documentation files (the "Software"), to deal
      7  * in the Software without restriction, including without limitation the rights
      8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      9  * copies of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  * SPDX-License-Identifier: MIT
     25  */
     26 #include <stddef.h>
     27 #include <stdio.h>
     28 #include "ares.h"
     29 #include "include/ares_buf.h"
     30 #include "include/ares_mem.h"
     31 
     32 int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size);
     33 
     34 #ifdef USE_LEGACY_FUZZERS
     35 
     36 /* This implementation calls the legacy c-ares parsers, which historically
     37  * all used different logic and parsing.  As of c-ares 1.21.0 these are
     38  * simply wrappers around a single parser, and simply convert the parsed
     39  * DNS response into the data structures the legacy parsers used which is a
     40  * small amount of code and not likely going to vary based on the input data.
     41  *
     42  * Instead, these days, it makes more sense to test the new parser directly
     43  * instead of calling it 10 or 11 times with the same input data to speed up
     44  * the number of iterations per second the fuzzer can perform.
     45  *
     46  * We are keeping this legacy fuzzer test for historic reasons or if someone
     47  * finds them of use.
     48  */
     49 
     50 int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size)
     51 {
     52   /* Feed the data into each of the ares_parse_*_reply functions. */
     53   struct hostent          *host = NULL;
     54   struct ares_addrttl      info[5];
     55   struct ares_addr6ttl     info6[5];
     56   unsigned char            addrv4[4] = { 0x10, 0x20, 0x30, 0x40 };
     57   struct ares_srv_reply   *srv       = NULL;
     58   struct ares_mx_reply    *mx        = NULL;
     59   struct ares_txt_reply   *txt       = NULL;
     60   struct ares_soa_reply   *soa       = NULL;
     61   struct ares_naptr_reply *naptr     = NULL;
     62   struct ares_caa_reply   *caa       = NULL;
     63   struct ares_uri_reply   *uri       = NULL;
     64   int                      count     = 5;
     65   ares_parse_a_reply(data, (int)size, &host, info, &count);
     66   if (host) {
     67     ares_free_hostent(host);
     68   }
     69 
     70   host  = NULL;
     71   count = 5;
     72   ares_parse_aaaa_reply(data, (int)size, &host, info6, &count);
     73   if (host) {
     74     ares_free_hostent(host);
     75   }
     76 
     77   host = NULL;
     78   ares_parse_ptr_reply(data, (int)size, addrv4, sizeof(addrv4), AF_INET, &host);
     79   if (host) {
     80     ares_free_hostent(host);
     81   }
     82 
     83   host = NULL;
     84   ares_parse_ns_reply(data, (int)size, &host);
     85   if (host) {
     86     ares_free_hostent(host);
     87   }
     88 
     89   ares_parse_srv_reply(data, (int)size, &srv);
     90   if (srv) {
     91     ares_free_data(srv);
     92   }
     93 
     94   ares_parse_mx_reply(data, (int)size, &mx);
     95   if (mx) {
     96     ares_free_data(mx);
     97   }
     98 
     99   ares_parse_txt_reply(data, (int)size, &txt);
    100   if (txt) {
    101     ares_free_data(txt);
    102   }
    103 
    104   ares_parse_soa_reply(data, (int)size, &soa);
    105   if (soa) {
    106     ares_free_data(soa);
    107   }
    108 
    109   ares_parse_naptr_reply(data, (int)size, &naptr);
    110   if (naptr) {
    111     ares_free_data(naptr);
    112   }
    113 
    114   ares_parse_caa_reply(data, (int)size, &caa);
    115   if (caa) {
    116     ares_free_data(caa);
    117   }
    118 
    119   ares_parse_uri_reply(data, (int)size, &uri);
    120   if (uri) {
    121     ares_free_data(uri);
    122   }
    123 
    124   return 0;
    125 }
    126 
    127 #else
    128 
    129 int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size)
    130 {
    131   ares_dns_record_t *dnsrec    = NULL;
    132   char              *printdata = NULL;
    133   ares_buf_t        *printmsg  = NULL;
    134   size_t             i;
    135   unsigned char     *datadup     = NULL;
    136   size_t             datadup_len = 0;
    137 
    138   /* There is never a reason to have a size > 65535, it is immediately
    139    * rejected by the parser */
    140   if (size > 65535) {
    141     return -1;
    142   }
    143 
    144   if (ares_dns_parse(data, size, 0, &dnsrec) != ARES_SUCCESS) {
    145     goto done;
    146   }
    147 
    148   /* Lets test the message fetchers */
    149   printmsg = ares_buf_create();
    150   if (printmsg == NULL) {
    151     goto done;
    152   }
    153 
    154   ares_buf_append_str(printmsg, ";; ->>HEADER<<- opcode: ");
    155   ares_buf_append_str(
    156     printmsg, ares_dns_opcode_tostr(ares_dns_record_get_opcode(dnsrec)));
    157   ares_buf_append_str(printmsg, ", status: ");
    158   ares_buf_append_str(printmsg,
    159                       ares_dns_rcode_tostr(ares_dns_record_get_rcode(dnsrec)));
    160   ares_buf_append_str(printmsg, ", id: ");
    161   ares_buf_append_num_dec(printmsg, (size_t)ares_dns_record_get_id(dnsrec), 0);
    162   ares_buf_append_str(printmsg, "\n;; flags: ");
    163   ares_buf_append_num_hex(printmsg, (size_t)ares_dns_record_get_flags(dnsrec),
    164                           0);
    165   ares_buf_append_str(printmsg, "; QUERY: ");
    166   ares_buf_append_num_dec(printmsg, ares_dns_record_query_cnt(dnsrec), 0);
    167   ares_buf_append_str(printmsg, ", ANSWER: ");
    168   ares_buf_append_num_dec(
    169     printmsg, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER), 0);
    170   ares_buf_append_str(printmsg, ", AUTHORITY: ");
    171   ares_buf_append_num_dec(
    172     printmsg, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_AUTHORITY), 0);
    173   ares_buf_append_str(printmsg, ", ADDITIONAL: ");
    174   ares_buf_append_num_dec(
    175     printmsg, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ADDITIONAL), 0);
    176   ares_buf_append_str(printmsg, "\n\n");
    177   ares_buf_append_str(printmsg, ";; QUESTION SECTION:\n");
    178   for (i = 0; i < ares_dns_record_query_cnt(dnsrec); i++) {
    179     const char         *name;
    180     ares_dns_rec_type_t qtype;
    181     ares_dns_class_t    qclass;
    182 
    183     if (ares_dns_record_query_get(dnsrec, i, &name, &qtype, &qclass) !=
    184         ARES_SUCCESS) {
    185       goto done;
    186     }
    187 
    188     ares_buf_append_str(printmsg, ";");
    189     ares_buf_append_str(printmsg, name);
    190     ares_buf_append_str(printmsg, ".\t\t\t");
    191     ares_buf_append_str(printmsg, ares_dns_class_tostr(qclass));
    192     ares_buf_append_str(printmsg, "\t");
    193     ares_buf_append_str(printmsg, ares_dns_rec_type_tostr(qtype));
    194     ares_buf_append_str(printmsg, "\n");
    195   }
    196   ares_buf_append_str(printmsg, "\n");
    197   for (i = ARES_SECTION_ANSWER; i < ARES_SECTION_ADDITIONAL + 1; i++) {
    198     size_t j;
    199 
    200     ares_buf_append_str(printmsg, ";; ");
    201     ares_buf_append_str(printmsg,
    202                         ares_dns_section_tostr((ares_dns_section_t)i));
    203     ares_buf_append_str(printmsg, " SECTION:\n");
    204     for (j = 0; j < ares_dns_record_rr_cnt(dnsrec, (ares_dns_section_t)i);
    205          j++) {
    206       size_t                   keys_cnt = 0;
    207       const ares_dns_rr_key_t *keys     = NULL;
    208       ares_dns_rr_t           *rr       = NULL;
    209       size_t                   k;
    210 
    211       rr = ares_dns_record_rr_get(dnsrec, (ares_dns_section_t)i, j);
    212       ares_buf_append_str(printmsg, ares_dns_rr_get_name(rr));
    213       ares_buf_append_str(printmsg, ".\t\t\t");
    214       ares_buf_append_str(printmsg,
    215                           ares_dns_class_tostr(ares_dns_rr_get_class(rr)));
    216       ares_buf_append_str(printmsg, "\t");
    217       ares_buf_append_str(printmsg,
    218                           ares_dns_rec_type_tostr(ares_dns_rr_get_type(rr)));
    219       ares_buf_append_str(printmsg, "\t");
    220       ares_buf_append_num_dec(printmsg, ares_dns_rr_get_ttl(rr), 0);
    221       ares_buf_append_str(printmsg, "\t");
    222 
    223       keys = ares_dns_rr_get_keys(ares_dns_rr_get_type(rr), &keys_cnt);
    224       for (k = 0; k < keys_cnt; k++) {
    225         char buf[256] = "";
    226 
    227         ares_buf_append_str(printmsg, ares_dns_rr_key_tostr(keys[k]));
    228         ares_buf_append_str(printmsg, "=");
    229         switch (ares_dns_rr_key_datatype(keys[k])) {
    230           case ARES_DATATYPE_INADDR:
    231             ares_inet_ntop(AF_INET, ares_dns_rr_get_addr(rr, keys[k]), buf,
    232                            sizeof(buf));
    233             ares_buf_append_str(printmsg, buf);
    234             break;
    235           case ARES_DATATYPE_INADDR6:
    236             ares_inet_ntop(AF_INET6, ares_dns_rr_get_addr6(rr, keys[k]), buf,
    237                            sizeof(buf));
    238             ares_buf_append_str(printmsg, buf);
    239             break;
    240           case ARES_DATATYPE_U8:
    241             ares_buf_append_num_dec(printmsg, ares_dns_rr_get_u8(rr, keys[k]),
    242                                     0);
    243             break;
    244           case ARES_DATATYPE_U16:
    245             ares_buf_append_num_dec(printmsg, ares_dns_rr_get_u16(rr, keys[k]),
    246                                     0);
    247             break;
    248           case ARES_DATATYPE_U32:
    249             ares_buf_append_num_dec(printmsg, ares_dns_rr_get_u32(rr, keys[k]),
    250                                     0);
    251             break;
    252           case ARES_DATATYPE_NAME:
    253           case ARES_DATATYPE_STR:
    254             ares_buf_append_byte(printmsg, '"');
    255             ares_buf_append_str(printmsg, ares_dns_rr_get_str(rr, keys[k]));
    256             ares_buf_append_byte(printmsg, '"');
    257             break;
    258           case ARES_DATATYPE_BIN:
    259             /* TODO */
    260             break;
    261           case ARES_DATATYPE_BINP:
    262             {
    263               size_t templen;
    264               ares_buf_append_byte(printmsg, '"');
    265               ares_buf_append_str(printmsg, (const char *)ares_dns_rr_get_bin(
    266                                               rr, keys[k], &templen));
    267               ares_buf_append_byte(printmsg, '"');
    268             }
    269             break;
    270           case ARES_DATATYPE_ABINP:
    271             {
    272               size_t a;
    273               for (a = 0; a < ares_dns_rr_get_abin_cnt(rr, keys[k]); a++) {
    274                 size_t templen;
    275 
    276                 if (a != 0) {
    277                   ares_buf_append_byte(printmsg, ' ');
    278                 }
    279                 ares_buf_append_byte(printmsg, '"');
    280                 ares_buf_append_str(
    281                   printmsg,
    282                   (const char *)ares_dns_rr_get_abin(rr, keys[k], a, &templen));
    283                 ares_buf_append_byte(printmsg, '"');
    284               }
    285             }
    286             break;
    287           case ARES_DATATYPE_OPT:
    288             /* TODO */
    289             break;
    290         }
    291         ares_buf_append_str(printmsg, " ");
    292       }
    293       ares_buf_append_str(printmsg, "\n");
    294     }
    295   }
    296   ares_buf_append_str(printmsg, ";; SIZE: ");
    297   ares_buf_append_num_dec(printmsg, size, 0);
    298   ares_buf_append_str(printmsg, "\n\n");
    299 
    300   printdata = ares_buf_finish_str(printmsg, NULL);
    301   printmsg  = NULL;
    302 
    303   /* Write it back out as a dns message to test writer */
    304   if (ares_dns_write(dnsrec, &datadup, &datadup_len) != ARES_SUCCESS) {
    305     goto done;
    306   }
    307 
    308 done:
    309   ares_dns_record_destroy(dnsrec);
    310   ares_buf_destroy(printmsg);
    311   ares_free(printdata);
    312   ares_free(datadup);
    313   return 0;
    314 }
    315 
    316 #endif