Coverage Report

Created: 2026-05-14 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/net-snmp/testing/fuzzing/snmp_parse_trap2_fuzzer.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2025, 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
31
#include <net-snmp/net-snmp-config.h>
32
#include <net-snmp/net-snmp-includes.h>
33
#include "../../apps/snmptrapd_handlers.h"
34
#include "ada_fuzz_header.h"
35
36
static netsnmp_session *add_session(netsnmp_transport *t)
37
66
{
38
66
    netsnmp_session session;
39
40
66
    snmp_sess_init(&session);
41
66
    session.peername = SNMP_DEFAULT_PEERNAME;
42
66
    session.version = SNMP_DEFAULT_VERSION;
43
66
    session.community_len = SNMP_DEFAULT_COMMUNITY_LEN;
44
66
    session.retries = SNMP_DEFAULT_RETRIES;
45
66
    session.timeout = SNMP_DEFAULT_TIMEOUT;
46
66
    session.callback = snmp_input;
47
66
    session.callback_magic = t;
48
66
    session.authenticator = NULL;
49
66
    session.isAuthoritative = SNMP_SESS_UNKNOWNAUTH;
50
51
66
    return snmp_add(&session, t, NULL, NULL);
52
66
}
53
54
32
int LLVMFuzzerInitialize(int *argc, char ***argv) {
55
32
    if (getenv("NETSNMP_DEBUGGING") != NULL) {
56
0
        snmp_enable_stderrlog();
57
0
        snmp_set_do_debugging(1);
58
0
        debug_register_tokens("sess_process_packet");
59
0
    }
60
61
32
    return 0;
62
32
}
63
64
67
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
65
67
    netsnmp_transport *transport = NULL;
66
67
    netsnmp_session *session = NULL;
67
67
    const unsigned short pkt_len = size;
68
67
    const void *const pkt = data;
69
67
    int skt = -1;
70
67
    int ret = 1;
71
72
67
    if (pkt_len == 0)
73
1
        goto cleanup;
74
75
66
    netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIBDIRS, "mibs");
76
66
    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
77
66
                           NETSNMP_DS_LIB_DONT_PERSIST_STATE, 1);
78
66
    netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PERSISTENT_DIR,
79
66
                          "/tmp");
80
81
66
    init_snmp("snmptrapd");
82
83
66
    transport = netsnmp_transport_open_server("trap_fuzzer", "127.0.0.1:7365");
84
66
    if (!transport) {
85
0
        fprintf(stderr, "Error: failed to open Net-SNMP transport.\n");
86
0
        goto cleanup;
87
0
    }
88
66
    session = add_session(transport);
89
66
    if (!session) {
90
0
        fprintf(stderr, "Error: failed to add Net-SNMP session.\n");
91
0
        goto cleanup;
92
0
    }
93
94
66
    skt = socket(AF_INET, SOCK_DGRAM, 0);
95
66
    if (skt < 0) {
96
0
        perror("socket()");
97
0
        goto shutdown;
98
0
    }
99
66
    struct sockaddr_in addr = {
100
66
        .sin_family = AF_INET,
101
66
        .sin_port = htons(7365),
102
66
        .sin_addr = { htonl(INADDR_LOOPBACK) }
103
66
    };
104
66
    if (connect(skt, &addr, sizeof(addr)) < 0) {
105
0
        perror("connect()");
106
0
        goto shutdown;
107
0
    }
108
66
    if (send(skt, pkt, pkt_len, 0) < 0) {
109
1
        perror("send()");
110
1
        goto shutdown;
111
1
    }
112
65
    {
113
65
        fd_set readfds,writefds,exceptfds;
114
65
        int numfds = 0, block = 0;
115
65
        struct timeval timeout;
116
117
65
        FD_ZERO(&readfds);
118
65
        FD_ZERO(&writefds);
119
65
        FD_ZERO(&exceptfds);
120
65
        timerclear(&timeout);
121
65
        timeout.tv_sec = 5;
122
65
        snmp_select_info(&numfds, &readfds, &timeout, &block);
123
65
        if (select(numfds, &readfds, &writefds, &exceptfds, &timeout) > 0)
124
65
            snmp_read(&readfds);
125
65
    }
126
65
    ret = 0;
127
128
66
shutdown:
129
66
    snmp_shutdown("snmptrapd");
130
131
67
cleanup:
132
67
    if (skt >= 0)
133
66
        close(skt);
134
67
    if (session)
135
66
        snmp_close(session);
136
137
67
    return ret;
138
66
}