Skip to content

Commit

Permalink
Fuzz: Add fuzzers to allow packet handling to get greater coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
ralight committed Nov 20, 2024
1 parent b9e1c5e commit 0244223
Show file tree
Hide file tree
Showing 10 changed files with 432 additions and 66 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ fuzzing/apps/db_dump/db_dump_fuzz_load_client_stats
fuzzing/apps/db_dump/db_dump_fuzz_load_stats
fuzzing/apps/mosquitto_passwd/mosquitto_passwd_fuzz_load
fuzzing/broker/broker_fuzz_acl_file
fuzzing/broker/broker_fuzz_handle_auth
fuzzing/broker/broker_fuzz_handle_connect
fuzzing/broker/broker_fuzz_handle_publish
fuzzing/broker/broker_fuzz_handle_subscribe
fuzzing/broker/broker_fuzz_handle_unsubscribe
fuzzing/broker/broker_fuzz_initial_packet
fuzzing/broker/broker_fuzz_initial_packet_with_init
fuzzing/broker/broker_fuzz_password_file
Expand All @@ -62,6 +67,7 @@ fuzzing/broker/broker_fuzz_read_handle
fuzzing/broker/broker_fuzz_second_packet
fuzzing/broker/broker_fuzz_second_packet_with_init
fuzzing/broker/broker_fuzz_test_config

fuzzing/corpora/broker/*
fuzzing/corpora/broker_packet_seed_corpus.zip
fuzzing/corpora/client/*
Expand Down
22 changes: 18 additions & 4 deletions fuzzing/broker/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,21 @@ LOCAL_CXXFLAGS+=-g -Wall -Werror -pthread
LOCAL_LDFLAGS+=
LOCAL_LIBADD+=$(LIB_FUZZING_ENGINE) ${R}/src/mosquitto_broker.a -lssl -lcrypto -lcjson -lm ${R}/libcommon/libmosquitto_common.a -Wl,-Bdynamic -Wl,-Bstatic -largon2 -Wl,-Bdynamic

all: $(FUZZERS)
PACKET_FUZZERS:= \
broker_fuzz_handle_auth \
broker_fuzz_handle_connect \
broker_fuzz_handle_publish \
broker_fuzz_handle_subscribe \
broker_fuzz_handle_unsubscribe

all: $(FUZZERS) $(PACKET_FUZZERS)

${PACKET_FUZZERS} : %: %.cpp fuzz_packet_read_base.o ${R}/src/mosquitto_broker.a
$(CXX) $(LOCAL_CXXFLAGS) $(LOCAL_CPPFLAGS) $(LOCAL_LDFLAGS) -o $@ $< fuzz_packet_read_base.o $(LOCAL_LIBADD)
install $@ ${OUT}/$@

fuzz_packet_read_base.o : fuzz_packet_read_base.c
$(CC) $(LOCAL_CXXFLAGS) $(LOCAL_CPPFLAGS) -c -o $@ $<

broker_fuzz_acl_file : broker_fuzz_acl_file.cpp ${R}/src/mosquitto_broker.a
$(CXX) $(LOCAL_CXXFLAGS) $(LOCAL_CPPFLAGS) $(LOCAL_LDFLAGS) -o $@ $< $(LOCAL_LIBADD)
Expand All @@ -42,8 +56,8 @@ broker_fuzz_queue_msg : broker_fuzz_queue_msg.cpp ${R}/src/mosquitto_broker.a
install $@ ${OUT}/$@
cp ${R}/fuzzing/corpora/broker_queue_msg_seed_corpus.zip ${OUT}/$@_seed_corpus.zip

broker_fuzz_read_handle : broker_fuzz_read_handle.cpp ${R}/src/mosquitto_broker.a
$(CXX) $(LOCAL_CXXFLAGS) $(LOCAL_CPPFLAGS) $(LOCAL_LDFLAGS) -o $@ $< $(LOCAL_LIBADD)
broker_fuzz_read_handle : broker_fuzz_read_handle.cpp fuzz_packet_read_base.o ${R}/src/mosquitto_broker.a
$(CXX) $(LOCAL_CXXFLAGS) $(LOCAL_CPPFLAGS) $(LOCAL_LDFLAGS) -o $@ $^ $(LOCAL_LIBADD)
install $@ ${OUT}/$@
cp ${R}/fuzzing/corpora/broker_packet_seed_corpus.zip ${OUT}/$@_seed_corpus.zip

Expand All @@ -54,4 +68,4 @@ broker_fuzz_test_config : broker_fuzz_test_config.cpp ${R}/src/mosquitto_broker.
cp ${R}/fuzzing/corpora/broker_conf.dict ${OUT}/$@.dict

clean:
rm -f *.o $(FUZZERS)
rm -f *.o $(FUZZERS) $(PACKET_FUZZERS)
38 changes: 38 additions & 0 deletions fuzzing/broker/broker_fuzz_handle_auth.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
Copyright (c) 2023 Cedalo GmbH
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
https://www.eclipse.org/legal/epl-2.0/
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
Contributors:
Roger Light - initial implementation and documentation.
*/

