1 // Copyright 2022 Code Intelligence GmbH
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <jni.h>
16
17 #include <cstddef>
18 #include <cstdint>
19
20 #include "com_code_intelligence_jazzer_runtime_FuzzerCallbacks.h"
21 #include "com_code_intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical.h"
22 #include "com_code_intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical.h"
23 #include "com_code_intelligence_jazzer_runtime_FuzzerCallbacksWithPc.h"
24 #include "src/main/native/com/code_intelligence/jazzer/driver/sanitizer_hooks_with_pc.h"
25
26 extern "C" {
27 void __sanitizer_weak_hook_compare_bytes(void *caller_pc, const void *s1,
28 const void *s2, std::size_t n1,
29 std::size_t n2, int result);
30 void __sanitizer_weak_hook_strstr(void *caller_pc, const char *s1,
31 const char *s2, const char *result);
32 void __sanitizer_weak_hook_memmem(void *caller_pc, const void *b1,
33 std::size_t n1, const void *s2,
34 std::size_t n2, void *result);
35 void __sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2);
36 void __sanitizer_cov_trace_cmp8(uint64_t arg1, uint64_t arg2);
37
38 void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases);
39
40 void __sanitizer_cov_trace_div4(uint32_t val);
41 void __sanitizer_cov_trace_div8(uint64_t val);
42
43 void __sanitizer_cov_trace_gep(uintptr_t idx);
44 }
45
idToPc(jint id)46 inline __attribute__((always_inline)) void *idToPc(jint id) {
47 return reinterpret_cast<void *>(static_cast<uintptr_t>(id));
48 }
49
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacks_traceCmpInt(JNIEnv * env,jclass cls,jint value1,jint value2,jint id)50 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacks_traceCmpInt(
51 JNIEnv *env, jclass cls, jint value1, jint value2, jint id) {
52 __sanitizer_cov_trace_cmp4(value1, value2);
53 }
54
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksWithPc_traceCmpInt(JNIEnv * env,jclass cls,jint value1,jint value2,jint id)55 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksWithPc_traceCmpInt(
56 JNIEnv *env, jclass cls, jint value1, jint value2, jint id) {
57 __sanitizer_cov_trace_cmp4_with_pc(idToPc(id), value1, value2);
58 }
59
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceCmpInt(JNIEnv * env,jclass cls,jint value1,jint value2,jint id)60 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceCmpInt(
61 JNIEnv *env, jclass cls, jint value1, jint value2, jint id) {
62 __sanitizer_cov_trace_cmp4(value1, value2);
63 }
64
65 extern "C" JNIEXPORT void JNICALL
JavaCritical_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceCmpInt(jint value1,jint value2,jint id)66 JavaCritical_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceCmpInt(
67 jint value1, jint value2, jint id) {
68 __sanitizer_cov_trace_cmp4(value1, value2);
69 }
70
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacks_traceSwitch(JNIEnv * env,jclass cls,jlong switch_value,jlongArray libfuzzer_case_values,jint id)71 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacks_traceSwitch(
72 JNIEnv *env, jclass cls, jlong switch_value,
73 jlongArray libfuzzer_case_values, jint id) {
74 jlong *case_values =
75 env->GetLongArrayElements(libfuzzer_case_values, nullptr);
76 if (env->ExceptionCheck()) env->ExceptionDescribe();
77 __sanitizer_cov_trace_switch(switch_value,
78 reinterpret_cast<uint64_t *>(case_values));
79 env->ReleaseLongArrayElements(libfuzzer_case_values, case_values, JNI_ABORT);
80 if (env->ExceptionCheck()) env->ExceptionDescribe();
81 }
82
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical_traceSwitch(JNIEnv * env,jclass cls,jlong switch_value,jlongArray libfuzzer_case_values,jint id)83 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical_traceSwitch(
84 JNIEnv *env, jclass cls, jlong switch_value,
85 jlongArray libfuzzer_case_values, jint id) {
86 auto *case_values = static_cast<jlong *>(
87 env->GetPrimitiveArrayCritical(libfuzzer_case_values, nullptr));
88 __sanitizer_cov_trace_switch(switch_value,
89 reinterpret_cast<uint64_t *>(case_values));
90 env->ReleasePrimitiveArrayCritical(libfuzzer_case_values, case_values,
91 JNI_ABORT);
92 }
93
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksWithPc_traceSwitch(JNIEnv * env,jclass cls,jlong switch_value,jlongArray libfuzzer_case_values,jint id)94 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksWithPc_traceSwitch(
95 JNIEnv *env, jclass cls, jlong switch_value,
96 jlongArray libfuzzer_case_values, jint id) {
97 jlong *case_values =
98 env->GetLongArrayElements(libfuzzer_case_values, nullptr);
99 if (env->ExceptionCheck()) env->ExceptionDescribe();
100 __sanitizer_cov_trace_switch_with_pc(
101 idToPc(id), switch_value, reinterpret_cast<uint64_t *>(case_values));
102 env->ReleaseLongArrayElements(libfuzzer_case_values, case_values, JNI_ABORT);
103 if (env->ExceptionCheck()) env->ExceptionDescribe();
104 }
105
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceSwitch(JNIEnv * env,jclass cls,jlong switch_value,jlongArray libfuzzer_case_values,jint id)106 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceSwitch(
107 JNIEnv *env, jclass cls, jlong switch_value,
108 jlongArray libfuzzer_case_values, jint id) {
109 Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical_traceSwitch(
110 env, cls, switch_value, libfuzzer_case_values, id);
111 }
112
113 extern "C" JNIEXPORT void JNICALL
JavaCritical_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceSwitch(jlong switch_value,jint case_values_length,jlong * case_values,jint id)114 JavaCritical_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceSwitch(
115 jlong switch_value, jint case_values_length, jlong *case_values, jint id) {
116 __sanitizer_cov_trace_switch(switch_value,
117 reinterpret_cast<uint64_t *>(case_values));
118 }
119
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacks_traceMemcmp(JNIEnv * env,jclass cls,jbyteArray b1,jbyteArray b2,jint result,jint id)120 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacks_traceMemcmp(
121 JNIEnv *env, jclass cls, jbyteArray b1, jbyteArray b2, jint result,
122 jint id) {
123 jbyte *b1_native = env->GetByteArrayElements(b1, nullptr);
124 if (env->ExceptionCheck()) env->ExceptionDescribe();
125 jbyte *b2_native = env->GetByteArrayElements(b2, nullptr);
126 if (env->ExceptionCheck()) env->ExceptionDescribe();
127 jint b1_length = env->GetArrayLength(b1);
128 if (env->ExceptionCheck()) env->ExceptionDescribe();
129 jint b2_length = env->GetArrayLength(b2);
130 if (env->ExceptionCheck()) env->ExceptionDescribe();
131 __sanitizer_weak_hook_compare_bytes(idToPc(id), b1_native, b2_native,
132 b1_length, b2_length, result);
133 env->ReleaseByteArrayElements(b1, b1_native, JNI_ABORT);
134 if (env->ExceptionCheck()) env->ExceptionDescribe();
135 env->ReleaseByteArrayElements(b2, b2_native, JNI_ABORT);
136 if (env->ExceptionCheck()) env->ExceptionDescribe();
137 }
138
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical_traceMemcmp(JNIEnv * env,jclass cls,jbyteArray b1,jbyteArray b2,jint result,jint id)139 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical_traceMemcmp(
140 JNIEnv *env, jclass cls, jbyteArray b1, jbyteArray b2, jint result,
141 jint id) {
142 auto *b1_native =
143 static_cast<jbyte *>(env->GetPrimitiveArrayCritical(b1, nullptr));
144 auto *b2_native =
145 static_cast<jbyte *>(env->GetPrimitiveArrayCritical(b2, nullptr));
146 jint b1_length = env->GetArrayLength(b1);
147 jint b2_length = env->GetArrayLength(b2);
148 __sanitizer_weak_hook_compare_bytes(idToPc(id), b1_native, b2_native,
149 b1_length, b2_length, result);
150 env->ReleasePrimitiveArrayCritical(b1, b1_native, JNI_ABORT);
151 env->ReleasePrimitiveArrayCritical(b2, b2_native, JNI_ABORT);
152 }
153
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceMemcmp(JNIEnv * env,jclass cls,jbyteArray b1,jbyteArray b2,jint result,jint id)154 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceMemcmp(
155 JNIEnv *env, jclass cls, jbyteArray b1, jbyteArray b2, jint result,
156 jint id) {
157 Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical_traceMemcmp(
158 env, cls, b1, b2, result, id);
159 }
160
161 extern "C" JNIEXPORT void JNICALL
JavaCritical_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceMemcmp(jint b1_length,jbyte * b1,jint b2_length,jbyte * b2,jint result,jint id)162 JavaCritical_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceMemcmp(
163 jint b1_length, jbyte *b1, jint b2_length, jbyte *b2, jint result,
164 jint id) {
165 __sanitizer_weak_hook_compare_bytes(idToPc(id), b1, b2, b1_length, b2_length,
166 result);
167 }
168
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacks_traceStrstr(JNIEnv * env,jclass cls,jstring s1,jstring s2,jint id)169 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacks_traceStrstr(
170 JNIEnv *env, jclass cls, jstring s1, jstring s2, jint id) {
171 const char *s1_native = env->GetStringUTFChars(s1, nullptr);
172 if (env->ExceptionCheck()) env->ExceptionDescribe();
173 const char *s2_native = env->GetStringUTFChars(s2, nullptr);
174 if (env->ExceptionCheck()) env->ExceptionDescribe();
175 // libFuzzer currently ignores the result, which allows us to simply pass a
176 // valid but arbitrary pointer here instead of performing an actual strstr
177 // operation.
178 __sanitizer_weak_hook_strstr(idToPc(id), s1_native, s2_native, s1_native);
179 env->ReleaseStringUTFChars(s1, s1_native);
180 if (env->ExceptionCheck()) env->ExceptionDescribe();
181 env->ReleaseStringUTFChars(s2, s2_native);
182 if (env->ExceptionCheck()) env->ExceptionDescribe();
183 }
184
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical_traceStrstr(JNIEnv * env,jclass cls,jstring s1,jstring s2,jint id)185 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical_traceStrstr(
186 JNIEnv *env, jclass cls, jstring s1, jstring s2, jint id) {
187 const char *s2_native = env->GetStringUTFChars(s2, nullptr);
188 __sanitizer_weak_hook_strstr(idToPc(id), nullptr, s2_native, s2_native);
189 env->ReleaseStringUTFChars(s2, s2_native);
190 }
191
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical_traceStrstrInternal(JNIEnv * env,jclass cls,jbyteArray needle,jint id)192 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical_traceStrstrInternal(
193 JNIEnv *env, jclass cls, jbyteArray needle, jint id) {
194 auto *needle_native =
195 static_cast<jbyte *>(env->GetPrimitiveArrayCritical(needle, nullptr));
196 jint needle_length = env->GetArrayLength(needle);
197 __sanitizer_weak_hook_memmem(idToPc(id), nullptr, 0, needle_native,
198 needle_length, nullptr);
199 env->ReleasePrimitiveArrayCritical(needle, needle_native, JNI_ABORT);
200 }
201
Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceStrstrInternal(JNIEnv * env,jclass cls,jbyteArray needle,jint id)202 void Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceStrstrInternal(
203 JNIEnv *env, jclass cls, jbyteArray needle, jint id) {
204 Java_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedNonCritical_traceStrstrInternal(
205 env, cls, needle, id);
206 }
207
208 extern "C" JNIEXPORT void JNICALL
JavaCritical_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceStrstrInternal(jint needle_length,jbyte * needle,jint id)209 JavaCritical_com_code_1intelligence_jazzer_runtime_FuzzerCallbacksOptimizedCritical_traceStrstrInternal(
210 jint needle_length, jbyte *needle, jint id) {
211 __sanitizer_weak_hook_memmem(idToPc(id), nullptr, 0, needle, needle_length,
212 nullptr);
213 }
214