File: sql_multithreaded_fuzzer.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (91 lines) | stat: -rw-r--r-- 2,789 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Unused because SQLite is so serialized and concurrency-unfriendly that this
// really wouldn't test anything.

#include <condition_variable>
#include <cstdlib>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
#include <vector>

#include "testing/libfuzzer/proto/lpm_interface.h"
#include "third_party/sqlite/fuzz/disabled_queries_parser.h"
#include "third_party/sqlite/fuzz/sql_query_grammar.pb.h"
#include "third_party/sqlite/fuzz/sql_query_proto_to_string.h"
#include "third_party/sqlite/fuzz/sql_run_queries.h"
#include "third_party/sqlite/sqlite3.h"

using namespace sql_query_grammar;

namespace {
constexpr int kNumThreads = 4;  // Must change with MultipleSQLQueries protobuf.
}

DEFINE_BINARY_PROTO_FUZZER(const MultipleSQLQueries& multiple_sql_queries) {
  char* skip_queries = ::getenv("SQL_SKIP_QUERIES");
  if (skip_queries) {
    sql_fuzzer::SetDisabledQueries(
        sql_fuzzer::ParseDisabledQueries(skip_queries));
  }

  assert(multiple_sql_queries.GetDescriptor()->field_count() == kNumThreads);

  sqlite3* db = sql_fuzzer::InitConnectionForFuzzing();
  if (!db)
    return;

  if (::getenv("LPM_SQLITE_TRACE")) {
    sql_fuzzer::EnableSqliteTracing(db);
  }

  std::vector<std::string> query_strs[kNumThreads];
  query_strs[0] = sql_fuzzer::SQLQueriesToVec(multiple_sql_queries.queries1());
  query_strs[1] = sql_fuzzer::SQLQueriesToVec(multiple_sql_queries.queries2());
  query_strs[2] = sql_fuzzer::SQLQueriesToVec(multiple_sql_queries.queries3());
  query_strs[3] = sql_fuzzer::SQLQueriesToVec(multiple_sql_queries.queries4());

  if (::getenv("LPM_DUMP_NATIVE_INPUT")) {
    std::cout << "_________________________" << std::endl;
    for (int i = 0; i < kNumThreads; i++) {
      std::cout << "Thread " << i << ":" << std::endl;
      for (std::string query : query_strs[i]) {
        if (query == ";")
          continue;
        std::cout << query << std::endl;
      }
    }
    std::cout << "------------------------" << std::endl;
  }

  int num_threads_started = 0;
  std::mutex m;
  std::condition_variable cv;

  std::vector<std::thread> threads;

  auto to_run = [&](std::vector<std::string> queries) {
    // Wait for all the threads to start.
    std::unique_lock<std::mutex> lk(m);
    num_threads_started++;
    cv.notify_all();
    cv.wait(lk, [&] { return num_threads_started == kNumThreads; });
    m.unlock();

    sql_fuzzer::RunSqlQueriesOnConnection(db, queries);
  };

  for (int i = 0; i < kNumThreads; i++) {
    threads.emplace_back(to_run, query_strs[i]);
  }

  for (int i = 0; i < kNumThreads; i++) {
    threads[i].join();
  }

  sql_fuzzer::CloseConnection(db);
}