1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "nativebridgesupport"
18
19 #include <android-base/properties.h>
20 #include <dlfcn.h>
21 #include <log/log_main.h>
22
23 #include "native_bridge_support/guest_state_accessor/accessor.h"
24
25 #if defined(__ANDROID__)
26 #include "native_bridge_support/guest_state_accessor/dlext_namespaces.h"
27 #endif
28
OpenSystemLibrary(const char * path,int flags)29 void* OpenSystemLibrary(const char* path, int flags) {
30 #if defined(__ANDROID__)
31 // The system namespace is called "default" for binaries in /system and
32 // "system" for those in the Runtime APEX. Try "system" first since
33 // "default" always exists.
34 // TODO(b/185587109): Get rid of this error prone logic.
35 android_namespace_t* system_ns = android_get_exported_namespace("system");
36 if (system_ns == nullptr) {
37 system_ns = android_get_exported_namespace("default");
38 if (system_ns == nullptr) {
39 ALOGE("Failed to get system namespace for loading %s", path);
40 }
41 }
42 const android_dlextinfo dlextinfo = {
43 .flags = ANDROID_DLEXT_USE_NAMESPACE,
44 .library_namespace = system_ns,
45 };
46
47 return android_dlopen_ext(path, flags, &dlextinfo);
48 #else
49 return dlopen(path, flags);
50 #endif
51 }
52
LoadGuestStateRegisters(const void * guest_state_data,size_t guest_state_data_size,NativeBridgeGuestRegs * guest_regs)53 int LoadGuestStateRegisters(const void* guest_state_data,
54 size_t guest_state_data_size,
55 NativeBridgeGuestRegs* guest_regs) {
56 std::string library_name = android::base::GetProperty(
57 "ro.dalvik.vm.native.bridge", /*default_value=*/"");
58 if (library_name.empty()) {
59 return NATIVE_BRIDGE_GUEST_STATE_ACCESSOR_ERROR_INVALID_STATE;
60 }
61
62 void *proxy = OpenSystemLibrary(library_name.c_str(), RTLD_NOW | RTLD_LOCAL);
63 if (!proxy) {
64 ALOGE("dlopen failed: %s: %s", library_name.c_str(), dlerror());
65 return NATIVE_BRIDGE_GUEST_STATE_ACCESSOR_ERROR_INVALID_STATE;
66 }
67
68 using LoadGuestStateRegistersFunc =
69 int (*)(const void *, size_t, NativeBridgeGuestRegs *);
70 LoadGuestStateRegistersFunc LoadGuestStateRegistersImpl =
71 reinterpret_cast<LoadGuestStateRegistersFunc>(
72 dlsym(proxy, "LoadGuestStateRegisters"));
73 if (!LoadGuestStateRegistersImpl) {
74 ALOGE("failed to initialize proxy library LoadGuestStateRegisters: %s", dlerror());
75 return NATIVE_BRIDGE_GUEST_STATE_ACCESSOR_ERROR_INVALID_STATE;
76 }
77
78 return LoadGuestStateRegistersImpl(guest_state_data, guest_state_data_size, guest_regs);
79 }
80