curl-fuzzer C++ reference
Loading...
Searching...
No Matches
curl_global_lifecycle.cc
1/*
2 * Copyright (C) Max Dymond, <cmeister2@gmail.com>, et al.
3 *
4 * SPDX-License-Identifier: curl
5 */
6
8
9#include <curl/curl.h>
10
11#include <csignal>
12#include <cstdio>
13#include <cstdlib>
14
15#include "proto_fuzzer/allocation_fault_injection.h"
16
17namespace proto_fuzzer {
18namespace {
19
20CurlGlobalLifecycle* registered_lifecycles = nullptr;
21
22} // namespace
23
27 : cleanup_(cleanup != nullptr ? cleanup : &curl_global_cleanup) {
28 // Curl_tls_keylog_open() runs once during global initialization. Keep the
29 // default output bounded while allowing a reproducer to select another path.
30 (void)setenv("SSLKEYLOGFILE", "/dev/null", 0);
31
32 // Mock-peer teardown can race a write. Surface that as a socket error rather
33 // than allowing SIGPIPE to terminate the process.
34 std::signal(SIGPIPE, SIG_IGN);
35
36 const bool callbacks_active = allocation_fault_injection::InitializeCurl();
37 if (allocation_fault_injection::ClaimCurlInitializationReference()) {
38 ++initialization_count_;
39 }
40 if (!callbacks_active) {
41 std::fputs("warning: libcurl allocation fault injection is unavailable\n", stderr);
42 }
43 if (initialization_count_ == 0 && curl_global_init(CURL_GLOBAL_ALL) == CURLE_OK) {
44 ++initialization_count_;
45 }
46 initialized_ = initialization_count_ != 0;
47 next_registered_ = registered_lifecycles;
48 registered_lifecycles = this;
49}
50
51CurlGlobalLifecycle::~CurlGlobalLifecycle() {
53 CurlGlobalLifecycle** link = &registered_lifecycles;
54 while (*link != nullptr && *link != this) {
55 link = &(*link)->next_registered_;
56 }
57 if (*link == this) {
58 *link = next_registered_;
59 }
60 next_registered_ = nullptr;
61}
62
65 if (!initialized_) {
66 return;
67 }
68 allocation_fault_injection::Reset();
69 while (initialization_count_ != 0) {
70 cleanup_();
71 --initialization_count_;
72 }
73 initialized_ = false;
74}
75
78 for (CurlGlobalLifecycle* lifecycle = registered_lifecycles; lifecycle != nullptr;
79 lifecycle = lifecycle->next_registered_) {
80 lifecycle->FinalizeForProcessExit();
81 }
82}
83
84} // namespace proto_fuzzer
Own the proto runtime's one curl global initialization.
void(*)() CleanupFunction
Process-exit cleanup callback, injectable for lifecycle regression tests.
CurlGlobalLifecycle(CleanupFunction cleanup=nullptr) noexcept
Initialize curl and its allocation hooks for this process.
void FinalizeForProcessExit() noexcept
Release this object's references after the fuzz engine has stopped.
friend void FinalizeRegisteredCurlGlobalLifecyclesForExit() noexcept
Finalize all registered process lifecycles before static destruction.
Process-wide libcurl initialization and final cleanup.