Skip to content

Commit fb683a6

Browse files
committed
uri_parser: Add URI parser fuzz testing based on libFuzzer
Change-Id: Id5f5bce49bcdc3beb21e49599261355f982aabd1
1 parent 0a6c9cf commit fb683a6

File tree

397 files changed

+727
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

397 files changed

+727
-2
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ source_downloads
77
unittest/traces
88
mysqlshdk/libs/db/mysqlx/xpl_error.h
99
/build/
10+
tests/fuzz/corpus/**

CMakeLists.txt

+6-2
Original file line numberDiff line numberDiff line change
@@ -239,22 +239,25 @@ IF(NOT PACKAGE_YEAR)
239239
ENDIF()
240240
add_definitions(-DPACKAGE_YEAR="${PACKAGE_YEAR}")
241241

242+
IF(WITH_TESTS)
243+
ENABLE_TESTING()
244+
ENDIF()
245+
242246
###
243247
### Initial configuration
244248
###
245-
246249
INCLUDE(version.cmake)
247250

248251
###
249252
### Detect Stuff
250253
###
251-
252254
INCLUDE(install_macros)
253255
INCLUDE(exeutils)
254256
INCLUDE(libutils)
255257
INCLUDE(compiler)
256258
INCLUDE(static_analysis)
257259
include(cmake/compile_flags.cmake)
260+
include(cmake/fuzzer.cmake)
258261
INCLUDE(msvc)
259262

260263
INCLUDE(CheckIncludeFiles)
@@ -689,6 +692,7 @@ IF(WITH_TESTS)
689692
### Unit-test support
690693
###
691694
add_subdirectory(unittest)
695+
add_subdirectory(tests/fuzz)
692696
ENDIF()
693697

694698
###

cmake/fuzzer.cmake

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# Copyright (c) 2017, 2020, Oracle and/or its affiliates.
2+
#
3+
# This program is free software; you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License, version 2.0,
5+
# as published by the Free Software Foundation.
6+
#
7+
# This program is also distributed with certain software (including
8+
# but not limited to OpenSSL) that is licensed under separate terms,
9+
# as designated in a particular file or component or in included license
10+
# documentation. The authors of MySQL hereby grant you an additional
11+
# permission to link the program and your derivative works with the
12+
# separately licensed software that they have included with MySQL.
13+
#
14+
# This program is distributed in the hope that it will be useful,
15+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
# GNU General Public License for more details.
18+
#
19+
# You should have received a copy of the GNU General Public License
20+
# along with this program; if not, write to the Free Software
21+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22+
23+
INCLUDE(CMakePushCheckState)
24+
25+
# Only supported for Clang/llvm
26+
IF(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
27+
RETURN()
28+
ENDIF()
29+
30+
# ld.lld: error:
31+
# /usr/lib64/clang/7.0.1/lib/linux/libclang_rt.fuzzer-x86_64.a
32+
# (FuzzerLoop.cpp.o): unsupported SHT_GROUP format
33+
IF(USE_LD_LLD AND C_LD_LLD_RESULT AND CXX_LD_LLD_RESULT)
34+
STRING(REPLACE "-fuse-ld=lld" ""
35+
CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS})
36+
STRING(REPLACE "-fuse-ld=lld" ""
37+
CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS})
38+
STRING(REPLACE "-Wl,--gdb-index" ""
39+
CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS})
40+
STRING(REPLACE "-Wl,--gdb-index" ""
41+
CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS})
42+
ENDIF()
43+
44+
# check if clang knows about the coverage and trace-pc-guard
45+
#
46+
# compiler | CFLAGS | LDFLAGS
47+
# ----------|------------------------------------|------------------
48+
# llvm 6.0+ | -fsanitize=fuzzer | -fsanitize=fuzzer
49+
# llvm 4.0 | -fsanitize-coverage=trace-pc-guard | -lFuzzer
50+
# llvm 3.9 | -fsanitize-coverage=trace-cmp | -lFuzzer
51+
# llvm 3.7 | -fsanitize-coverage=edge | -lFuzzer
52+
53+
# llvm 4.0+
54+
CMAKE_PUSH_CHECK_STATE(RESET)
55+
SET(CMAKE_REQUIRED_FLAGS "-fsanitize-coverage=trace-pc-guard")
56+
CHECK_CXX_COMPILER_FLAG("-fsanitize-coverage=trace-pc-guard"
57+
COMPILER_HAS_SANITIZE_COVERAGE_TRACE_PC_GUARD)
58+
CMAKE_POP_CHECK_STATE()
59+
60+
# llvm 3.8+
61+
CMAKE_PUSH_CHECK_STATE(RESET)
62+
SET(CMAKE_REQUIRED_FLAGS "-fsanitize-coverage=edge")
63+
CHECK_CXX_COMPILER_FLAG("-fsanitize-coverage=edge"
64+
COMPILER_HAS_SANITIZE_COVERAGE_TRACE_EDGE)
65+
CMAKE_POP_CHECK_STATE()
66+
67+
# http://llvm.org/docs/LibFuzzer.html#tracing-cmp-instructions
68+
CMAKE_PUSH_CHECK_STATE(RESET)
69+
SET(CMAKE_REQUIRED_FLAGS "-fsanitize-coverage=trace-cmp")
70+
CHECK_CXX_COMPILER_FLAG("-fsanitize-coverage=trace-cmp"
71+
COMPILER_HAS_SANITIZE_COVERAGE_TRACE_CMP)
72+
CMAKE_POP_CHECK_STATE()
73+
74+
CMAKE_PUSH_CHECK_STATE(RESET)
75+
SET(CMAKE_REQUIRED_FLAGS "-fprofile-instr-generate")
76+
CHECK_CXX_COMPILER_FLAG("-fprofile-instr-generate"
77+
COMPILER_HAS_PROFILE_INSTR_GENERATE)
78+
CMAKE_POP_CHECK_STATE()
79+
80+
CMAKE_PUSH_CHECK_STATE(RESET)
81+
# invalid argument '-fcoverage-mapping' only allowed
82+
# with '-fprofile-instr-generate'
83+
SET(CMAKE_REQUIRED_FLAGS "-fprofile-instr-generate")
84+
CHECK_CXX_COMPILER_FLAG("-fcoverage-mapping" COMPILER_HAS_COVERAGE_MAPPING)
85+
CMAKE_POP_CHECK_STATE()
86+
87+
CMAKE_PUSH_CHECK_STATE(RESET)
88+
SET(CMAKE_REQUIRED_LIBRARIES "-fsanitize=address,fuzzer")
89+
SET(CMAKE_REQUIRED_FLAGS "-fsanitize=address,fuzzer")
90+
CHECK_CXX_SOURCE_COMPILES("
91+
extern \"C\" int LLVMFuzzerTestOneInput (void *, int)
92+
{ return 0; }"
93+
COMPILER_HAS_SANITIZE_FUZZER)
94+
CMAKE_POP_CHECK_STATE()
95+
96+
97+
IF(COMPILER_HAS_SANITIZE_FUZZER)
98+
SET(SANITIZE_COVERAGE_FLAGS "-fsanitize=address,fuzzer")
99+
ELSEIF(COMPILER_HAS_SANITIZE_COVERAGE_TRACE_PC_GUARD)
100+
SET(SANITIZE_COVERAGE_FLAGS "-fsanitize-coverage=trace-pc-guard")
101+
ELSEIF(COMPILER_HAS_SANITIZE_COVERAGE_TRACE_CMP)
102+
SET(SANITIZE_COVERAGE_FLAGS "-fsanitize-coverage=trace-cmp")
103+
ELSEIF(COMPILER_HAS_SANITIZE_COVERAGE_TRACE_EDGE)
104+
SET(SANITIZE_COVERAGE_FLAGS "-fsanitize-coverage=edge")
105+
ELSE()
106+
MESSAGE(WARNING "Coverage is not supported. Skiping build fuzz tests.")
107+
ENDIF()
108+
109+
# check that libFuzzer is found
110+
#
111+
# check_library_exists() doesn't work here as it would provide a main() which
112+
# calls a test-function ... which collides with libFuzzer's main():
113+
#
114+
# if the libFuzzer is found by the compiler it will provide a 'main()' and
115+
# require that we provide a 'LLVMFuzzerTestOneInput' at link-time.
116+
IF(SANITIZE_COVERAGE_FLAGS)
117+
CMAKE_PUSH_CHECK_STATE(RESET)
118+
SET(CMAKE_REQUIRED_LIBRARIES Fuzzer)
119+
SET(CMAKE_REQUIRED_FLAGS ${SANITIZE_COVERAGE_FLAGS})
120+
CHECK_CXX_SOURCE_COMPILES("
121+
extern \"C\" int LLVMFuzzerTestOneInput (void *, int)
122+
{ return 0; }"
123+
CLANG_HAS_LIBFUZZER)
124+
CMAKE_POP_CHECK_STATE()
125+
ENDIF()
126+
127+
IF(COMPILER_HAS_SANITIZE_FUZZER OR CLANG_HAS_LIBFUZZER)
128+
IF(CLANG_HAS_LIBFUZZER)
129+
SET(LIBFUZZER_LIBRARIES Fuzzer)
130+
ENDIF()
131+
SET(LIBFUZZER_LINK_FLAGS ${SANITIZE_COVERAGE_FLAGS})
132+
SET(LIBFUZZER_COMPILE_FLAGS)
133+
LIST(APPEND LIBFUZZER_COMPILE_FLAGS ${SANITIZE_COVERAGE_FLAGS})
134+
135+
IF(COMPILER_HAS_PROFILE_INSTR_GENERATE)
136+
LIST(APPEND LIBFUZZER_COMPILE_FLAGS -fprofile-instr-generate)
137+
SET(LIBFUZZER_LINK_FLAGS
138+
"${LIBFUZZER_LINK_FLAGS} -fprofile-instr-generate")
139+
IF(COMPILER_HAS_COVERAGE_MAPPING)
140+
LIST(APPEND LIBFUZZER_COMPILE_FLAGS -fcoverage-mapping)
141+
ENDIF()
142+
ENDIF()
143+
ENDIF()
144+
145+
146+
FUNCTION(LIBFUZZER_ADD_TEST TARGET)
147+
SET(OPTS)
148+
SET(ONE_VAL_ARGS INITIAL_CORPUS_DIR MAX_TOTAL_TIME TIMEOUT)
149+
SET(MULTI_VAL_ARGS)
150+
CMAKE_PARSE_ARGUMENTS(ARG "${OPTS}" "${ONE_VAL_ARGS}" "${MULTI_VAL_ARGS}" ${ARGN})
151+
152+
153+
IF(NOT DEFINED ARG_MAX_TOTAL_TIME)
154+
SET(ARG_MAX_TOTAL_TIME 10)
155+
ENDIF()
156+
IF(NOT DEFINED ARG_TIMEOUT)
157+
SET(ARG_TIMEOUT 0.2)
158+
ENDIF()
159+
160+
SET(BINARY_CORPUS_DIR "${CMAKE_CURRENT_BINARY_DIR}/corpus/${TARGET}")
161+
SET(BINARY_ARTIFACT_DIR "${CMAKE_CURRENT_BINARY_DIR}/artifacts/${TARGET}")
162+
163+
SET_TARGET_PROPERTIES(
164+
${TARGET}
165+
PROPERTIES
166+
COMPILE_OPTIONS "${LIBFUZZER_COMPILE_FLAGS}"
167+
LINK_FLAGS "${LIBFUZZER_LINK_FLAGS}"
168+
)
169+
170+
IF(LIBFUZZER_LIBRARIES)
171+
TARGET_LINK_LIBRARIES(${TARGET} ${LIBFUZZER_LIBRARIES})
172+
ENDIF()
173+
174+
# reset the artifact and corpus dir if the binary changed.
175+
ADD_CUSTOM_COMMAND(TARGET ${TARGET}
176+
POST_BUILD
177+
COMMAND ${CMAKE_COMMAND} -E remove_directory "${BINARY_CORPUS_DIR}"
178+
COMMAND ${CMAKE_COMMAND} -E make_directory "${BINARY_CORPUS_DIR}"
179+
COMMAND ${CMAKE_COMMAND} -E remove_directory "${BINARY_ARTIFACT_DIR}"
180+
COMMAND ${CMAKE_COMMAND} -E make_directory "${BINARY_ARTIFACT_DIR}"
181+
)
182+
183+
IF(ARG_INITIAL_CORPUS_DIR)
184+
# prepare the corpus in the build-dir based on samples from the source-dir
185+
ADD_CUSTOM_COMMAND(TARGET ${TARGET}
186+
POST_BUILD
187+
COMMAND $<TARGET_FILE:${TARGET}>
188+
-merge=1
189+
-verbosity=0
190+
-merge_control_file="${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.control"
191+
"${ARG_INITIAL_CORPUS_DIR}" "${BINARY_CORPUS_DIR}" 2> /dev/null
192+
COMMENT "Preparing corpus for ${TARGET}"
193+
)
194+
ENDIF()
195+
196+
# use cmake -E env to set the LLVM_PROFILE_FILE in a portable way
197+
ADD_TEST(${TARGET}
198+
${CMAKE_BINARY_DIR}/bin/${TARGET}
199+
-max_total_time=${ARG_MAX_TOTAL_TIME} -timeout=${ARG_TIMEOUT}
200+
-artifact_prefix=${BINARY_ARTIFACT_DIR}/
201+
${BINARY_CORPUS_DIR}
202+
)
203+
ENDFUNCTION()

tests/fuzz/CMakeLists.txt

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright (c) 2020, Oracle and/or its affiliates.
2+
#
3+
# This program is free software; you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License, version 2.0,
5+
# as published by the Free Software Foundation.
6+
#
7+
# This program is also distributed with certain software (including
8+
# but not limited to OpenSSL) that is licensed under separate terms, as
9+
# designated in a particular file or component or in included license
10+
# documentation. The authors of MySQL hereby grant you an additional
11+
# permission to link the program and your derivative works with the
12+
# separately licensed software that they have included with MySQL.
13+
# This program is distributed in the hope that it will be useful, but
14+
# WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16+
# the GNU General Public License, version 2.0, for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License
19+
# along with this program; if not, write to the Free Software Foundation, Inc.,
20+
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21+
22+
function(add_fuzz_test fuzz_target)
23+
message(STATUS "target=${fuzz_target}, srcs=${ARGN}")
24+
25+
add_shell_executable("${fuzz_target}" "${ARGN}" TRUE)
26+
27+
TARGET_INCLUDE_DIRECTORIES("${fuzz_target}" PRIVATE
28+
${PROJECT_SOURCE_DIR}
29+
${PROJECT_SOURCE_DIR}/mysqlshdk/include
30+
${PROJECT_SOURCE_DIR}/mysqlshdk/libs
31+
)
32+
# Instead of compiling all *.cc files listed in fuzz_uri_parser_SRC we can
33+
# link libraries, but then we lose information about code coverage in
34+
# uri_parser.cc
35+
# target_link_libraries(fuzz_uri_parser db shellcore-minimal)
36+
LIBFUZZER_ADD_TEST(fuzz_uri_parser
37+
INITIAL_CORPUS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../corpus/fuzz_uri_parser)
38+
endfunction()
39+
40+
IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
41+
IF(LIBFUZZER_COMPILE_FLAGS)
42+
add_subdirectory(uri_parser)
43+
ENDIF()
44+
ENDIF()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
kg@[::ffff:192.168.1.120]:3308
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[fe80::8090:f18c:182c:ec91%25area51]:3008
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.1﻾1:37778/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.0.0.127:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.0.0.1:5010󠀲/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysql://user:@[fe80::a%25en1]:4002/db
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@󠁜4294967295.-52363856998860641595325061.
0.257:500/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.1.
0.1:-1/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.0.3.1:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.1.0.𝅘𝅥𝅮1:-520/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.0.0.0:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.0.0.32769:127/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@-8714292349336472560438111007379281.0.0.1:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.0.1.1:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@0.0.1.1:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.0.0.170141183460469231731687303715884105731:70547/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
my󠁰sqlx://root:@1ʴ.0.0.1:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@9223372036854775808.0.0.0:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://roo :@127.;.0.1:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mys󠀱qlx://root:@9223372036854775809.⁨0.��(�2147483647.129:1J4780817/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:ʲ@127.0.0.1:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@17.2147483648.0.9223372036854775554:15665/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://ro᠎ot:@127.0.0.1:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://roo󠁩t:@�270.32769.0:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@4294967296.32769.1.0󠀸:5011/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@103.240.󠀯0.340282366920938463463374607431768211457󠁪6:1/�chema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://󠁽root:@1ʲ27.4294967297.0.1��:3/sch3ma
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@1root:@127.2560ᅟ.1:109922/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.127.0.1:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.0.0.170141183460469231731687303715884105727:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@0.0.0.71895292:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@�-222.1.0:340282366920938463463374607431768211454/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@-14.0.0.1:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127.0.256.1:2127/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@127��0.257.󠀭0:5010/schema
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mysqlx://root:@�270.32769.0:5010/schema

0 commit comments

Comments
 (0)