Skip to content

Commit 6861032

Browse files
committed
testing/fuzzing: Add a second trap fuzz test
Add a fuzzer that simulates sending random network packets as traps to Net-SNMP.
1 parent 03e28b6 commit 6861032

File tree

1 file changed

+138
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)