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 <dlfcn.h>
16 #include <jni.h>
17
18 #include <cstdlib>
19
20 #if defined(_ANDROID)
21 #define __jni_version__ JNI_VERSION_1_6
22 #else
23 #define __jni_version__ JNI_VERSION_1_8
24 #endif
25
26 // The jazzer_preload library, if used, forwards all calls to native libFuzzer
27 // hooks such as __sanitizer_cov_trace_cmp8 to the Jazzer JNI library. In order
28 // to load the hook symbols when the library is ready, it needs to be passed a
29 // handle - the JVM loads libraries with RTLD_LOCAL and thus their symbols
30 // wouldn't be found as part of the global lookup procedure.
JNI_OnLoad(JavaVM *,void *)31 jint JNI_OnLoad(JavaVM *, void *) {
32 Dl_info info;
33
34 if (!dladdr(reinterpret_cast<const void *>(&JNI_OnLoad), &info) ||
35 !info.dli_fname) {
36 fprintf(stderr, "Failed to determine our dli_fname\n");
37 abort();
38 }
39
40 void *handle = dlopen(info.dli_fname, RTLD_NOLOAD | RTLD_LAZY);
41 if (handle == nullptr) {
42 fprintf(stderr, "Failed to dlopen self: %s\n", dlerror());
43 abort();
44 }
45
46 void *preload_init = dlsym(RTLD_DEFAULT, "jazzer_preload_init");
47 // jazzer_preload is only preloaded when Jazzer is started with --native, so
48 // not finding this method is an expected error.
49 if (preload_init) {
50 reinterpret_cast<void (*)(void *)>(preload_init)(handle);
51 }
52
53 dlclose(handle);
54
55 return __jni_version__;
56 }
57