-
Notifications
You must be signed in to change notification settings - Fork 36
Open
Labels
bugSomething isn't workingSomething isn't working
Description
PromptFuzz hit a crash trying to run fuse-fuzzer on a c-ares fuzz harness file.
Seems like the error is that the size > 16 ? 16 : size generates a clang Node with kind=Other, and that is not handled during some processing code.
id_000359.infer.cc:
#include "FDSan.h"
#include <ares.h>
#include <ares_dns.h>
#include <ares_nameser.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <vector>
#include <fstream>
#include <iostream>
#include <sstream>
//<ID> 359
//<Prompt> []
/*<Combination>: [
*/
//<score> 0, nr_unique_branch: 0
//<Quality> {"density":0,"unique_branches":{},"library_calls":[],"critical_calls":[],"visited":0}
/*Certainly! Let's break down how to create a fuzz driver that uses the selected c-ares APIs based on your requirements and input.
### 1. **Event Design**
Given the APIs:
- `ares_dns_record_query_get` - Gets query info from a DNS record.
- `ares_dns_record_rr_del` - Deletes a resource record from a DNS record.
- `ares_version` - Queries the c-ares version.
- `ares_process_fd` - Processes a file descriptor for ares events.
- `ares_dns_rr_add_abin` - Adds binary data to a DNS RR (resource record).
**Event**:
Given a byte stream which is a DNS message (output from c-ares), we will:
- Parse it into a DNS record.
- Access its queries.
- Remove a resource record.
- Add some binary data to a resource record.
- Simulate event handling via file descriptors.
- Report the c-ares version.
### 2. **Resource Management**
- We'll parse the DNS message directly from the fuzzer input.
- To get file descriptors, we'll use `fmemopen`.
- We'll manage all memory and cleanup.
### 3. **Code Walkthrough**
*/
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if(size<0) return 0;
if (size < 8) {
return 0;
}
// Not enough for a meaningful DNS message
// 1. Parse DNS message from input data into a record
ares_dns_record_t *dnsrec = nullptr;
ares_status_t status = ares_dns_parse(data, size, 0, &dnsrec);
if (status != ARES_SUCCESS || !dnsrec) {
return 0;
}
// 2. Get query info if present
size_t query_cnt = ares_dns_record_query_cnt(dnsrec);
if (query_cnt > 0) {
const char *qname = nullptr;
ares_dns_rec_type_t qtype;
ares_dns_class_t qclass;
ares_dns_record_query_get(dnsrec, 0, &qname, &qtype, &qclass); // Use first query
}
// 3. Delete a resource record if present in answer section
size_t rr_cnt = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER);
if (rr_cnt > 0) {
ares_dns_record_rr_del(dnsrec, ARES_SECTION_ANSWER, 0);
}
// 4. Add binary data as an attribute to a resource record if possible
const ares_dns_rr_t *rr = nullptr;
if (ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER) > 0) {
rr = ares_dns_record_rr_get_const(dnsrec, ARES_SECTION_ANSWER, 0);
}
// Make a mutable copy by duplicating the record and getting RR 0
ares_dns_record_t *dnsrec_dup = nullptr;
if (rr) {
dnsrec_dup = ares_dns_record_duplicate(dnsrec);
if (dnsrec_dup) {
ares_dns_rr_t *rr_mut = const_cast<ares_dns_rr_t*>(
ares_dns_record_rr_get_const(dnsrec_dup, ARES_SECTION_ANSWER, 0));
// Choose key 0 (arbitrary, for fuzzing)
ares_dns_rr_add_abin(rr_mut, (ares_dns_rr_key_t)0, data, size > 16 ? 16 : size);
}
}
// 5. Report c-ares version
int ver = 0;
ares_version(&ver);
// 6. Use file descriptors to simulate network events.
// Here we'll create a fake channel and process some fd events with the input fd.
ares_channel_t *channel = nullptr;
if (ares_library_init(ARES_LIB_INIT_ALL) == ARES_SUCCESS) {
if (ares_init_options(&channel, nullptr, 0) == ARES_SUCCESS && channel) {
FILE *in_file = fmemopen((void *)data, size, "rb");
if (in_file) {
int fd = fuzz_fileno(in_file);
ares_process_fd(channel, fd, fd);
assert_file_closed(&in_file);;
}
ares_destroy(channel);
}
ares_library_cleanup();
}
// Cleanup
if (dnsrec_dup)
ares_dns_record_destroy(dnsrec_dup);
if (dnsrec)
ares_dns_record_destroy(dnsrec);
return 0;
}This runs into:
thread 'main' panicked at src/ast/helper.rs:161:18:
not implemented: Node {
id: Id(0x5555567bea30),
kind: Other,
inner: [
Node {
id: Id(0x5555567be9a0),
kind: BinaryOperator(
BinaryOperator {
range: SourceRange {
begin: SourceLocation {
spelling_loc: Some(
BareSourceLocation {
offset: 3036,
file: "/root/promptfuzz/output/c-ares/work/id_000359/id_000359.infer.cc",
line: 93,
presumed_file: None,
presumed_line: None,
col: 64,
tok_len: 4,
included_from: None,
is_macro_arg_expansion: false,
},
),
...
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working