Coverage Report

Created: 2023-01-17 06:13

/src/libpcap/testprogs/fuzz/fuzz_both.c
Line
Count
Source (jump to first uncovered line)
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <fcntl.h>
4
#include <errno.h>
5
#include <string.h>
6
#include <unistd.h>
7
8
#include <pcap/pcap.h>
9
10
FILE * outfile = NULL;
11
12
14.2k
static int bufferToFile(const char * name, const uint8_t *Data, size_t Size) {
13
14.2k
    FILE * fd;
14
14.2k
    if (remove(name) != 0) {
15
0
        if (errno != ENOENT) {
16
0
            printf("failed remove, errno=%d\n", errno);
17
0
            return -1;
18
0
        }
19
0
    }
20
14.2k
    fd = fopen(name, "wb");
21
14.2k
    if (fd == NULL) {
22
0
        printf("failed open, errno=%d\n", errno);
23
0
        return -2;
24
0
    }
25
14.2k
    if (fwrite (Data, 1, Size, fd) != Size) {
26
0
        fclose(fd);
27
0
        return -3;
28
0
    }
29
14.2k
    fclose(fd);
30
14.2k
    return 0;
31
14.2k
}
32
33
0
void fuzz_openFile(const char * name) {
34
0
    if (outfile != NULL) {
35
0
        fclose(outfile);
36
0
    }
37
0
    outfile = fopen(name, "w");
38
0
}
39
40
14.3k
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
41
14.3k
    pcap_t * pkts;
42
14.3k
    char errbuf[PCAP_ERRBUF_SIZE];
43
14.3k
    char filename[FILENAME_MAX] = { 0 };
44
14.3k
    const u_char *pkt;
45
14.3k
    struct pcap_pkthdr *header;
46
14.3k
    int fd = -1, r;
47
14.3k
    size_t filterSize;
48
14.3k
    char * filter;
49
14.3k
    struct bpf_program bpf;
50
51
52
    //initialize output file
53
14.3k
    if (outfile == NULL) {
54
1
        outfile = fopen("/dev/null", "w");
55
1
        if (outfile == NULL) {
56
0
            return 0;
57
0
        }
58
1
    }
59
60
14.3k
    if (Size < 1) {
61
0
        return 0;
62
0
    }
63
14.3k
    filterSize = Data[0];
64
14.3k
    if (Size < 1+filterSize || filterSize == 0) {
65
15
        return 0;
66
15
    }
67
68
    //generate temporary file name
69
14.2k
    snprintf(filename, FILENAME_MAX, "/tmp/libpcap_fuzz_both.XXXXXX");
70
14.2k
    if ((fd = mkstemp(filename)) < 0) {
71
0
        return 0;
72
0
    }
73
14.2k
    close(fd);
74
75
    //rewrite buffer to a file as libpcap does not have buffer inputs
76
14.2k
    if (bufferToFile(filename, Data+1+filterSize, Size-(1+filterSize)) < 0) {
77
0
        unlink(filename);
78
0
        return 0;
79
0
    }
80
81
    //initialize structure
82
14.2k
    pkts = pcap_open_offline(filename, errbuf);
83
14.2k
    if (pkts == NULL) {
84
781
        fprintf(outfile, "Couldn't open pcap file %s\n", errbuf);
85
781
        unlink(filename);
86
781
        return 0;
87
781
    }
88
89
13.5k
    filter = malloc(filterSize);
90
13.5k
    memcpy(filter, Data+1, filterSize);
91
    //null terminate string
92
13.5k
    filter[filterSize-1] = 0;
93
94
13.5k
    if (pcap_compile(pkts, &bpf, filter, 1, PCAP_NETMASK_UNKNOWN) == 0) {
95
        //loop over packets
96
8.15k
        r = pcap_next_ex(pkts, &header, &pkt);
97
34.7k
        while (r > 0) {
98
            //checks filter
99
26.5k
            fprintf(outfile, "packet length=%d/%d filter=%d\n",header->caplen, header->len, pcap_offline_filter(&bpf, header, pkt));
100
26.5k
            r = pcap_next_ex(pkts, &header, &pkt);
101
26.5k
        }
102
        //close structure
103
8.15k
        pcap_close(pkts);
104
8.15k
        pcap_freecode(&bpf);
105
8.15k
    }
106
5.36k
    else {
107
5.36k
        pcap_close(pkts);
108
5.36k
    }
109
13.5k
    free(filter);
110
111
13.5k
    unlink(filename);
112
13.5k
    return 0;
113
14.2k
}