summaryrefslogtreecommitdiffstats
path: root/tools/fuzzing/shmem/SharedMemoryFuzzer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/fuzzing/shmem/SharedMemoryFuzzer.cpp')
-rw-r--r--tools/fuzzing/shmem/SharedMemoryFuzzer.cpp122
1 files changed, 122 insertions, 0 deletions
diff --git a/tools/fuzzing/shmem/SharedMemoryFuzzer.cpp b/tools/fuzzing/shmem/SharedMemoryFuzzer.cpp
new file mode 100644
index 0000000000..49a79fa975
--- /dev/null
+++ b/tools/fuzzing/shmem/SharedMemoryFuzzer.cpp
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "FuzzingMutate.h"
+#include "FuzzingTraits.h"
+#include "nsDebug.h"
+#include "prenv.h"
+#include "SharedMemoryFuzzer.h"
+
+#define SHMEM_FUZZER_DEFAULT_MUTATION_PROBABILITY 2
+#define SHMEM_FUZZER_DEFAULT_MUTATION_FACTOR 500
+#define SHMEM_FUZZER_LOG(fmt, args...) \
+ if (SharedMemoryFuzzer::IsLoggingEnabled()) { \
+ printf_stderr("[SharedMemoryFuzzer] " fmt "\n", ##args); \
+ }
+
+namespace mozilla {
+namespace ipc {
+
+using namespace fuzzing;
+
+/* static */
+bool SharedMemoryFuzzer::IsLoggingEnabled() {
+ static bool sInitialized = false;
+ static bool sIsLoggingEnabled = false;
+
+ if (!sInitialized) {
+ sIsLoggingEnabled = !!PR_GetEnv("SHMEM_FUZZER_ENABLE_LOGGING");
+ sInitialized = true;
+ }
+ return sIsLoggingEnabled;
+}
+
+/* static */
+bool SharedMemoryFuzzer::IsEnabled() {
+ static bool sInitialized = false;
+ static bool sIsFuzzerEnabled = false;
+
+ if (!sInitialized) {
+ sIsFuzzerEnabled = !!PR_GetEnv("SHMEM_FUZZER_ENABLE");
+ }
+ return sIsFuzzerEnabled;
+}
+
+/* static */
+uint64_t SharedMemoryFuzzer::MutationProbability() {
+ static uint64_t sPropValue = SHMEM_FUZZER_DEFAULT_MUTATION_PROBABILITY;
+ static bool sInitialized = false;
+
+ if (sInitialized) {
+ return sPropValue;
+ }
+ sInitialized = true;
+
+ const char* probability = PR_GetEnv("SHMEM_FUZZER_MUTATION_PROBABILITY");
+ if (probability) {
+ long n = std::strtol(probability, nullptr, 10);
+ if (n != 0) {
+ sPropValue = n;
+ return sPropValue;
+ }
+ }
+ return sPropValue;
+}
+
+/* static */
+uint64_t SharedMemoryFuzzer::MutationFactor() {
+ static uint64_t sPropValue = SHMEM_FUZZER_DEFAULT_MUTATION_FACTOR;
+ static bool sInitialized = false;
+
+ if (sInitialized) {
+ return sPropValue;
+ }
+ sInitialized = true;
+
+ const char* factor = PR_GetEnv("SHMEM_FUZZER_MUTATION_FACTOR");
+ if (factor) {
+ long n = strtol(factor, nullptr, 10);
+ if (n != 0) {
+ sPropValue = n;
+ return sPropValue;
+ }
+ }
+ return sPropValue;
+}
+
+/* static */
+void* SharedMemoryFuzzer::MutateSharedMemory(void* aMemory, size_t aSize) {
+ if (!IsEnabled()) {
+ return aMemory;
+ }
+
+ if (aSize == 0) {
+ /* Shmem opened from foreign handle. */
+ SHMEM_FUZZER_LOG("shmem is of size 0.");
+ return aMemory;
+ }
+
+ if (!aMemory) {
+ /* Memory space is not mapped. */
+ SHMEM_FUZZER_LOG("shmem memory space is not mapped.");
+ return aMemory;
+ }
+
+ // The likelihood when a value gets fuzzed of this object.
+ if (!FuzzingTraits::Sometimes(MutationProbability())) {
+ return aMemory;
+ }
+
+ const size_t max = FuzzingTraits::Frequency(aSize, MutationFactor());
+ SHMEM_FUZZER_LOG("shmem of size: %zu / mutations: %zu", aSize, max);
+ for (size_t i = 0; i < max; i++) {
+ FuzzingMutate::ChangeBit((uint8_t*)aMemory, aSize);
+ }
+ return aMemory;
+}
+
+} // namespace ipc
+} // namespace mozilla