Source code

Revision control

Copy as Markdown

Other Tools

/* -*- 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