1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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
|