#include "fuzz_packet_read_base.h"

extern "C" int fuzz_packet_read_init(struct mosquitto *context)
{
context->protocol = mosq_p_mqtt5;
context->auth_method = strdup("FUZZ");
return !context->auth_method;
}

extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
{
free(context->auth_method);
context->auth_method = NULL;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
int rc = fuzz_packet_read_base(data, size, handle__auth);
return rc;
}
59 changes: 59 additions & 0 deletions fuzzing/broker/broker_fuzz_handle_connect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Copyright (c) 2023 Cedalo GmbH
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
https://www.eclipse.org/legal/epl-2.0/
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
Contributors:
Roger Light - initial implementation and documentation.
*/

#include "fuzz_packet_read_base.h"

extern "C" int fuzz_basic_auth(int event, void *event_data, void *userdata)
{
struct mosquitto_evt_basic_auth *ed = (struct mosquitto_evt_basic_auth *)event_data;

/* This is a check that is ultimately determined by the fuzz input data, so
* the fuzzer can discover how to access both the fail/success cases.
*/
if(ed->client->id && (ed->client->id[0]%2 == 0)){
return MOSQ_ERR_SUCCESS;
}else{
return MOSQ_ERR_AUTH;
}
}

extern "C" int fuzz_packet_read_init(struct mosquitto *context)
{
context->listener->security_options->pid = (mosquitto_plugin_id_t *)calloc(1, sizeof(mosquitto_plugin_id_t));
if(!context->listener->security_options->pid){
return 1;
}
mosquitto_callback_register(context->listener->security_options->pid,
MOSQ_EVT_BASIC_AUTH, fuzz_basic_auth, NULL, NULL);

return 0;
}

extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
{
mosquitto_callback_unregister(context->listener->security_options->pid,
MOSQ_EVT_BASIC_AUTH, fuzz_basic_auth, NULL);

free(context->listener->security_options->pid);
context->listener->security_options->pid = NULL;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
return fuzz_packet_read_base(data, size, handle__connect);
}
59 changes: 59 additions & 0 deletions fuzzing/broker/broker_fuzz_handle_publish.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Copyright (c) 2023 Cedalo GmbH
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
https://www.eclipse.org/legal/epl-2.0/
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
Contributors:
Roger Light - initial implementation and documentation.
*/

#include "fuzz_packet_read_base.h"

extern "C" int fuzz_acl_check(int event, void *event_data, void *userdata)
{
struct mosquitto_evt_acl_check *ed = (struct mosquitto_evt_acl_check *)event_data;

/* This is a check that is ultimately determined by the fuzz input data, so
* the fuzzer can discover how to access both the fail/success cases.
*/
if(ed->topic && (ed->topic[0]%2 == 0)){
return MOSQ_ERR_SUCCESS;
}else{
return MOSQ_ERR_AUTH;
}
}

