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 FILE *logfile = NULL;
13 
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)14 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
15     MYSQL mysql;
16     long flags;
17     bool opt_cleartext = true;
18     unsigned int opt_ssl = SSL_MODE_DISABLED;
19     MYSQL_RES *result;
20 
21     if (Size < sizeof(unsigned long)) {
22         return 0;
23     }
24     if (logfile == NULL) {
25         logfile = fopen("/dev/null", "w");
26     }
27     memcpy(&flags, Data + Size - sizeof(unsigned long), sizeof(unsigned long));
28     mysql_init(&mysql);
29     mysql_options(&mysql, MYSQL_ENABLE_CLEARTEXT_PLUGIN, &opt_cleartext);
30     mysql_options(&mysql, MYSQL_OPT_SSL_MODE, &opt_ssl);
31     mysql.options.protocol = MYSQL_PROTOCOL_FUZZ;
32     // The fuzzing takes place on network data received from server
33     sock_initfuzz(Data,Size - sizeof(unsigned long));
34     if (!mysql_real_connect(&mysql, "localhost", "root", "root", "dbname", 0, NULL, flags)) {
35         goto out;
36     } else {
37         fprintf(logfile, "The last inserted row id is: %llu\n", mysql_insert_id(&mysql));
38         fprintf(logfile, "%llu affected rows\n", mysql_affected_rows(&mysql));
39         mysql_info(&mysql);
40     }
41 
42     mysql_query(&mysql, "CREATE DATABASE fuzzbase");
43     if (mysql_query(&mysql, "SELECT * FROM CARS")) {
44         goto out;
45     }
46     result = mysql_store_result(&mysql);
47     if (result != NULL) {
48         int num_fields = mysql_num_fields(result);
49         MYSQL_FIELD *field;
50         while((field = mysql_fetch_field(result))) {
51             fprintf(logfile, "%s\n", field->name);
52         }
53         MYSQL_ROW row = mysql_fetch_row(result);
54         unsigned long * lengths = mysql_fetch_lengths(result);
55         while (row ) {
56             for(int i = 0; i < num_fields; i++) {
57                 fprintf(logfile, "length %lu, %s\n", lengths[i], row[i] ? row[i] : "NULL");
58             }
59             row = mysql_fetch_row(result);
60         }
61         mysql_free_result(result);
62     }
63     result = mysql_list_dbs(&mysql, NULL);
64     if (result) {
65         mysql_free_result(result);
66     }
67     result = mysql_list_tables(&mysql, NULL);
68     if (result) {
69         mysql_free_result(result);
70     }
71     result = mysql_list_fields(&mysql, "sometable", NULL);
72     if (result) {
73         mysql_free_result(result);
74     }
75     result = mysql_list_processes(&mysql);
76     if (result) {
77         mysql_free_result(result);
78     }
79     mysql_ping(&mysql);
80 
81     if (mysql_change_user(&mysql, "user", "password", "new_database")) {
82         goto out;
83     }
84     if (mysql_query(&mysql, "INSERT INTO Fuzzers(Name) VALUES('myfuzzer')") == 0) {
85         fprintf(logfile, "The last inserted row id is: %llu\n", mysql_insert_id(&mysql));
86         fprintf(logfile, "%llu affected rows\n", mysql_affected_rows(&mysql));
87         mysql_info(&mysql);
88     }
89     mysql_get_host_info(&mysql);
90     mysql_get_proto_info(&mysql);
91     mysql_get_server_info(&mysql);
92     mysql_get_server_version(&mysql);
93     mysql_dump_debug_info(&mysql);
94     mysql_sqlstate(&mysql);
95     mysql_stat(&mysql);
96 
97 out:
98     mysql_close(&mysql);
99     return 0;
100 }
101