ClickHouse

Форк
0
/
tcp_protocol_fuzzer.cpp 
119 строк · 3.0 Кб
1
#include <cstdint>
2
#include <future>
3
#include <thread>
4
#include <utility>
5
#include <vector>
6
#include <iostream>
7
#include <chrono>
8

9
#include <Poco/Net/PollSet.h>
10
#include <Poco/Net/SocketAddress.h>
11
#include <Poco/Net/StreamSocket.h>
12

13
#include <Interpreters/Context.h>
14

15

16
int mainEntryClickHouseServer(int argc, char ** argv);
17

18
static std::string clickhouse("clickhouse-server");
19
static std::vector<char *> args{clickhouse.data()};
20
static std::future<int> main_app;
21

22
static std::string s_host("0.0.0.0");
23
static char * host = s_host.data();
24
static int64_t port = 9000;
25

26
using namespace std::chrono_literals;
27

28
extern "C"
29
int LLVMFuzzerInitialize(int * argc, char ***argv)
30
{
31
    for (int i = 1; i < *argc; ++i)
32
    {
33
        if ((*argv)[i][0] == '-')
34
        {
35
            if ((*argv)[i][1] == '-')
36
                args.push_back((*argv)[i]);
37
            else
38
            {
39
                if (strncmp((*argv)[i], "-host=", 6) == 0)
40
                {
41
                    host = (*argv)[i] + 6;
42
                }
43
                else if (strncmp((*argv)[i], "-port=", 6) == 0)
44
                {
45
                    char * p_end = nullptr;
46
                    port = strtol((*argv)[i] + 6, &p_end, 10);
47
                }
48
            }
49
        }
50
    }
51

52
    args.push_back(nullptr);
53

54
    main_app = std::async(std::launch::async, mainEntryClickHouseServer, args.size() - 1, args.data());
55

56
    while (!DB::Context::getGlobalContextInstance() || !DB::Context::getGlobalContextInstance()->isServerCompletelyStarted())
57
    {
58
        std::this_thread::sleep_for(100ms);
59
        if (main_app.wait_for(0s) == std::future_status::ready)
60
            exit(-1);
61
    }
62

63
    return 0;
64
}
65

66
extern "C"
67
int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size)
68
{
69
    try
70
    {
71
        if (main_app.wait_for(0s) == std::future_status::ready)
72
            return -1;
73

74
        if (size == 0)
75
            return -1;
76

77
        Poco::Net::SocketAddress address(host, port);
78
        Poco::Net::StreamSocket socket;
79

80
        socket.connectNB(address);
81

82
        Poco::Net::PollSet ps;
83
        ps.add(socket, Poco::Net::PollSet::POLL_READ | Poco::Net::PollSet::POLL_WRITE);
84

85
        std::vector<char> buf(1048576);
86
        size_t sent = 0;
87
        while (true)
88
        {
89
            auto m = ps.poll(Poco::Timespan(1000000));
90
            if (m.empty())
91
                continue;
92
            if (m.begin()->second & Poco::Net::PollSet::POLL_READ)
93
            {
94
                if (int n = socket.receiveBytes(buf.data(), static_cast<int>(buf.size())); n == 0)
95
                {
96
                    socket.close();
97
                    break;
98
                }
99

100
                continue;
101
            }
102

103
            if (sent < size && m.begin()->second & Poco::Net::PollSet::POLL_WRITE)
104
            {
105
                sent += socket.sendBytes(data + sent, static_cast<int>(size - sent));
106
                if (sent == size)
107
                {
108
                    socket.shutdownSend();
109
                    continue;
110
                }
111
            }
112
        }
113
    }
114
    catch (...)
115
    {
116
    }
117

118
    return 0;
119
}
120

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.