Open
Description
when you are using __libfuzzer_extra_counters to update the coverage with kcov ( or any other coverage feedback)
you don't get correct cov: number in the output.
maybe I have to configure something.
#include <errno.h>
#include <fcntl.h>
#include <linux/bpf.h>
#include <memory.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <stddef.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <time.h>
void fail(const char* msg, ...);
void cover_start();
void cover_stop();
extern "C" int LLVMFuzzerTestOneInput(const char* data, long size)
{
cover_start();
truncate(data, size);
cover_stop();
return 0;
}
#define KCOV_COVER_SIZE (256 << 10)
#define KCOV_TRACE_PC 0
#define KCOV_INIT_TRACE64 _IOR('c', 1, uint64_t)
#define KCOV_ENABLE _IO('c', 100)
__attribute__((section("__libfuzzer_extra_counters"))) unsigned char libfuzzer_coverage[32 << 10];
uint64_t* kcov_data;
extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
int kcov = open("/sys/kernel/debug/kcov", O_RDWR);
if (kcov == -1)
fail("open of /sys/kernel/debug/kcov failed");
if (ioctl(kcov, KCOV_INIT_TRACE64, KCOV_COVER_SIZE))
fail("cover init trace write failed");
kcov_data = (uint64_t*)mmap(NULL, KCOV_COVER_SIZE * sizeof(kcov_data[0]),
PROT_READ | PROT_WRITE, MAP_SHARED, kcov, 0);
if (kcov_data == MAP_FAILED)
fail("cover mmap failed");
if (ioctl(kcov, KCOV_ENABLE, KCOV_TRACE_PC))
fail("cover enable write trace failed");
close(kcov);
return 0;
}
void cover_start()
{
__atomic_store_n(&kcov_data[0], 0, __ATOMIC_RELAXED);
}
#include <iostream>
#include <set>
std::set<uint64_t> uniqueNumbers;
void cover_stop()
{
uint64_t ncov = __atomic_load_n(&kcov_data[0], __ATOMIC_RELAXED);
if (ncov >= KCOV_COVER_SIZE)
fail("too much cover: %llu", ncov);
for (uint64_t i = 0; i < ncov; i++) {
uint64_t pc = __atomic_load_n(&kcov_data[i + 1], __ATOMIC_RELAXED);
auto it = uniqueNumbers.find(pc);
if (it == uniqueNumbers.end()) {
uniqueNumbers.insert(pc);
printf("all pc %lu new uniq pc %lx\n", uniqueNumbers.size(), pc);
}
libfuzzer_coverage[pc % sizeof(libfuzzer_coverage)]++;
}
}
void fail(const char* msg, ...)
{
int e = errno;
va_list args;
va_start(args, msg);
vfprintf(stderr, msg, args);
va_end(args);
fprintf(stderr, " (errno %d)\n", e);
_exit(1);
}
so my printf shows huge amount of new hits but cov output is not
after some seconds:
all 1058 new uniq pc ffffffff823d8cc1
all 1059 new uniq pc ffffffff81a294b4
all 1060 new uniq pc ffffffff81a27a28
all 1061 new uniq pc ffffffff81a27a53
#9064 NEW cov: 77 ft: 1409 corp: 70/481b lim: 29 exec/s: 1812 rss: 27Mb L: 29/29 MS: 2 CopyPart-InsertRepeatedBytes-
#9125 REDUCE cov: 77 ft: 1427 corp: 71/496b lim: 29 exec/s: 1825 rss: 27Mb L: 15/29 MS: 1 CopyPart-
#9141 NEW cov: 77 ft: 1430 corp: 72/525b lim: 29 exec/s: 1828 rss: 27Mb L: 29/29 MS: 1 CopyPart-
#9690 REDUCE cov: 77 ft: 1430 corp: 72/522b lim: 33 exec/s: 1938 rss: 27Mb L: 18/29 MS: 4 ChangeByte-EraseBytes-EraseBytes-PersAutoDict- DE: "\331\\\302\201\377\377\377\377"-
#10037 REDUCE cov: 77 ft: 1430 corp: 72/521b lim: 33 exec/s: 1672 rss: 27Mb L: 17/29 MS: 2 InsertRepeatedBytes-EraseBytes-
#10098 REDUCE cov: 77 ft: 1430 corp: 72/510b lim: 33 exec/s: 1683 rss: 27Mb L: 18/29 MS: 1 EraseBytes-
#10401 NEW cov: 77 ft: 1453 corp: 73/537b lim: 33 exec/s: 1733 rss: 27Mb L: 27/29 MS: 3 CopyPart-CrossOver-CopyPart-
#11827 REDUCE cov: 77 ft: 1453 corp: 73/536b lim: 43 exec/s: 1689 rss: 27Mb L: 8/29 MS: 1 EraseBytes-