Repository: c-ares/c-ares
Fuzzing engine: libfuzzer
Fuzz target: ares_parse_reply_fuzzer
Sanitizer: memory
Crash type: Use-of-uninitialized-value

Sanitizer report:
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 4253038037
INFO: Loaded 1 modules   (1762 inline 8-bit counters): 1762 [0x55b14b190218, 0x55b14b1908fa), 
INFO: Loaded 1 PC tables (1762 PCs): 1762 [0x55b14b190900,0x55b14b197720), 
/out/ares_parse_reply_fuzzer: Running 1 inputs 1 time(s) each.
Running: /testcase/OSV-2020-630.poc
MemorySanitizer:DEADLYSIGNAL
==7==ERROR: MemorySanitizer: SEGV on unknown address 0x00ce00000200 (pc 0x55b14afed1d0 bp 0x00cd000100ff sp 0x7ffe637bd800 T7)
==7==The signal is caused by a WRITE memory access.
/usr/local/bin/bdyne: line 32:     7 Segmentation fault      /out/ares_parse_reply_fuzzer /testcase/OSV-2020-630.poc


Fix patch:
diff --git a/ares_parse_a_reply.c b/ares_parse_a_reply.c
index 850c39c0..b506f721 100644
--- a/ares_parse_a_reply.c
+++ b/ares_parse_a_reply.c
@@ -71,7 +71,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
 
       if (naddrttls)
         {
-          *naddrttls = naddrs;
+          *naddrttls = 0;
         }
 
       return status;
@@ -162,7 +162,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
               memcpy(hostent->h_addr_list[i],
                      &(((struct sockaddr_in *)next->ai_addr)->sin_addr),
                      sizeof(struct in_addr));
-              if (naddrttls)
+              if (naddrttls && i < *naddrttls)
                 {
                   if (next->ai_ttl > cname_ttl)
                     addrttls[i].ttl = cname_ttl;
@@ -177,6 +177,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
             }
           next = next->ai_next;
         }
+      if (i == 0)
+        {
+          ares_free(addrs);
+        }
     }
 
   if (host)
diff --git a/ares_parse_aaaa_reply.c b/ares_parse_aaaa_reply.c
index c56279fa..aca3f001 100644
--- a/ares_parse_aaaa_reply.c
+++ b/ares_parse_aaaa_reply.c
@@ -73,7 +73,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
 
       if (naddrttls)
         {
-          *naddrttls = naddrs;
+          *naddrttls = 0;
         }
 
       return status;
@@ -164,7 +164,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
               memcpy(hostent->h_addr_list[i],
                      &(((struct sockaddr_in6 *)next->ai_addr)->sin6_addr),
                      sizeof(struct ares_in6_addr));
-              if (naddrttls)
+              if (naddrttls && i < *naddrttls)
                 {
                     if(next->ai_ttl > cname_ttl)
                       addrttls[i].ttl = cname_ttl;
@@ -179,6 +179,11 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
             }
           next = next->ai_next;
         }
+
+      if (i == 0)
+        {
+          ares_free(addrs);
+        }
     }
 
   if (host)
diff --git a/test/fuzzcheck.sh b/test/fuzzcheck.sh
index 4c50ff21..3a137661 100755
--- a/test/fuzzcheck.sh
+++ b/test/fuzzcheck.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+set -e
 # Check that all of the base fuzzing corpus parse without errors
 ./aresfuzz fuzzinput/*
 ./aresfuzzname fuzznames/*
diff --git a/test/fuzzinput/clusterfuzz-5650695891451904 b/test/fuzzinput/clusterfuzz-5650695891451904
new file mode 100644
index 00000000..1aba3b32
Binary files /dev/null and b/test/fuzzinput/clusterfuzz-5650695891451904 differ
diff --git a/test/fuzzinput/clusterfuzz-5651369832218624 b/test/fuzzinput/clusterfuzz-5651369832218624
new file mode 100644
index 00000000..7e5184cf
Binary files /dev/null and b/test/fuzzinput/clusterfuzz-5651369832218624 differ
diff --git a/test/fuzzinput/clusterfuzz-5674462260756480 b/test/fuzzinput/clusterfuzz-5674462260756480
new file mode 100644
index 00000000..c7b7c65d
Binary files /dev/null and b/test/fuzzinput/clusterfuzz-5674462260756480 differ
diff --git a/test/fuzzinput/clusterfuzz-5680630672654336 b/test/fuzzinput/clusterfuzz-5680630672654336
new file mode 100644
index 00000000..7b5f9cbf
Binary files /dev/null and b/test/fuzzinput/clusterfuzz-5680630672654336 differ
diff --git a/test/fuzzinput/clusterfuzz-5683497160671232 b/test/fuzzinput/clusterfuzz-5683497160671232
new file mode 100644
index 00000000..8d70a178
Binary files /dev/null and b/test/fuzzinput/clusterfuzz-5683497160671232 differ
diff --git a/test/fuzzinput/clusterfuzz-5687310655422464 b/test/fuzzinput/clusterfuzz-5687310655422464
new file mode 100644
index 00000000..cdb78175
Binary files /dev/null and b/test/fuzzinput/clusterfuzz-5687310655422464 differ
diff --git a/test/fuzzinput/clusterfuzz-5695341573177344 b/test/fuzzinput/clusterfuzz-5695341573177344
new file mode 100644
index 00000000..b96ddd47
Binary files /dev/null and b/test/fuzzinput/clusterfuzz-5695341573177344 differ
diff --git a/test/fuzzinput/clusterfuzz-5697835103682560 b/test/fuzzinput/clusterfuzz-5697835103682560
new file mode 100644
index 00000000..f5ef00f6
Binary files /dev/null and b/test/fuzzinput/clusterfuzz-5697835103682560 differ
diff --git a/test/fuzzinput/clusterfuzz-5728518081609728 b/test/fuzzinput/clusterfuzz-5728518081609728
new file mode 100644
index 00000000..31f69570
Binary files /dev/null and b/test/fuzzinput/clusterfuzz-5728518081609728 differ
diff --git a/test/fuzzinput/clusterfuzz-5732960017317888 b/test/fuzzinput/clusterfuzz-5732960017317888
new file mode 100644
index 00000000..5596018c
Binary files /dev/null and b/test/fuzzinput/clusterfuzz-5732960017317888 differ