Skip to content

[libfuzzer] coverage output of libfuzzer doesn't show correct number when you are using __libfuzzer_extra_counters #87468

Open
@R00tkitSMM

Description

@R00tkitSMM

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-

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions