You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

442 lines
13 KiB

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3667900243c..337344e124d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -597,6 +597,7 @@ IF(WITH_JEMALLOC AND (WITH_TCMALLOC OR WITH_TCMALLOC_DEBUG))
MESSAGE(FATAL_ERROR "Specify only *one* of WITH_TCMALLOC and WITH_JEMALLOC")
ENDIF()
+OPTION(FUZZING "Fuzzing" OFF)
OPTION(ENABLED_PROFILING "Enable profiling" ON)
OPTION(WITHOUT_SERVER OFF)
@@ -1587,6 +1588,10 @@ IF(NOT WITHOUT_SERVER AND WITH_UNIT_TESTS)
TARGET_LINK_LIBRARIES(server_unittest_library ${ICU_LIBRARIES})
ENDIF()
+IF (FUZZING)
+ ADD_SUBDIRECTORY(fuzz)
+ENDIF()
+
# scripts/mysql_config depends on client and server targets loaded above.
# It is referenced by some of the directories below, so we insert it here.
ADD_SUBDIRECTORY(scripts)
diff --git a/include/mysql.h b/include/mysql.h
index b805bffdf88..23d2311299e 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -262,7 +262,8 @@ enum mysql_protocol_type {
MYSQL_PROTOCOL_TCP,
MYSQL_PROTOCOL_SOCKET,
MYSQL_PROTOCOL_PIPE,
- MYSQL_PROTOCOL_MEMORY
+ MYSQL_PROTOCOL_MEMORY,
+ MYSQL_PROTOCOL_FUZZ
};
enum mysql_ssl_mode {
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index ce785802ad9..4f048082335 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -485,7 +485,8 @@ enum mysql_protocol_type {
MYSQL_PROTOCOL_TCP,
MYSQL_PROTOCOL_SOCKET,
MYSQL_PROTOCOL_PIPE,
- MYSQL_PROTOCOL_MEMORY
+ MYSQL_PROTOCOL_MEMORY,
+ MYSQL_PROTOCOL_FUZZ
};
enum mysql_ssl_mode {
SSL_MODE_DISABLED = 1,
diff --git a/include/violite.h b/include/violite.h
index c04e82505a7..2498ba0053c 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -108,12 +108,14 @@ enum enum_vio_type : int {
*/
VIO_TYPE_PLUGIN = 7,
+ VIO_TYPE_FUZZ = 8,
+
FIRST_VIO_TYPE = VIO_TYPE_TCPIP,
/*
If a new type is added, please update LAST_VIO_TYPE. In addition, please
change get_vio_type_name() in vio/vio.c to return correct name for it.
*/
- LAST_VIO_TYPE = VIO_TYPE_PLUGIN
+ LAST_VIO_TYPE = VIO_TYPE_FUZZ
};
/**
@@ -444,4 +446,20 @@ struct Vio {
#define SSL_handle SSL *
+
+//Vio fuzzing
+bool vio_connect_fuzz(MYSQL_VIO vio, struct sockaddr *addr, socklen_t len,
+ int timeout);
+int vio_socket_timeout_fuzz(Vio *vio, uint which, bool b);
+void sock_initfuzz(const uint8_t *Data, size_t Size);
+size_t vio_read_buff_fuzz(Vio *vio, uchar *buf, size_t size);
+size_t vio_write_buff_fuzz(Vio *vio, const uchar *buf, size_t size);
+bool vio_is_connected_fuzz(Vio *vio);
+bool vio_was_timeout_fuzz(Vio *vio);
+int vio_shutdown_fuzz(Vio *vio);
+int vio_keepalive_fuzz(Vio *vio, bool set_keep_alive);
+int vio_io_wait_fuzz(Vio *vio, enum enum_vio_io_event event, int timeout);
+int vio_fastsend_fuzz(Vio *vio);
+bool vio_should_retry_fuzz(Vio *vio);
+
#endif /* vio_violite_h_ */
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index 4956a0dc2d8..bab0aa3b504 100644
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -353,11 +353,11 @@ IF(UNIX)
ADD_INSTALL_RPATH_FOR_OPENSSL(libmysql)
- IF(LINK_FLAG_Z_DEFS)
+ IF(LINK_FLAG_Z_DEFS AND NOT FUZZING)
MY_TARGET_LINK_OPTIONS(libmysql "LINKER:${LINK_FLAG_Z_DEFS}")
ENDIF()
- IF(LINUX)
+ IF(LINUX AND NOT FUZZING)
MY_TARGET_LINK_OPTIONS(libmysql
"LINKER:--version-script=${CMAKE_CURRENT_BINARY_DIR}/libmysql.ver")
ENDIF()
diff --git a/mysys/mf_tempfile.cc b/mysys/mf_tempfile.cc
index f4f5dffba9a..26ab2ce0917 100644
--- a/mysys/mf_tempfile.cc
+++ b/mysys/mf_tempfile.cc
@@ -320,6 +320,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
set_my_errno(ENAMETOOLONG);
return file;
}
+ sprintf(prefix_buff, "%sXXXXXX", prefix ? prefix : "tmp.");
my_stpcpy(convert_dirname(to, dir, NullS), prefix_buff);
file = mkstemp(to);
file_info::RegisterFilename(file, to, file_info::OpenType::FILE_BY_MKSTEMP);
diff --git a/mysys/my_rnd.cc b/mysys/my_rnd.cc
index 8253e3967d4..034c71de600 100644
--- a/mysys/my_rnd.cc
+++ b/mysys/my_rnd.cc
@@ -48,6 +48,9 @@
*/
double my_rnd(struct rand_struct *rand_st) {
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return 65.43;
+#endif
rand_st->seed1 = (rand_st->seed1 * 3 + rand_st->seed2) % rand_st->max_value;
rand_st->seed2 = (rand_st->seed1 + rand_st->seed2 + 33) % rand_st->max_value;
return (((double)rand_st->seed1) / rand_st->max_value_dbl);
@@ -64,6 +67,12 @@ Fill a buffer with random bytes using the SSL library routines
*/
int my_rand_buffer(unsigned char *buffer, size_t buffer_size) {
int rc;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ for (size_t i = 0; i < buffer_size; i++)
+ buffer[i] = i;
+ return 0;
+#endif
+
rc = RAND_bytes(buffer, (int)buffer_size);
if (!rc) {
@@ -85,6 +94,9 @@ int my_rand_buffer(unsigned char *buffer, size_t buffer_size) {
double my_rnd_ssl(bool *failed) {
unsigned int res;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return 34.56;
+#endif
if (my_rand_buffer((unsigned char *)&res, sizeof(res))) {
*failed = true;
return 0;
diff --git a/sql-common/client.cc b/sql-common/client.cc
index 61404be555b..721802cb60c 100644
--- a/sql-common/client.cc
+++ b/sql-common/client.cc
@@ -5774,6 +5774,12 @@ static mysql_state_machine_status csm_begin_connect(mysql_async_connect *ctx) {
}
}
#endif /* _WIN32 */
+if (!net->vio &&
+ (mysql->options.protocol == MYSQL_PROTOCOL_FUZZ)) {
+ net->vio =
+ vio_new(0, VIO_TYPE_FUZZ, 0);
+ ctx->host_info = (char *)ER_CLIENT(CR_LOCALHOST_CONNECTION);
+}
#if defined(HAVE_SYS_UN_H)
if (!net->vio &&
(!mysql->options.protocol ||
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 519926135ed..db75dc7f5e5 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -6862,7 +6862,9 @@ int mysqld_main(int argc, char **argv)
unireg_abort(MYSQLD_ABORT_EXIT); // Will do exit
}
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
my_init_signals();
+#endif
size_t guardize = 0;
#ifndef _WIN32
@@ -7347,8 +7349,10 @@ int mysqld_main(int argc, char **argv)
unireg_abort(MYSQLD_ABORT_EXIT);
#ifndef _WIN32
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
// Start signal handler thread.
start_signal_handler();
+#endif
#endif
/* set all persistent options */
@@ -7393,8 +7397,9 @@ int mysqld_main(int argc, char **argv)
}
start_handle_manager();
-
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
create_compress_gtid_table_thread();
+#endif
LogEvent()
.type(LOG_TYPE_ERROR)
@@ -7441,6 +7446,10 @@ int mysqld_main(int argc, char **argv)
(void)RUN_HOOK(server_state, before_handle_connection, (nullptr));
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return 0;
+#endif
+
#if defined(_WIN32)
if (mysqld_socket_acceptor != nullptr)
mysqld_socket_acceptor->check_and_spawn_admin_connection_handler_thread();
@@ -10281,6 +10290,9 @@ static int get_options(int *argc_ptr, char ***argv_ptr) {
if (opt_short_log_format) opt_specialflag |= SPECIAL_SHORT_LOG_FORMAT;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ Connection_handler_manager::thread_handling = Connection_handler_manager::SCHEDULER_NO_THREADS;
+#endif
if (Connection_handler_manager::init()) {
LogErr(ERROR_LEVEL, ER_CONNECTION_HANDLING_OOM);
return 1;
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index fba0684f322..8352dacbc03 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -1487,18 +1487,14 @@ dberr_t buf_pool_init(ulint total_size, ulint n_instances) {
n = n_instances;
}
- std::vector<std::thread> threads;
-
std::mutex m;
for (ulint id = i; id < n; ++id) {
- threads.emplace_back(std::thread(buf_pool_create, &buf_pool_ptr[id], size,
- id, &m, std::ref(errs[id])));
+ buf_pool_create(&buf_pool_ptr[id], size,
+ id, &m, std::ref(errs[id]));
}
for (ulint id = i; id < n; ++id) {
- threads[id - i].join();
-
if (errs[id] != DB_SUCCESS) {
err = errs[id];
}
diff --git a/vio/CMakeLists.txt b/vio/CMakeLists.txt
index d44eebce63a..975bc878e17 100644
--- a/vio/CMakeLists.txt
+++ b/vio/CMakeLists.txt
@@ -27,6 +27,7 @@ SET(VIO_SOURCES
viosocket.cc
viossl.cc
viosslfactories.cc
+ viofuzz.cc
)
IF(WIN32)
diff --git a/vio/vio.cc b/vio/vio.cc
index 38e3d90f20e..abbc9a52478 100644
--- a/vio/vio.cc
+++ b/vio/vio.cc
@@ -284,6 +284,26 @@ static bool vio_init(Vio *vio, enum enum_vio_type type, my_socket sd,
vio->is_blocking_flag = true;
break;
+ case VIO_TYPE_FUZZ:
+ vio->viodelete = vio_delete;
+ vio->vioerrno = vio_errno;
+ vio->read = vio_read_buff_fuzz;
+ vio->write = vio_write_buff_fuzz;
+ vio->fastsend = vio_fastsend_fuzz;
+ vio->viokeepalive = vio_keepalive_fuzz;
+ vio->should_retry = vio_should_retry_fuzz;
+ vio->was_timeout = vio_was_timeout_fuzz;
+ vio->vioshutdown = vio_shutdown_fuzz;
+ vio->peer_addr = vio_peer_addr;
+ vio->timeout = vio_socket_timeout_fuzz;
+ vio->io_wait = vio_io_wait_fuzz;
+ vio->is_connected = vio_is_connected_fuzz;
+ vio->has_data = vio->read_buffer ? vio_buff_has_data : has_no_data;
+ vio->is_blocking = vio_is_blocking;
+ vio->set_blocking = vio_set_blocking;
+ vio->set_blocking_flag = vio_set_blocking_flag;
+ vio->is_blocking_flag = false;
+
default:
vio->viodelete = vio_delete;
vio->vioerrno = vio_errno;
@@ -568,7 +588,8 @@ static const vio_string vio_type_names[] = {{"", 0},
{STRING_WITH_LEN("SSL/TLS")},
{STRING_WITH_LEN("Shared Memory")},
{STRING_WITH_LEN("Internal")},
- {STRING_WITH_LEN("Plugin")}};
+ {STRING_WITH_LEN("Plugin")},
+ {STRING_WITH_LEN("Fuzz")}};
void get_vio_type_name(enum enum_vio_type vio_type, const char **str,
int *len) {
diff --git a/vio/viofuzz.cc b/vio/viofuzz.cc
new file mode 100644
index 00000000000..83f22a5dbb9
--- /dev/null
+++ b/vio/viofuzz.cc
@@ -0,0 +1,124 @@
+
+#include "my_config.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <time.h>
+#ifndef _WIN32
+#include <netdb.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "my_compiler.h"
+#include "my_dbug.h"
+#include "my_inttypes.h"
+#include "my_io.h"
+#include "my_macros.h"
+#include "vio/vio_priv.h"
+
+#ifdef FIONREAD_IN_SYS_FILIO
+#include <sys/filio.h>
+#endif
+#ifndef _WIN32
+#include <netinet/tcp.h>
+#endif
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+static const uint8_t *fuzzBuffer;
+static size_t fuzzSize;
+static size_t fuzzPos;
+
+
+void sock_initfuzz(const uint8_t *Data, size_t Size) {
+ fuzzPos = 0;
+ fuzzSize = Size;
+ fuzzBuffer = Data;
+}
+
+bool vio_connect_fuzz(Vio *vio, struct sockaddr *addr, socklen_t len,
+ int timeout) {
+ DBUG_ENTER("vio_socket_connect");
+
+ /* Only for socket-based transport types. */
+ DBUG_ASSERT(vio->type == VIO_TYPE_SOCKET || vio->type == VIO_TYPE_TCPIP);
+
+ /* Initiate the connection. */
+ return 0;
+}
+
+
+int vio_socket_timeout_fuzz(Vio *vio, uint which, bool b) {
+ DBUG_ENTER("vio_socket_timeout_fuzz\n");
+ return 0;
+}
+
+
+size_t vio_read_buff_fuzz(Vio *vio, uchar *bufp, size_t size) {
+ DBUG_ENTER("vio_read_buff_fuzz.\n");
+ if (size > fuzzSize - fuzzPos) {
+ size = fuzzSize - fuzzPos;
+ }
+ if (fuzzPos < fuzzSize) {
+ memcpy(bufp, fuzzBuffer + fuzzPos, size);
+ }
+ fuzzPos += size;
+#ifdef FUZZ_DEBUG
+ printf("net cli %zu ", size);
+ for (size_t i=0; i<size; i++)
+ printf("%02x ", bufp[i]);
+ printf("\n");
+#endif //FUZZ_DEBUG
+ return size;
+}
+
+size_t vio_write_buff_fuzz(Vio *vio, const uchar *bufp, size_t size) {
+ DBUG_ENTER("vio_write_buff_fuzz\n");
+#ifdef FUZZ_DEBUG
+ printf("net srv %zu ", size);
+ for (size_t i=0; i<size; i++)
+ printf("%02x ", bufp[i]);
+ printf("\n");
+#endif //FUZZ_DEBUG
+ return size;
+}
+
+bool vio_is_connected_fuzz(Vio *vio) {
+ DBUG_ENTER("vio_is_connected_fuzz\n");
+ return (fuzzPos < fuzzSize);
+}
+
+bool vio_was_timeout_fuzz(Vio *vio) {
+ DBUG_ENTER("vio_was_timeout_fuzz\n");
+ return false;
+}
+
+int vio_shutdown_fuzz(Vio *vio) {
+ DBUG_ENTER("vio_shutdown_fuzz");
+ return 0;
+}
+
+int vio_keepalive_fuzz(Vio *vio, bool set_keep_alive) {
+ DBUG_ENTER("vio_keepalive_fuzz\n");
+ return 0;
+}
+int vio_io_wait_fuzz(Vio *vio, enum enum_vio_io_event event, int timeout) {
+ DBUG_ENTER("vio_io_wait_fuzz");
+ return 1;
+}
+
+int vio_fastsend_fuzz(Vio *vio) {
+ DBUG_ENTER("vio_fastsend_fuzz\n");
+ return 0;
+}
+
+bool vio_should_retry_fuzz(Vio *vio) {
+ DBUG_ENTER("vio_should_retry_fuzz\n");
+ return (fuzzPos < fuzzSize);
+}