extern "C" int fuzz_packet_read_init(struct mosquitto *context)
{
context->listener->security_options->pid = (mosquitto_plugin_id_t *)calloc(1, sizeof(mosquitto_plugin_id_t));
if(!context->listener->security_options->pid){
return 1;
}
mosquitto_callback_register(context->listener->security_options->pid,
MOSQ_EVT_ACL_CHECK, fuzz_acl_check, NULL, NULL);

return 0;
}

extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
{
mosquitto_callback_unregister(context->listener->security_options->pid,
MOSQ_EVT_ACL_CHECK, fuzz_acl_check, NULL);

free(context->listener->security_options->pid);
context->listener->security_options->pid = NULL;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
return fuzz_packet_read_base(data, size, handle__publish);
}
59 changes: 59 additions & 0 deletions fuzzing/broker/broker_fuzz_handle_subscribe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Copyright (c) 2023 Cedalo GmbH
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
https://www.eclipse.org/legal/epl-2.0/
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
Contributors:
Roger Light - initial implementation and documentation.
*/

#include "fuzz_packet_read_base.h"

extern "C" int fuzz_acl_check(int event, void *event_data, void *userdata)
{
struct mosquitto_evt_acl_check *ed = (struct mosquitto_evt_acl_check *)event_data;

/* This is a check that is ultimately determined by the fuzz input data, so
* the fuzzer can discover how to access both the fail/success cases.
*/
if(ed->topic && (ed->topic[0]%2 == 0)){
return MOSQ_ERR_SUCCESS;
}else{
return MOSQ_ERR_AUTH;
}
}

extern "C" int fuzz_packet_read_init(struct mosquitto *context)
{
context->listener->security_options->pid = (mosquitto_plugin_id_t *)calloc(1, sizeof(mosquitto_plugin_id_t));
if(!context->listener->security_options->pid){
return 1;
}
mosquitto_callback_register(context->listener->security_options->pid,
MOSQ_EVT_ACL_CHECK, fuzz_acl_check, NULL, NULL);

return 0;
}

extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
{
mosquitto_callback_unregister(context->listener->security_options->pid,
MOSQ_EVT_ACL_CHECK, fuzz_acl_check, NULL);

free(context->listener->security_options->pid);
context->listener->security_options->pid = NULL;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
return fuzz_packet_read_base(data, size, handle__subscribe);
}
59 changes: 59 additions & 0 deletions fuzzing/broker/broker_fuzz_handle_unsubscribe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Copyright (c) 2023 Cedalo GmbH
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
https://www.eclipse.org/legal/epl-2.0/
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
Contributors:
Roger Light - initial implementation and documentation.
*/

#include "fuzz_packet_read_base.h"

extern "C" int fuzz_acl_check(int event, void *event_data, void *userdata)
{
struct mosquitto_evt_acl_check *ed = (struct mosquitto_evt_acl_check *)event_data;

/* This is a check that is ultimately determined by the fuzz input data, so
* the fuzzer can discover how to access both the fail/success cases.
*/
if(ed->topic && (ed->topic[0]%2 == 0)){
return MOSQ_ERR_SUCCESS;
}else{
return MOSQ_ERR_AUTH;
}
}

extern "C" int fuzz_packet_read_init(struct mosquitto *context)
{
context->listener->security_options->pid = (mosquitto_plugin_id_t *)calloc(1, sizeof(mosquitto_plugin_id_t));
if(!context->listener->security_options->pid){
return 1;
}
mosquitto_callback_register(context->listener->security_options->pid,
MOSQ_EVT_ACL_CHECK, fuzz_acl_check, NULL, NULL);

return 0;
}

extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
{
mosquitto_callback_unregister(context->listener->security_options->pid,
MOSQ_EVT_ACL_CHECK, fuzz_acl_check, NULL);

free(context->listener->security_options->pid);
context->listener->security_options->pid = NULL;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
return fuzz_packet_read_base(data, size, handle__unsubscribe);
}
Loading

0 comments on commit 0244223

Please sign in to comment.