• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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