1 #include <stdint.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string>
5 #include <iostream>
6 #include <mysql.h>
7 #include <mysql/client_plugin.h>
8 #include <mysqld_error.h>
9 #include "violite.h"
10
11 using namespace std;
12
13 #define STRING_SIZE 50
14
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)15 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
16 MYSQL mysql;
17 MYSQL_BIND bind[4];
18 MYSQL_RES *prepare_meta_result;
19 MYSQL_TIME ts;
20 unsigned long length[4];
21 int column_count;
22 short small_data;
23 int int_data;
24 char str_data[STRING_SIZE];
25 bool is_null[4];
26 bool error[4];
27 bool opt_cleartext = true;
28 unsigned int opt_ssl = SSL_MODE_DISABLED;
29
30 mysql_init(&mysql);
31 mysql_options(&mysql, MYSQL_ENABLE_CLEARTEXT_PLUGIN, &opt_cleartext);
32 mysql_options(&mysql, MYSQL_OPT_SSL_MODE, &opt_ssl);
33 mysql.options.protocol = MYSQL_PROTOCOL_FUZZ;
34 // The fuzzing takes place on network data received from server
35 sock_initfuzz(Data,Size);
36 if (!mysql_real_connect(&mysql,"localhost","root","root","",0,NULL,0))
37 {
38 return 0;
39 }
40
41 MYSQL_STMT *stmt = mysql_stmt_init(&mysql);
42 if (!stmt)
43 {
44 mysql_stmt_close(stmt);
45 mysql_close(&mysql);
46 return 0;
47 }
48 if (mysql_stmt_prepare(stmt, "SELECT col1, col2, col3, col4 FROM Cars",(ulong)strlen("SELECT col1, col2, col3, col4 FROM Cars")))
49 {
50 mysql_stmt_close(stmt);
51 mysql_close(&mysql);
52 return 0;
53 }
54 prepare_meta_result = mysql_stmt_result_metadata(stmt);
55 if (!prepare_meta_result)
56 {
57 mysql_stmt_close(stmt);
58 mysql_close(&mysql);
59 return 0;
60 }
61
62 if (mysql_stmt_execute(stmt))
63 {
64 mysql_stmt_close(stmt);
65 mysql_close(&mysql);
66 return 0;
67 }
68 column_count= mysql_num_fields(prepare_meta_result);
69 memset(bind, 0, sizeof(bind));
70 /* INTEGER COLUMN */
71 bind[0].buffer_type= MYSQL_TYPE_LONG;
72 bind[0].buffer= (char *)&int_data;
73 bind[0].is_null= &is_null[0];
74 bind[0].length= &length[0];
75 bind[0].error= &error[0];
76
77 /* STRING COLUMN */
78 bind[1].buffer_type= MYSQL_TYPE_STRING;
79 bind[1].buffer= (char *)str_data;
80 bind[1].buffer_length= STRING_SIZE;
81 bind[1].is_null= &is_null[1];
82 bind[1].length= &length[1];
83 bind[1].error= &error[1];
84
85 /* SMALLINT COLUMN */
86 bind[2].buffer_type= MYSQL_TYPE_SHORT;
87 bind[2].buffer= (char *)&small_data;
88 bind[2].is_null= &is_null[2];
89 bind[2].length= &length[2];
90 bind[2].error= &error[2];
91
92 /* TIMESTAMP COLUMN */
93 bind[3].buffer_type= MYSQL_TYPE_TIMESTAMP;
94 bind[3].buffer= (char *)&ts;
95 bind[3].is_null= &is_null[3];
96 bind[3].length= &length[3];
97 bind[3].error= &error[3];
98
99 if (mysql_stmt_bind_result(stmt, bind))
100 {
101 mysql_free_result(prepare_meta_result);
102 mysql_stmt_close(stmt);
103 mysql_close(&mysql);
104 return 0;
105 }
106 if (mysql_stmt_store_result(stmt))
107 {
108 mysql_free_result(prepare_meta_result);
109 mysql_stmt_close(stmt);
110 mysql_close(&mysql);
111 return 0;
112 }
113 while (1) {
114 int status = mysql_stmt_fetch(stmt);
115 if (status == 1 || status == MYSQL_NO_DATA)
116 break;
117 }
118
119 mysql_free_result(prepare_meta_result);
120 mysql_stmt_close(stmt);
121 mysql_close(&mysql);
122 return 0;
123 }
124