Line | Count | Source |
1 | | /* |
2 | | * Copyright 2026 Google LLC |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #include <fuzzer/FuzzedDataProvider.h> |
18 | | #include <memory> |
19 | | #include <string> |
20 | | |
21 | | |
22 | | #include "tlbmc/pacemaker/pacemaker.h" |
23 | | #include "absl/status/statusor.h" |
24 | | #include "absl/time/time.h" |
25 | | #include "absl/synchronization/mutex.h" |
26 | | #include "absl/log/initialize.h" |
27 | | #include "absl/log/globals.h" |
28 | | |
29 | | namespace milotic_tlbmc { |
30 | | |
31 | | class FuzzedShellCommandExecutor : public ShellCommandExecutor { |
32 | | public: |
33 | 4.08k | void SetFDP(FuzzedDataProvider* fdp) { |
34 | 4.08k | absl::MutexLock lock(&mutex_); |
35 | 4.08k | fdp_ = fdp; |
36 | 4.08k | } |
37 | | |
38 | 19.1k | absl::StatusOr<std::string> Execute(const std::string& command) override { |
39 | 19.1k | absl::MutexLock lock(&mutex_); |
40 | 19.1k | if (!fdp_) return ""; |
41 | 19.1k | if (fdp_->ConsumeBool()) { |
42 | 3.70k | return absl::InternalError("Simulated shell error"); |
43 | 3.70k | } |
44 | 15.4k | return fdp_->ConsumeRandomLengthString(256); |
45 | 19.1k | } |
46 | | |
47 | | private: |
48 | | FuzzedDataProvider* fdp_ ABSL_GUARDED_BY(mutex_) = nullptr; |
49 | | absl::Mutex mutex_; |
50 | | }; |
51 | | |
52 | 2.04k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
53 | 2.04k | static bool initialized = []() { |
54 | 1 | absl::InitializeLog(); |
55 | 1 | absl::SetMinLogLevel(absl::LogSeverityAtLeast::kFatal); |
56 | 1 | return true; |
57 | 1 | }(); |
58 | | |
59 | 2.04k | FuzzedDataProvider fdp(data, size); |
60 | | |
61 | 2.04k | auto executor = std::make_unique<FuzzedShellCommandExecutor>(); |
62 | 2.04k | auto* raw_executor = executor.get(); |
63 | 2.04k | raw_executor->SetFDP(&fdp); |
64 | | |
65 | | // Fuzz Pacemaker exclusively |
66 | 2.04k | auto pacemaker = Pacemaker::Create(absl::Milliseconds(100), std::move(executor)); |
67 | | |
68 | | // Exercise main health checks workflow |
69 | 2.04k | (void)pacemaker->PerformChecks(); |
70 | 2.04k | (void)pacemaker->GetMonitoringData(); |
71 | | |
72 | | // Exercise individual helper functions with fuzzed parameters |
73 | 2.04k | std::string proc_name = fdp.ConsumeRandomLengthString(64); |
74 | 2.04k | (void)pacemaker->GetPid(proc_name); |
75 | 2.04k | (void)pacemaker->GetCpuUsage(proc_name); |
76 | 2.04k | (void)pacemaker->GetLastActiveTimestamp(proc_name); |
77 | 2.04k | (void)pacemaker->IsServiceActive(proc_name); |
78 | 2.04k | (void)pacemaker->RestartService(proc_name); |
79 | | |
80 | 2.04k | int port = fdp.ConsumeIntegral<int>(); |
81 | 2.04k | (void)pacemaker->IsPortListening(port); |
82 | | |
83 | 2.04k | int pid = fdp.ConsumeIntegral<int>(); |
84 | 2.04k | (void)pacemaker->GetMemoryUsage(pid); |
85 | | |
86 | 2.04k | uint8_t err_raw = fdp.ConsumeIntegral<uint8_t>(); |
87 | 2.04k | pacemaker->RecordError(static_cast<ErrorType>(err_raw % 5)); |
88 | | |
89 | 2.04k | (void)pacemaker->GetMonitoringData(); |
90 | | |
91 | 2.04k | raw_executor->SetFDP(nullptr); |
92 | 2.04k | return 0; |
93 | 2.04k | } |
94 | | |
95 | | } // namespace milotic_tlbmc |