mirror of https://github.com/google/oss-fuzz.git
[mysql] Initial integration for mysql server (#2593)
* Initial integration for mysql server
This commit is contained in:
parent
50390b7fb5
commit
276d4c7888
|
@ -0,0 +1,25 @@
|
|||
# Copyright 2018 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
FROM gcr.io/oss-fuzz-base/base-builder
|
||||
MAINTAINER secalert_us@oracle.com
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y build-essential libssl-dev libncurses5-dev libncursesw5-dev make cmake perl bison pkg-config
|
||||
RUN git clone --depth 1 https://github.com/mysql/mysql-server
|
||||
WORKDIR $SRC
|
||||
COPY build.sh $SRC/
|
||||
COPY fix.diff $SRC/
|
||||
COPY targets $SRC/mysql-server/fuzz
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
#!/bin/bash -eu
|
||||
# Copyright 2018 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
cd mysql-server
|
||||
git apply ../fix.diff
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DDOWNLOAD_BOOST=1 -DWITH_BOOST=$WORK -DWITH_SSL=system -DFUZZING=1 -DCMAKE_INSTALL_PREFIX=$OUT/mysql
|
||||
make install
|
||||
cp $OUT/mysql/bin/fuzz* $OUT/
|
||||
cp ../fuzz/fuzz*.options $OUT/
|
||||
cp ../fuzz/fuzz*.dict $OUT/
|
||||
cp ../fuzz/init.sql $OUT/
|
||||
|
||||
rm -Rf $OUT/mysql/data
|
||||
$OUT/mysql/bin/mysqld --user=root --initialize-insecure --log-error-verbosity=5 --datadir=$OUT/mysql/data --basedir=$OUT/mysql/
|
|
@ -0,0 +1,363 @@
|
|||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 758df9761e8..837a8c6b071 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -461,6 +461,7 @@ ENDIF()
|
||||
|
||||
OPTION(DISABLE_SHARED
|
||||
"Don't build shared libraries, compile code as position-dependent" OFF)
|
||||
+OPTION(FUZZING "Fuzzing" OFF)
|
||||
IF(DISABLE_SHARED)
|
||||
MESSAGE("Dynamic plugins are disabled.")
|
||||
ENDIF()
|
||||
@@ -1140,6 +1141,10 @@ IF(NOT WITHOUT_SERVER)
|
||||
ADD_SUBDIRECTORY(sql)
|
||||
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 561960cd925..a11ccb42299 100644
|
||||
--- a/include/mysql.h
|
||||
+++ b/include/mysql.h
|
||||
@@ -260,7 +260,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/violite.h b/include/violite.h
|
||||
index b0c5c6958ba..7ef140dc163 100644
|
||||
--- a/include/violite.h
|
||||
+++ b/include/violite.h
|
||||
@@ -106,12 +106,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
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -457,4 +459,20 @@ struct Vio {
|
||||
#define SSL_handle void *
|
||||
#endif
|
||||
|
||||
+
|
||||
+//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 2606e908124..20a80adcd5b 100644
|
||||
--- a/libmysql/CMakeLists.txt
|
||||
+++ b/libmysql/CMakeLists.txt
|
||||
@@ -319,7 +319,7 @@ IF(NOT DISABLE_SHARED)
|
||||
ENDIF()
|
||||
|
||||
GET_TARGET_PROPERTY(libmysql_link_flags libmysql LINK_FLAGS)
|
||||
- IF(LINK_FLAG_NO_UNDEFINED)
|
||||
+ IF(LINK_FLAG_NO_UNDEFINED AND NOT FUZZING)
|
||||
SET(libmysql_link_flags
|
||||
"${libmysql_link_flags} ${LINK_FLAG_NO_UNDEFINED}")
|
||||
SET(libmysql_link_flags
|
||||
diff --git a/mysys_ssl/my_rnd.cc b/mysys_ssl/my_rnd.cc
|
||||
index d4b3ec4b851..aaaf8bdb93c 100644
|
||||
--- a/mysys_ssl/my_rnd.cc
|
||||
+++ b/mysys_ssl/my_rnd.cc
|
||||
@@ -50,6 +50,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);
|
||||
@@ -66,6 +69,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) {
|
||||
@@ -89,6 +98,10 @@ int my_rand_buffer(unsigned char *buffer, size_t buffer_size) {
|
||||
double my_rnd_ssl(struct rand_struct *rand_st) {
|
||||
unsigned int res;
|
||||
|
||||
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
+ return 34.56;
|
||||
+#endif
|
||||
+
|
||||
if (my_rand_buffer((unsigned char *)&res, sizeof(res)))
|
||||
return my_rnd(rand_st);
|
||||
|
||||
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
|
||||
index 13479e3c474..5d165982fe6 100644
|
||||
--- a/sql/mysqld.cc
|
||||
+++ b/sql/mysqld.cc
|
||||
@@ -6124,7 +6124,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
|
||||
@@ -6598,8 +6600,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 */
|
||||
@@ -6771,6 +6775,10 @@ int mysqld_main(int argc, char **argv)
|
||||
|
||||
(void)RUN_HOOK(server_state, before_handle_connection, (NULL));
|
||||
|
||||
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
+ return 0;
|
||||
+#endif
|
||||
+
|
||||
#if defined(_WIN32)
|
||||
setup_conn_event_handler_threads();
|
||||
#else
|
||||
@@ -9501,6 +9509,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/vio/CMakeLists.txt b/vio/CMakeLists.txt
|
||||
index f46858dd4bf..09c0a62ef8c 100644
|
||||
--- a/vio/CMakeLists.txt
|
||||
+++ b/vio/CMakeLists.txt
|
||||
@@ -25,6 +25,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 de46703eb82..01e8695f574 100644
|
||||
--- a/vio/vio.cc
|
||||
+++ b/vio/vio.cc
|
||||
@@ -300,6 +300,27 @@ static bool vio_init(Vio *vio, enum enum_vio_type type, my_socket sd,
|
||||
return false;
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
+ if (type == 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;
|
||||
+ return false;
|
||||
+ }
|
||||
vio->viodelete = vio_delete;
|
||||
vio->vioerrno = vio_errno;
|
||||
vio->read = vio->read_buffer ? vio_read_buff : vio_read;
|
||||
@@ -577,7 +598,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..d8c2987d7be
|
||||
--- /dev/null
|
||||
+++ b/vio/viofuzz.cc
|
||||
@@ -0,0 +1,128 @@
|
||||
+
|
||||
+#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) {
|
||||
+ int ret, wait;
|
||||
+ int retry_count = 0;
|
||||
+ 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. */
|
||||
+ ret=0;
|
||||
+
|
||||
+ DBUG_RETURN(MY_TEST(ret));
|
||||
+}
|
||||
+
|
||||
+
|
||||
+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 %d ", size);
|
||||
+ for (int i=0; i<size; i++)
|
||||
+ printf("%02x ", bufp[i]);
|
||||
+ printf("\n");
|
||||
+#endif
|
||||
+ 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 %d ", size);
|
||||
+ for (int i=0; i<size; i++)
|
||||
+ printf("%02x ", bufp[i]);
|
||||
+ printf("\n");
|
||||
+#endif
|
||||
+ 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);
|
||||
+}
|
|
@ -0,0 +1,12 @@
|
|||
homepage: "https://www.mysql.com"
|
||||
primary_contact: "secalert_us@oracle.com"
|
||||
auto_ccs :
|
||||
- "p.antoine@catenacyber.fr"
|
||||
- "christopher.alves@telecomnancy.net"
|
||||
- "zouhair.janati-idrissi@telecomnancy.net"
|
||||
- "julien.zhan@telecomnancy.net"
|
||||
|
||||
sanitizers:
|
||||
- address
|
||||
- memory
|
||||
- undefined
|
|
@ -0,0 +1,24 @@
|
|||
find_library(FUZZINGENGINE_LIB FuzzingEngine)
|
||||
|
||||
if(NOT FUZZINGENGINE_LIB)
|
||||
MYSQL_ADD_EXECUTABLE(fuzz_real_query fuzz_real_query.cc onefile.cc)
|
||||
TARGET_LINK_LIBRARIES(fuzz_real_query mysqlclient)
|
||||
|
||||
MYSQL_ADD_EXECUTABLE(fuzz_stmt_fetch fuzz_stmt_fetch.cc onefile.cc)
|
||||
TARGET_LINK_LIBRARIES(fuzz_stmt_fetch mysqlclient)
|
||||
|
||||
MYSQL_ADD_EXECUTABLE(fuzz_mysqld fuzz_mysqld.cc onefile.cc)
|
||||
TARGET_LINK_LIBRARIES(fuzz_mysqld sql_main sql_gis binlog rpl master slave sql_main sql_dd sql_gis mysys mysys_ssl binlogevents_static ${ICU_LIBRARIES})
|
||||
else()
|
||||
MYSQL_ADD_EXECUTABLE(fuzz_real_query fuzz_real_query.cc)
|
||||
TARGET_LINK_LIBRARIES(fuzz_real_query mysqlclient)
|
||||
TARGET_LINK_LIBRARIES(fuzz_real_query FuzzingEngine)
|
||||
|
||||
MYSQL_ADD_EXECUTABLE(fuzz_stmt_fetch fuzz_stmt_fetch.cc)
|
||||
TARGET_LINK_LIBRARIES(fuzz_stmt_fetch mysqlclient)
|
||||
TARGET_LINK_LIBRARIES(fuzz_stmt_fetch FuzzingEngine)
|
||||
|
||||
MYSQL_ADD_EXECUTABLE(fuzz_mysqld fuzz_mysqld.cc)
|
||||
TARGET_LINK_LIBRARIES(fuzz_mysqld sql_main sql_gis binlog rpl master slave sql_main sql_dd sql_gis mysys mysys_ssl binlogevents_static ${ICU_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(fuzz_mysqld FuzzingEngine)
|
||||
endif()
|
|
@ -0,0 +1,2 @@
|
|||
This is the directory used for fuzzing, intended to be used with oss-fuzz.
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
//#include <stdint.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <stdio.h>
|
||||
//#include <string>
|
||||
//#include <iostream>
|
||||
//#include <mysql.h>
|
||||
//#include <mysql/client_plugin.h>
|
||||
//#include <mysqld_error.h>
|
||||
#include "sql/sql_class.h"
|
||||
#include "sql/conn_handler/channel_info.h"
|
||||
#include "sql/conn_handler/connection_handler.h"
|
||||
#include "sql/conn_handler/connection_handler_manager.h"
|
||||
#include "sql/conn_handler/init_net_server_extension.h"
|
||||
#include "sql/conn_handler/connection_handler_impl.h"
|
||||
#include "sql/mysqld.h"
|
||||
#include "sql/set_var.h"
|
||||
#include "sql/rpl_handler.h"
|
||||
#include "sql/log.h"
|
||||
#include "sql/opt_costconstantcache.h"
|
||||
#include "sql/sql_plugin.h"
|
||||
#include "violite.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std;
|
||||
FILE *logfile = NULL;
|
||||
Connection_handler_manager * chm;
|
||||
extern int mysqld_main(int argc, char **argv);
|
||||
|
||||
class Channel_info_fuzz : public Channel_info {
|
||||
bool m_is_admin_conn;
|
||||
|
||||
protected:
|
||||
virtual Vio *create_and_init_vio() const {
|
||||
Vio *vio = vio_new(0, VIO_TYPE_FUZZ, VIO_LOCALHOST);
|
||||
return vio;
|
||||
}
|
||||
|
||||
public:
|
||||
Channel_info_fuzz(bool is_admin_conn) : m_is_admin_conn(is_admin_conn) {}
|
||||
|
||||
virtual THD *create_thd() {
|
||||
Vio *vio_tmp = create_and_init_vio();
|
||||
if (vio_tmp == NULL) return NULL;
|
||||
|
||||
THD *thd = new (std::nothrow) THD();
|
||||
if (thd == NULL) {
|
||||
vio_delete(vio_tmp);
|
||||
return NULL;
|
||||
}
|
||||
thd->get_protocol_classic()->init_net(vio_tmp);
|
||||
thd->set_admin_connection(m_is_admin_conn);
|
||||
init_net_server_extension(thd);
|
||||
return thd;
|
||||
}
|
||||
|
||||
virtual bool is_admin_connection() const { return m_is_admin_conn; }
|
||||
};
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
if (Size < 1) {
|
||||
return 0;
|
||||
}
|
||||
if (logfile == NULL) {
|
||||
my_progname = "fuzz_mysqld";
|
||||
/* first init was run with
|
||||
* mysqld --user=root --initialize-insecure --log-error-verbosity=5 --datadir=/out/mysql/data/ --basedir=/out/mysql/
|
||||
*/
|
||||
system("rm -Rf /tmp/mysql");
|
||||
system("cp -r /out/mysql/data /tmp/mysql");
|
||||
|
||||
char *fakeargv[] = {const_cast<char *>("fuzz_mysqld"),
|
||||
const_cast<char *>("--user=root"),
|
||||
const_cast<char *>("--secure-file-priv=NULL"),
|
||||
const_cast<char *>("--log-error-verbosity=5"),
|
||||
const_cast<char *>("--explicit_defaults_for_timestamp"),
|
||||
//we should adapt vio_fuzz to give a socket to openssl in order to support ssl
|
||||
const_cast<char *>("--skip-ssl"),
|
||||
const_cast<char *>("--mysqlx=0"),
|
||||
const_cast<char *>("--event-scheduler=DISABLED"),
|
||||
const_cast<char *>("--thread_stack=1048576"),
|
||||
const_cast<char *>("--datadir=/tmp/mysql/"),
|
||||
const_cast<char *>("--basedir=/out/mysql/"),
|
||||
const_cast<char *>("--init-file=/out/init.sql"),
|
||||
0};
|
||||
int fakeargc = 12;
|
||||
mysqld_main(fakeargc, fakeargv);
|
||||
|
||||
chm = Connection_handler_manager::get_instance();
|
||||
logfile = fopen("/dev/null", "w");
|
||||
}
|
||||
// The fuzzing takes place on network data received from client
|
||||
sock_initfuzz(Data,Size-1);
|
||||
|
||||
Channel_info_fuzz *channel_info = new (std::nothrow) Channel_info_fuzz(Data[Size-1] & 0x80);
|
||||
chm->process_new_connection(channel_info);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
user="root"
|
|
@ -0,0 +1,2 @@
|
|||
[libfuzzer]
|
||||
close_fd_mask = 3
|
|
@ -0,0 +1,100 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <mysql.h>
|
||||
#include <mysql/client_plugin.h>
|
||||
#include <mysqld_error.h>
|
||||
#include "violite.h"
|
||||
|
||||
using namespace std;
|
||||
FILE *logfile = NULL;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
MYSQL mysql;
|
||||
long flags;
|
||||
bool opt_cleartext = true;
|
||||
unsigned int opt_ssl = SSL_MODE_DISABLED;
|
||||
MYSQL_RES *result;
|
||||
|
||||
if (Size < sizeof(unsigned long)) {
|
||||
return 0;
|
||||
}
|
||||
if (logfile == NULL) {
|
||||
logfile = fopen("/dev/null", "w");
|
||||
}
|
||||
flags = * ((unsigned long *) (Data + Size - sizeof(unsigned long)));
|
||||
mysql_init(&mysql);
|
||||
mysql_options(&mysql, MYSQL_ENABLE_CLEARTEXT_PLUGIN, &opt_cleartext);
|
||||
mysql_options(&mysql, MYSQL_OPT_SSL_MODE, &opt_ssl);
|
||||
mysql.options.protocol = MYSQL_PROTOCOL_FUZZ;
|
||||
// The fuzzing takes place on network data received from server
|
||||
sock_initfuzz(Data,Size - sizeof(unsigned long));
|
||||
if (!mysql_real_connect(&mysql, "localhost", "root", "root", "dbname", 0, NULL, flags)) {
|
||||
goto out;
|
||||
} else {
|
||||
fprintf(logfile, "The last inserted row id is: %llu\n", mysql_insert_id(&mysql));
|
||||
fprintf(logfile, "%llu affected rows\n", mysql_affected_rows(&mysql));
|
||||
mysql_info(&mysql);
|
||||
}
|
||||
|
||||
mysql_query(&mysql, "CREATE DATABASE fuzzbase");
|
||||
if (mysql_query(&mysql, "SELECT * FROM CARS")) {
|
||||
goto out;
|
||||
}
|
||||
result = mysql_store_result(&mysql);
|
||||
if (result != NULL) {
|
||||
int num_fields = mysql_num_fields(result);
|
||||
MYSQL_FIELD *field;
|
||||
while((field = mysql_fetch_field(result))) {
|
||||
fprintf(logfile, "%s\n", field->name);
|
||||
}
|
||||
MYSQL_ROW row = mysql_fetch_row(result);
|
||||
unsigned long * lengths = mysql_fetch_lengths(result);
|
||||
while (row ) {
|
||||
for(int i = 0; i < num_fields; i++) {
|
||||
fprintf(logfile, "length %lu, %s\n", lengths[i], row[i] ? row[i] : "NULL");
|
||||
}
|
||||
row = mysql_fetch_row(result);
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
result = mysql_list_dbs(&mysql, NULL);
|
||||
if (result) {
|
||||
mysql_free_result(result);
|
||||
}
|
||||
result = mysql_list_tables(&mysql, NULL);
|
||||
if (result) {
|
||||
mysql_free_result(result);
|
||||
}
|
||||
result = mysql_list_fields(&mysql, "sometable", NULL);
|
||||
if (result) {
|
||||
mysql_free_result(result);
|
||||
}
|
||||
result = mysql_list_processes(&mysql);
|
||||
if (result) {
|
||||
mysql_free_result(result);
|
||||
}
|
||||
mysql_ping(&mysql);
|
||||
|
||||
if (mysql_change_user(&mysql, "user", "password", "new_database")) {
|
||||
goto out;
|
||||
}
|
||||
if (mysql_query(&mysql, "INSERT INTO Fuzzers(Name) VALUES('myfuzzer')") == 0) {
|
||||
fprintf(logfile, "The last inserted row id is: %llu\n", mysql_insert_id(&mysql));
|
||||
fprintf(logfile, "%llu affected rows\n", mysql_affected_rows(&mysql));
|
||||
mysql_info(&mysql);
|
||||
}
|
||||
mysql_get_host_info(&mysql);
|
||||
mysql_get_proto_info(&mysql);
|
||||
mysql_get_server_info(&mysql);
|
||||
mysql_get_server_version(&mysql);
|
||||
mysql_dump_debug_info(&mysql);
|
||||
mysql_sqlstate(&mysql);
|
||||
mysql_stat(&mysql);
|
||||
|
||||
out:
|
||||
mysql_close(&mysql);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <mysql.h>
|
||||
#include <mysql/client_plugin.h>
|
||||
#include <conn_handler/connection_handler.h>
|
||||
#include "violite.h"
|
||||
|
||||
using namespace std;
|
||||
FILE *logfile = NULL;
|
||||
Connection_handler * connection_handler;
|
||||
|
||||
class Channel_info_fuzz : public Channel_info {
|
||||
bool m_is_admin_conn;
|
||||
|
||||
protected:
|
||||
virtual Vio *create_and_init_vio() const {
|
||||
Vio *vio = mysql_socket_vio_new(0, VIO_TYPE_FUZZ, 0);
|
||||
return vio;
|
||||
}
|
||||
|
||||
public:
|
||||
Channel_info_fuzz(bool is_admin_conn) : m_is_admin_conn(is_admin_conn) {}
|
||||
|
||||
virtual THD *create_thd() {
|
||||
THD *thd = Channel_info::create_thd();
|
||||
|
||||
if (thd != NULL) {
|
||||
thd->set_admin_connection(m_is_admin_conn);
|
||||
init_net_server_extension(thd);
|
||||
}
|
||||
return thd;
|
||||
}
|
||||
|
||||
virtual bool is_admin_connection() const { return m_is_admin_conn; }
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
if (Size < 1) {
|
||||
return 0;
|
||||
}
|
||||
if (logfile == NULL) {
|
||||
connection_handler = new (std::nothrow) One_thread_connection_handler();
|
||||
logfile = fopen("/dev/null", "w");
|
||||
}
|
||||
// The fuzzing takes place on network data received from server
|
||||
sock_initfuzz(Data,Size-1);
|
||||
|
||||
Channel_info_fuzz *channel_info = new (std::nothrow) Channel_info_fuzz(Data[Size-1] & 0x80);
|
||||
connection_handler->add_connection(channel_info);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <mysql.h>
|
||||
#include <mysql/client_plugin.h>
|
||||
#include <mysqld_error.h>
|
||||
#include "violite.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define STRING_SIZE 50
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
MYSQL mysql;
|
||||
MYSQL_BIND bind[4];
|
||||
MYSQL_RES *prepare_meta_result;
|
||||
MYSQL_TIME ts;
|
||||
unsigned long length[4];
|
||||
int param_count, column_count, row_count;
|
||||
short small_data;
|
||||
int int_data;
|
||||
char str_data[STRING_SIZE];
|
||||
bool is_null[4];
|
||||
bool error[4];
|
||||
|
||||
mysql_init(&mysql);
|
||||
mysql.options.protocol = MYSQL_PROTOCOL_FUZZ;
|
||||
// The fuzzing takes place on network data received from server
|
||||
sock_initfuzz(Data,Size);
|
||||
if (!mysql_real_connect(&mysql,"localhost","root","root","",0,NULL,0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
MYSQL_STMT *stmt = mysql_stmt_init(&mysql);
|
||||
if (!stmt)
|
||||
{
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(&mysql);
|
||||
return 0;
|
||||
}
|
||||
if (mysql_stmt_prepare(stmt, "SELECT col1, col2, col3, col4 FROM Cars",(ulong)strlen("SELECT col1, col2, col3, col4 FROM Cars")))
|
||||
{
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(&mysql);
|
||||
return 0;
|
||||
}
|
||||
prepare_meta_result = mysql_stmt_result_metadata(stmt);
|
||||
if (!prepare_meta_result)
|
||||
{
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(&mysql);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mysql_stmt_execute(stmt))
|
||||
{
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(&mysql);
|
||||
return 0;
|
||||
}
|
||||
column_count= mysql_num_fields(prepare_meta_result);
|
||||
memset(bind, 0, sizeof(bind));
|
||||
/* INTEGER COLUMN */
|
||||
bind[0].buffer_type= MYSQL_TYPE_LONG;
|
||||
bind[0].buffer= (char *)&int_data;
|
||||
bind[0].is_null= &is_null[0];
|
||||
bind[0].length= &length[0];
|
||||
bind[0].error= &error[0];
|
||||
|
||||
/* STRING COLUMN */
|
||||
bind[1].buffer_type= MYSQL_TYPE_STRING;
|
||||
bind[1].buffer= (char *)str_data;
|
||||
bind[1].buffer_length= STRING_SIZE;
|
||||
bind[1].is_null= &is_null[1];
|
||||
bind[1].length= &length[1];
|
||||
bind[1].error= &error[1];
|
||||
|
||||
/* SMALLINT COLUMN */
|
||||
bind[2].buffer_type= MYSQL_TYPE_SHORT;
|
||||
bind[2].buffer= (char *)&small_data;
|
||||
bind[2].is_null= &is_null[2];
|
||||
bind[2].length= &length[2];
|
||||
bind[2].error= &error[2];
|
||||
|
||||
/* TIMESTAMP COLUMN */
|
||||
bind[3].buffer_type= MYSQL_TYPE_TIMESTAMP;
|
||||
bind[3].buffer= (char *)&ts;
|
||||
bind[3].is_null= &is_null[3];
|
||||
bind[3].length= &length[3];
|
||||
bind[3].error= &error[3];
|
||||
|
||||
if (mysql_stmt_bind_result(stmt, bind))
|
||||
{
|
||||
mysql_free_result(prepare_meta_result);
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(&mysql);
|
||||
return 0;
|
||||
}
|
||||
if (mysql_stmt_store_result(stmt))
|
||||
{
|
||||
mysql_free_result(prepare_meta_result);
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(&mysql);
|
||||
return 0;
|
||||
}
|
||||
while (!mysql_stmt_fetch(stmt)) {}
|
||||
|
||||
mysql_free_result(prepare_meta_result);
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(&mysql);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
CREATE USER 'fuzzuser'@'localhost' IDENTIFIED BY 'fuzzpass';
|
||||
ALTER USER 'root'@'localhost' IDENTIFIED BY 'mainpass';
|
|
@ -0,0 +1,50 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
FILE * fp;
|
||||
uint8_t *Data;
|
||||
size_t Size;
|
||||
|
||||
if (argc != 2) {
|
||||
return 1;
|
||||
}
|
||||
//opens the file, get its size, and reads it into a buffer
|
||||
fp = fopen(argv[1], "rb");
|
||||
if (fp == NULL) {
|
||||
return 2;
|
||||
}
|
||||
if (fseek(fp, 0L, SEEK_END) != 0) {
|
||||
fclose(fp);
|
||||
return 2;
|
||||
}
|
||||
Size = ftell(fp);
|
||||
if (Size == (size_t) -1) {
|
||||
fclose(fp);
|
||||
return 2;
|
||||
}
|
||||
if (fseek(fp, 0L, SEEK_SET) != 0) {
|
||||
fclose(fp);
|
||||
return 2;
|
||||
}
|
||||
Data = (uint8_t*)malloc(Size*sizeof(uint8_t));
|
||||
if (Data == NULL) {
|
||||
fclose(fp);
|
||||
return 2;
|
||||
}
|
||||
if (fread(Data, Size, 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
free(Data);
|
||||
return 2;
|
||||
}
|
||||
|
||||
//lauch fuzzer
|
||||
LLVMFuzzerTestOneInput(Data, Size);
|
||||
free(Data);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue