diff options
Diffstat (limited to 'projects/mysql-server/targets/fuzz_docommand.cc')
-rw-r--r-- | projects/mysql-server/targets/fuzz_docommand.cc | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/projects/mysql-server/targets/fuzz_docommand.cc b/projects/mysql-server/targets/fuzz_docommand.cc new file mode 100644 index 00000000..3d3ef209 --- /dev/null +++ b/projects/mysql-server/targets/fuzz_docommand.cc @@ -0,0 +1,173 @@ +//#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/protocol_classic.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 "sql/sql_thd_internal_api.h" +#include "sql/mysqld_thd_manager.h" +#include "sql/sql_parse.h" +#include "mysql/psi/mysql_socket.h" +#include "violite.h" +#include <stdlib.h> +#include <libgen.h> + +using namespace std; +FILE *logfile = NULL; +Connection_handler_manager * chm; +extern int mysqld_main(int argc, char **argv); +char *filepath = NULL; + +extern "C" int LLVMFuzzerInitialize(const int* argc, char*** argv) { + filepath = dirname(strdup((*argv)[0])); + return 0; +} + + +const uint8_t startConn[] = +"\xa6\x00\x00\x01\x85\xa6\xff\x01\x00\x00\x00\x01\x2d\x00\x00\x00" \ +"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ +"\x00\x00\x00\x00\x72\x6f\x6f\x74\x00\x01\x00\x6d\x79\x73\x71\x6c" \ +"\x5f\x63\x6c\x65\x61\x72\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00" \ +"\x69\x04\x5f\x70\x69\x64\x05\x35\x34\x30\x30\x31\x03\x5f\x6f\x73" \ +"\x08\x6f\x73\x78\x31\x30\x2e\x31\x33\x09\x5f\x70\x6c\x61\x74\x66" \ +"\x6f\x72\x6d\x06\x78\x38\x36\x5f\x36\x34\x0f\x5f\x63\x6c\x69\x65" \ +"\x6e\x74\x5f\x76\x65\x72\x73\x69\x6f\x6e\x06\x38\x2e\x30\x2e\x31" \ +"\x36\x0c\x5f\x63\x6c\x69\x65\x6e\x74\x5f\x6e\x61\x6d\x65\x08\x6c" \ +"\x69\x62\x6d\x79\x73\x71\x6c\x0c\x70\x72\x6f\x67\x72\x61\x6d\x5f" \ +"\x6e\x61\x6d\x65\x05\x6d\x79\x73\x71\x6c" +"\x00\x00\x00\x03" +; + + +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; } +}; + +#define MAX_SIZE 256 + + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (Size < 1) { + return 0; + } + if (logfile == NULL) { + my_progname = "fuzz_docommand"; + /* 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"); + char command[MAX_SIZE]; + char argbase[MAX_SIZE]; + char arginitfile[MAX_SIZE]; + snprintf(command, MAX_SIZE-1, "cp -r %s/mysql/data /tmp/mysql", filepath); + //unsafe + system(command); + + snprintf(argbase, MAX_SIZE-1, "--basedir=%s/mysql/", filepath); + snprintf(arginitfile, MAX_SIZE-1, "--init-file=%s/initnopw.sql", filepath); + + char *fakeargv[] = {const_cast<char *>("fuzz_docommand"), + 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 *>("--performance_schema=OFF"), + const_cast<char *>("--thread_stack=1048576"), + const_cast<char *>("--datadir=/tmp/mysql/"), + const_cast<char *>("--port=3301"), + const_cast<char *>("--socket=/tmp/docommand.sock"), + const_cast<char *>(argbase), + const_cast<char *>(arginitfile), + 0}; + int fakeargc = 15; + mysqld_main(fakeargc, fakeargv); + + chm = Connection_handler_manager::get_instance(); + logfile = fopen("/dev/null", "w"); + } + Channel_info_fuzz * channel_info = new (std::nothrow) Channel_info_fuzz(true); + sock_initfuzz(startConn,sizeof(startConn)); + if (my_thread_init()) { + channel_info->send_error_and_close_channel(ER_OUT_OF_RESOURCES, 0, false); + abort(); + } + + THD *thd_fuzz = channel_info->create_thd(); + if (thd_fuzz == NULL) { + channel_info->send_error_and_close_channel(ER_OUT_OF_RESOURCES, 0, false); + abort(); + } + + thd_fuzz->set_new_thread_id(); + thd_set_thread_stack(thd_fuzz, (char *)&thd_fuzz); + thd_fuzz->store_globals(); + mysql_thread_set_psi_id(thd_fuzz->thread_id()); + mysql_socket_set_thread_owner( + thd_fuzz->get_protocol_classic()->get_vio()->mysql_socket); + Global_THD_manager *thd_manager = Global_THD_manager::get_instance(); + thd_manager->add_thd(thd_fuzz); + if (thd_prepare_connection(thd_fuzz)) { + abort(); + } + delete channel_info; + + // The fuzzing takes place on network data received from client + sock_initfuzz(Data,Size); + + while (thd_connection_alive(thd_fuzz)) { + if (do_command(thd_fuzz)) break; + } + end_connection(thd_fuzz); + close_connection(thd_fuzz, 0, false, false); + thd_fuzz->release_resources(); + thd_manager->remove_thd(thd_fuzz); + delete thd_fuzz; + + return 0; +} |