Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2020 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 | #include "linker_translate_path.h" |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 18 | |
| 19 | #include <string> |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 20 | |
| 21 | #include <android/api-level.h> |
| 22 | |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 23 | #include "linker.h" |
| 24 | |
| 25 | // Handle dlopen by full path. |
| 26 | // |
| 27 | // 1. Translate original path to native_bridge path. |
| 28 | // |
| 29 | // Native bridge libraries reside in $LIB/$ABI subdirectory. For example: |
| 30 | // /system/lib/liblog.so -> /system/lib/arm/liblog.so |
| 31 | // |
| 32 | // Native bridge libraries do not use apex. For example: |
| 33 | // /apex/com.android.i18n/lib/libicuuc.so -> /system/lib/arm/libicuuc.so |
| 34 | // |
| 35 | // 2. Repeat linker workaround to open apex libraries by system path (see http://b/121248172). |
| 36 | // |
| 37 | // For older target SDK versions, linker allows to open apex libraries by system path, so it does: |
| 38 | // /system/lib/libicuuc.so -> /apex/com.android.art/lib/libicuuc.so |
| 39 | // |
| 40 | // Adding native bridge path translation, we get: |
| 41 | // /system/lib/libicuuc.so -> /apex/com.android.art/lib/libicuuc.so -> /system/lib/arm/libicuuc.so |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 42 | |
| 43 | #if defined(__arm__) |
| 44 | #define SYSTEM_LIB(name) \ |
| 45 | { "/system/lib/" name, "/system/lib/arm/" name } |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 46 | #define APEX_LIB(apex, name) \ |
| 47 | { "/apex/" apex "/lib/" name, "/system/lib/arm/" name } |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 48 | #elif defined(__aarch64__) |
| 49 | #define SYSTEM_LIB(name) \ |
| 50 | { "/system/lib64/" name, "/system/lib64/arm64/" name } |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 51 | #define APEX_LIB(apex, name) \ |
| 52 | { "/apex/" apex "/lib64/" name, "/system/lib64/arm64/" name } |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 53 | #else |
| 54 | #error "Unknown guest arch" |
| 55 | #endif |
| 56 | |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 57 | /** |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 58 | * Translate /system path or /apex path to native_bridge path |
| 59 | * Function name is misleading, as it overrides the corresponding function in original linker. |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 60 | * |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 61 | * param out_name pointing to native_bridge path |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 62 | * return true if translation is needed |
| 63 | */ |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 64 | bool translateSystemPathToApexPath(const char* name, std::string* out_name) { |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 65 | static constexpr const char* kPathTranslation[][2] = { |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 66 | // Libraries accessible by system path. |
| 67 | SYSTEM_LIB("libEGL.so"), |
| 68 | SYSTEM_LIB("libGLESv1_CM.so"), |
| 69 | SYSTEM_LIB("libGLESv2.so"), |
| 70 | SYSTEM_LIB("libGLESv3.so"), |
| 71 | SYSTEM_LIB("libOpenMAXAL.so"), |
| 72 | SYSTEM_LIB("libOpenSLES.so"), |
| 73 | SYSTEM_LIB("libRS.so"), |
| 74 | SYSTEM_LIB("libaaudio.so"), |
| 75 | SYSTEM_LIB("libamidi.so"), |
| 76 | SYSTEM_LIB("libandroid.so"), |
| 77 | SYSTEM_LIB("libbinder_ndk.so"), |
| 78 | SYSTEM_LIB("libc.so"), |
| 79 | SYSTEM_LIB("libcamera2ndk.so"), |
| 80 | SYSTEM_LIB("libdl.so"), |
| 81 | SYSTEM_LIB("libjnigraphics.so"), |
| 82 | SYSTEM_LIB("liblog.so"), |
| 83 | SYSTEM_LIB("libm.so"), |
| 84 | SYSTEM_LIB("libmediandk.so"), |
| 85 | SYSTEM_LIB("libnativewindow.so"), |
| 86 | SYSTEM_LIB("libstdc++.so"), |
| 87 | SYSTEM_LIB("libsync.so"), |
| 88 | SYSTEM_LIB("libvulkan.so"), |
| 89 | SYSTEM_LIB("libwebviewchromium_plat_support.so"), |
| 90 | SYSTEM_LIB("libz.so"), |
| 91 | // Apex/system after R. |
| 92 | APEX_LIB("com.android.i18n", "libandroidicu.so"), |
| 93 | APEX_LIB("com.android.i18n", "libicui18n.so"), |
| 94 | APEX_LIB("com.android.i18n", "libicuuc.so"), |
| 95 | // Apex/system on R (see http://b/161958857). |
| 96 | APEX_LIB("com.android.art", "libicui18n.so"), |
| 97 | APEX_LIB("com.android.art", "libicuuc.so"), |
| 98 | APEX_LIB("com.android.art", "libnativehelper.so"), |
| 99 | // Apex/system on Q. |
| 100 | APEX_LIB("com.android.runtime", "libicui18n.so"), |
| 101 | APEX_LIB("com.android.runtime", "libicuuc.so"), |
| 102 | }; |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 103 | |
| 104 | static constexpr const char* kPathTranslationQ[][2] = { |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 105 | // Apps targeting below Q can open apex libraries by system path. |
| 106 | SYSTEM_LIB("libicui18n.so"), |
| 107 | SYSTEM_LIB("libicuuc.so"), |
| 108 | SYSTEM_LIB("libneuralnetworks.so"), |
| 109 | }; |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 110 | |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 111 | static constexpr const char* kPathTranslationN[][2] = { |
| 112 | // Apps targeting below N can open greylisted libraries. |
| 113 | SYSTEM_LIB("libandroid_runtime.so"), |
| 114 | SYSTEM_LIB("libbinder.so"), |
| 115 | SYSTEM_LIB("libcrypto.so"), |
| 116 | SYSTEM_LIB("libcutils.so"), |
| 117 | SYSTEM_LIB("libexpat.so"), |
| 118 | SYSTEM_LIB("libgui.so"), |
| 119 | SYSTEM_LIB("libmedia.so"), |
| 120 | SYSTEM_LIB("libnativehelper.so"), |
| 121 | SYSTEM_LIB("libssl.so"), |
| 122 | SYSTEM_LIB("libstagefright.so"), |
| 123 | SYSTEM_LIB("libsqlite.so"), |
| 124 | SYSTEM_LIB("libui.so"), |
| 125 | SYSTEM_LIB("libutils.so"), |
| 126 | SYSTEM_LIB("libvorbisidec.so"), |
| 127 | }; |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 128 | |
| 129 | if (name == nullptr) { |
| 130 | return false; |
| 131 | } |
| 132 | |
| 133 | auto comparator = [name](auto p) { return strcmp(name, p[0]) == 0; }; |
| 134 | |
| 135 | if (auto it = std::find_if(std::begin(kPathTranslation), std::end(kPathTranslation), comparator); |
| 136 | it != std::end(kPathTranslation)) { |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 137 | *out_name = (*it)[1]; |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 138 | return true; |
| 139 | } |
| 140 | |
| 141 | if (get_application_target_sdk_version() < __ANDROID_API_Q__) { |
| 142 | if (auto it = |
| 143 | std::find_if(std::begin(kPathTranslationQ), std::end(kPathTranslationQ), comparator); |
| 144 | it != std::end(kPathTranslationQ)) { |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 145 | *out_name = (*it)[1]; |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 146 | return true; |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | if (get_application_target_sdk_version() < __ANDROID_API_N__) { |
| 151 | if (auto it = |
| 152 | std::find_if(std::begin(kPathTranslationN), std::end(kPathTranslationN), comparator); |
| 153 | it != std::end(kPathTranslationN)) { |
Evgeny Eltsin | dc8bbbb | 2020-09-21 19:42:07 +0200 | [diff] [blame] | 154 | *out_name = (*it)[1]; |
Lev Rumyantsev | 0ea3b6f | 2020-06-25 13:13:53 -0700 | [diff] [blame] | 155 | return true; |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | return false; |
| 160 | } |