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