blob: b5f581666b923e2889bb57080bbe4fdf9149680f [file] [log] [blame]
Lev Rumyantsev0ea3b6f2020-06-25 13:13:53 -07001/*
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 Eltsindc8bbbb2020-09-21 19:42:07 +020018
19#include <string>
Lev Rumyantsev0ea3b6f2020-06-25 13:13:53 -070020
21#include <android/api-level.h>
22
Evgeny Eltsindc8bbbb2020-09-21 19:42:07 +020023#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 Rumyantsev0ea3b6f2020-06-25 13:13:53 -070042
43#if defined(__arm__)
44#define SYSTEM_LIB(name) \
45 { "/system/lib/" name, "/system/lib/arm/" name }
Evgeny Eltsindc8bbbb2020-09-21 19:42:07 +020046#define APEX_LIB(apex, name) \
47 { "/apex/" apex "/lib/" name, "/system/lib/arm/" name }
Lev Rumyantsev0ea3b6f2020-06-25 13:13:53 -070048#elif defined(__aarch64__)
49#define SYSTEM_LIB(name) \
50 { "/system/lib64/" name, "/system/lib64/arm64/" name }
Evgeny Eltsindc8bbbb2020-09-21 19:42:07 +020051#define APEX_LIB(apex, name) \
52 { "/apex/" apex "/lib64/" name, "/system/lib64/arm64/" name }
Lev Rumyantsev0ea3b6f2020-06-25 13:13:53 -070053#else
54#error "Unknown guest arch"
55#endif
56
Lev Rumyantsev0ea3b6f2020-06-25 13:13:53 -070057/**
Evgeny Eltsindc8bbbb2020-09-21 19:42:07 +020058 * 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 Rumyantsev0ea3b6f2020-06-25 13:13:53 -070060 *
Evgeny Eltsindc8bbbb2020-09-21 19:42:07 +020061 * param out_name pointing to native_bridge path
Lev Rumyantsev0ea3b6f2020-06-25 13:13:53 -070062 * return true if translation is needed
63 */
Evgeny Eltsindc8bbbb2020-09-21 19:42:07 +020064bool translateSystemPathToApexPath(const char* name, std::string* out_name) {
Lev Rumyantsev0ea3b6f2020-06-25 13:13:53 -070065 static constexpr const char* kPathTranslation[][2] = {
Evgeny Eltsindc8bbbb2020-09-21 19:42:07 +020066 // 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 Rumyantsev0ea3b6f2020-06-25 13:13:53 -0700103
104 static constexpr const char* kPathTranslationQ[][2] = {
Evgeny Eltsindc8bbbb2020-09-21 19:42:07 +0200105 // 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 Rumyantsev0ea3b6f2020-06-25 13:13:53 -0700110
Evgeny Eltsindc8bbbb2020-09-21 19:42:07 +0200111 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 Rumyantsev0ea3b6f2020-06-25 13:13:53 -0700128
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 Eltsindc8bbbb2020-09-21 19:42:07 +0200137 *out_name = (*it)[1];
Lev Rumyantsev0ea3b6f2020-06-25 13:13:53 -0700138 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 Eltsindc8bbbb2020-09-21 19:42:07 +0200145 *out_name = (*it)[1];
Lev Rumyantsev0ea3b6f2020-06-25 13:13:53 -0700146 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 Eltsindc8bbbb2020-09-21 19:42:07 +0200154 *out_name = (*it)[1];
Lev Rumyantsev0ea3b6f2020-06-25 13:13:53 -0700155 return true;
156 }
157 }
158
159 return false;
160}