diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2024-04-26 02:57:20 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2024-04-26 02:58:54 +0200 |
commit | 42694bf99a8937060944d94af7333e1cc006ad94 (patch) | |
tree | e2c9273a8e9bc529511ade2f5ef367bac6fdcc11 | |
parent | 9d171be3899e4e94e418a2975fdec41da194e986 (diff) | |
download | slirp-42694bf99a8937060944d94af7333e1cc006ad94.zip slirp-42694bf99a8937060944d94af7333e1cc006ad94.tar.gz slirp-42694bf99a8937060944d94af7333e1cc006ad94.tar.bz2 |
fuzz: Fix icmp6 matching and checksum computation
-rw-r--r-- | fuzzing/slirp_fuzz_icmp6.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/fuzzing/slirp_fuzz_icmp6.c b/fuzzing/slirp_fuzz_icmp6.c index 094769c..bbe041c 100644 --- a/fuzzing/slirp_fuzz_icmp6.c +++ b/fuzzing/slirp_fuzz_icmp6.c @@ -64,10 +64,12 @@ extern size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, } // Exclude packets that are not ICMP from the mutation strategy - if (ip_data[9] != IPPROTO_ICMPV6) + if (ip_data[6] != IPPROTO_ICMPV6) continue; - uint8_t Data_to_mutate[MaxSize]; + // Allocate a bit more than needed, this is useful for + // checksum calculation. + uint8_t Data_to_mutate[MaxSize + PSEUDO_IPV6_SIZE]; uint8_t ip_hl_in_bytes = sizeof(struct ip6); /* ip header length */ // Fixme : don't use ip_hl_in_bytes inside the fuzzing code, maybe use the @@ -87,7 +89,7 @@ extern size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, // Copy interesting data to the `Data_to_mutate` array // here we want to fuzz everything in icmp - memset(Data_to_mutate, 0, MaxSize); + memset(Data_to_mutate, 0, MaxSize + PSEUDO_IPV6_SIZE); memcpy(Data_to_mutate, start_of_icmp, icmp_size); // Call to libfuzzer's mutation function. @@ -104,8 +106,18 @@ extern size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, // Set the `checksum` field to 0 and calculate the new checksum *(uint16_t *)(Data_to_mutate + 2) = 0; + // Copy the source and destination IP addresses, the tcp length and + // protocol number at the end of the `Data_to_mutate` array to calculate + // the new checksum. + memcpy(Data_to_mutate + icmp_size, ip_data + 8, 16*2); + + *(Data_to_mutate + icmp_size + 16*2 + 1) = IPPROTO_ICMPV6; + + *(Data_to_mutate + icmp_size + 16*2 + 2) = (uint8_t)(icmp_size / 256); + *(Data_to_mutate + icmp_size + 16*2 + 3) = (uint8_t)(icmp_size % 256); + uint16_t new_checksum = - compute_checksum(Data_to_mutate, icmp_size); + compute_checksum(Data_to_mutate, icmp_size + PSEUDO_IPV6_SIZE); *(uint16_t *)(Data_to_mutate + 2) = htons(new_checksum); // Copy the mutated data back to the `Data` array |