Coverage Report

Created: 2026-04-12 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/net-snmp/testing/fuzzing/snmp_e2e_fuzzer.c
Line
Count
Source
1
 /*
2
  * Copyright (c) 2021, Net-snmp authors
3
  * All rights reserved.
4
  *
5
  * Redistribution and use in source and binary forms, with or without
6
  * modification, are permitted provided that the following conditions are met:
7
  *
8
  * * Redistributions of source code must retain the above copyright notice, this
9
  *   list of conditions and the following disclaimer.
10
  *
11
  * * Redistributions in binary form must reproduce the above copyright notice,
12
  *   this list of conditions and the following disclaimer in the documentation
13
  *   and/or other materials provided with the distribution.
14
  *
15
  * * Neither the name of the copyright holder nor the names of its
16
  *   contributors may be used to endorse or promote products derived from
17
  *   this software without specific prior written permission.
18
  *
19
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
  */
30
#include <net-snmp/net-snmp-config.h>
31
#include <net-snmp/net-snmp-includes.h>
32
#include <net-snmp/library/large_fd_set.h>
33
#include <net-snmp/agent/snmp_agent.h>
34
#include <net-snmp/agent/snmp_vars.h>
35
#include <net-snmp/agent/mib_modules.h>
36
#include <stdio.h>
37
#include <unistd.h>
38
#include <sys/types.h>
39
#include <sys/stat.h>
40
#include <fcntl.h>
41
42
9.20k
#define FAKE_FD 3
43
44
const void     *recv_data;
45
int             recv_datalen;
46
47
int
48
snmpfuzz_recv(netsnmp_transport *t, void *buf, int bufsiz, void **opaque,
49
              int *opaque_len)
50
3.54k
{
51
3.54k
    if (bufsiz > recv_datalen) {
52
1.77k
        memcpy(buf, recv_data, recv_datalen);
53
1.77k
        return recv_datalen;
54
1.77k
    } else {
55
1.77k
        return -1;
56
1.77k
    }
57
3.54k
}
58
59
static int
60
snmpfuzz_callback(int op, netsnmp_session *sess, int reqid,
61
                  netsnmp_pdu *pdu, void *magic)
62
6
{
63
    /*
64
     * We leave this empty for now
65
     */
66
6
    return 0;
67
6
}
68
69
void
70
fuzz_fake_pcap(const u_char * buf, size_t len)
71
1.77k
{
72
1.77k
    netsnmp_large_fd_set lfdset;
73
74
1.77k
    recv_data = buf;
75
1.77k
    recv_datalen = len;
76
77
1.77k
    netsnmp_large_fd_set_init(&lfdset, FD_SETSIZE);
78
1.77k
    netsnmp_large_fd_setfd(FAKE_FD, &lfdset);
79
1.77k
    snmp_read2(&lfdset);
80
1.77k
    netsnmp_large_fd_set_cleanup(&lfdset);
81
1.77k
}
82
83
int
84
LLVMFuzzerTestOneInput(const uint8_t * data, size_t size)
85
7.42k
{
86
7.42k
    netsnmp_session *ss;
87
7.42k
    netsnmp_transport *transport;
88
89
7.42k
    u_char         *fuzz_buf = malloc(size + 1);
90
7.42k
    memcpy(fuzz_buf, data, size);
91
7.42k
    fuzz_buf[size] = '\0';
92
93
7.42k
    ss = SNMP_MALLOC_TYPEDEF(netsnmp_session);
94
95
    /*
96
     * We allocate with malloc to avoid constants
97
     */
98
7.42k
    char          **fake_argv = malloc(sizeof(char *) * 3);
99
7.42k
    fake_argv[0] = strdup("snmp_e2e_fuzzer");
100
7.42k
    fake_argv[1] = strdup("-Dall");
101
7.42k
    fake_argv[2] = strdup("localhost");
102
103
7.42k
    snmp_parse_args(3, fake_argv, ss, "", NULL);
104
105
7.42k
    transport = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
106
7.42k
    transport->sock = FAKE_FD;
107
7.42k
    transport->f_recv = snmpfuzz_recv;
108
109
7.42k
    ss->callback = snmpfuzz_callback;
110
7.42k
    ss->callback_magic = (void *) NULL;
111
7.42k
    ss->securityModel = SNMP_SEC_MODEL_USM;
112
7.42k
    create_user_from_session(ss);
113
114
    /*
115
     * Use snmp_add() to specify transport explicitly
116
     */
117
7.42k
    snmp_add(ss, transport, NULL, NULL);
118
119
7.42k
    fuzz_fake_pcap(fuzz_buf, size);
120
121
7.42k
    snmp_close(ss);
122
    /* To do: register session 'ss' properly and remove the call below. */
123
7.42k
    netsnmp_cleanup_session(ss);
124
7.42k
    free(ss);
125
7.42k
    free(fuzz_buf);
126
127
7.42k
    free(fake_argv[0]);
128
7.42k
    free(fake_argv[1]);
129
7.42k
    free(fake_argv[2]);
130
7.42k
    free(fake_argv);
131
132
7.42k
    return 0;
133
7.42k
}