aboutsummaryrefslogtreecommitdiffstats
path: root/fuzz/CMakeLists.txt
blob: 9e9598badc3e726dc00d73fdc85ee1f9827c18bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# CMakeLists.txt
#
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# Copyright 1998 Gerald Combs
#
# SPDX-License-Identifier: GPL-2.0-or-later
#

# List of dissectors compiled below, which should be turned off.
# This is done to avoid single fuzzer (like IP) to call UDP protocols, which can go back to IP, and so on..
# While doing so might find some bugs, but it's likely to be the problem for too big corpus in oss-fuzzer
# (see: https://github.com/google/oss-fuzz/issues/1087).
# + udplite - it's sharing most of code with UDP.
set(FUZZ_DISABLED_DISSECTORS ip udp udplite ospf bgp dhcp json)

set(FUZZ_DISSECTORS ip)
set(FUZZ_IP_PROTO_DISSECTORS udp ospf)

set(FUZZ_TCP_PORT_DISSECTORS bgp)
# list(APPEND FUZZ_TCP_PORT_DISSECTORS bzr)     # disabled, cause of known problem.
# list(APPEND FUZZ_TCP_PORT_DISSECTORS echo)    # disabled, too simple.

set(FUZZ_UDP_PORT_DISSECTORS dns dhcp)
# list(FUZZ_UDP_PORT_DISSECTORS bfd)            # disabled, too simple.

set(FUZZ_MEDIA_TYPE_DISSECTORS json)

set(fuzzshark_LIBS
	ui
	wiretap
	epan
	${VERSION_INFO_LIBS}
)
if(OSS_FUZZ)
	if("$ENV{LIB_FUZZING_ENGINE}" STREQUAL "")
		message(FATAL_ERROR "LIB_FUZZING_ENGINE is not set!")
	endif()
	list(APPEND fuzzshark_LIBS $ENV{LIB_FUZZING_ENGINE})
endif()
set(fuzzshark_FILES
	fuzzshark.c
	$<TARGET_OBJECTS:version_info>
)
set(FUZZ_LINK_FLAGS "${WS_LINK_FLAGS}")
if(ENABLE_FUZZER)
	set(FUZZ_LINK_FLAGS "${FUZZ_LINK_FLAGS} -fsanitize=fuzzer")
endif()
if(OSS_FUZZ)
	# libFuzzingEngine.a is not position independent, so cannot use -pie.
	set(FUZZ_LINK_FLAGS "${FUZZ_LINK_FLAGS} -no-pie")
endif()

# Convert the list of disabled dissectors from a;b;c -> "a", "b", "c"
# for use in fuzzshark.c (macro)
string(REGEX REPLACE "([^;]+)" "\"\\1\"" FUZZ_DISABLED_DISSECTORS_MACRO "${FUZZ_DISABLED_DISSECTORS}")
string(REPLACE ";" ", " FUZZ_DISABLED_DISSECTORS_MACRO "${FUZZ_DISABLED_DISSECTORS_MACRO}")

# Targets that are build via all-fuzzers:
# - fuzzshark: a non-specific fuzz target, configurable through env vars (requires BUILD_fuzzshark)
# - fuzzshark_<target>: fuzz target for a specific dissector target.
# - fuzzshark_<table>-<target>: fuzz target for a specific dissector via a dissector table.
add_custom_target(all-fuzzers)

function(fuzzshark_set_common_options fuzzer_name)
	# Sanitizers require a C++ runtime, so use a C++ linker.
	set_target_properties(${fuzzer_name} PROPERTIES
		FOLDER "Fuzzers"
		LINK_FLAGS "${FUZZ_LINK_FLAGS}"
		LINKER_LANGUAGE "CXX"
	)
	target_link_libraries(${fuzzer_name} ${fuzzshark_LIBS})
	add_dependencies(all-fuzzers ${fuzzer_name})
endfunction()

if(BUILD_fuzzshark)
	if(NOT (ENABLE_FUZZER OR OSS_FUZZ))
		# libFuzzer includes a main routine that enables fuzzing. If
		# support for fuzzing was not enabled, add a small standalone
		# target that can be used to test-compile fuzzshark.c.
		list(APPEND fuzzshark_FILES StandaloneFuzzTargetMain.c)
	endif()
	add_executable(fuzzshark ${fuzzshark_FILES})
	fuzzshark_set_common_options(fuzzshark)
endif()

# Create a new dissector fuzzer target.
# If <dissector_table> is empty, <name> will be called directly.
# If <dissector_table> is non-empty, a dissector with filter name <name> will be
# looked up in dissector table <dissector_table>.
function(generate_fuzzer dissector_table name)
	if(NOT (ENABLE_FUZZER OR OSS_FUZZ))
		return()
	endif()

	if(dissector_table STREQUAL "")
		set(fuzzer_name fuzzshark_${name})
	else()
		# "ip.proto" and "udp" -> "ip_proto-udp"
		set(fuzzer_name fuzzshark_${dissector_table}-${name})
		string(REPLACE "." "_" fuzzer_name ${fuzzer_name})
	endif()

	add_executable(${fuzzer_name} EXCLUDE_FROM_ALL ${fuzzshark_FILES})
	fuzzshark_set_common_options(${fuzzer_name})
	target_compile_definitions(${fuzzer_name} PRIVATE
		FUZZ_DISSECTOR_LIST=${FUZZ_DISABLED_DISSECTORS_MACRO}
		FUZZ_DISSECTOR_TARGET="${name}"
	)
	if(NOT dissector_table STREQUAL "")
		target_compile_definitions(${fuzzer_name} PRIVATE
			FUZZ_DISSECTOR_TABLE="${dissector_table}")
	endif()
endfunction()

# Add fuzzer targets for every dissector in list FUZZ_<table-var>_DISSECTORS,
# where <table-var> changes a <table> such as "ip.proto" into "IP_PROTO".
function(add_table_fuzzers table)
	string(REPLACE "." "_" table_var ${table})
	string(TOUPPER "${table_var}" table_var)
	foreach(dissector IN LISTS FUZZ_${table_var}_DISSECTORS)
		generate_fuzzer(${table} ${dissector})
	endforeach()
endfunction()

foreach(dissector IN LISTS FUZZ_DISSECTORS)
	generate_fuzzer("" ${dissector})
endforeach()

add_table_fuzzers("ip.proto")
add_table_fuzzers("tcp.port")
add_table_fuzzers("udp.port")
add_table_fuzzers("media_type")

#
# Editor modelines  -  https://www.wireshark.org/tools/modelines.html
#
# Local variables:
# c-basic-offset: 8
# tab-width: 8
# indent-tabs-mode: t
# End:
#
# vi: set shiftwidth=8 tabstop=8 noexpandtab:
# :indentSize=8:tabSize=8:noTabs=false:
#