1/*
2 * Copyright (C) 2015 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 "nativeloader/native_loader.h"
18#include <nativehelper/ScopedUtfChars.h>
19
20#include <dlfcn.h>
21#ifdef __ANDROID__
22#define LOG_TAG "libnativeloader"
23#include "nativeloader/dlext_namespaces.h"
24#include "cutils/properties.h"
25#include "log/log.h"
26#endif
27#include "nativebridge/native_bridge.h"
28
29#include <algorithm>
30#include <vector>
31#include <string>
32#include <mutex>
33
34#include <android-base/file.h>
35#include <android-base/macros.h>
36#include <android-base/strings.h>
37
38#define CHECK(predicate) LOG_ALWAYS_FATAL_IF(!(predicate),\
39                                             "%s:%d: %s CHECK '" #predicate "' failed.",\
40                                             __FILE__, __LINE__, __FUNCTION__)
41
42namespace android {
43
44#if defined(__ANDROID__)
45class NativeLoaderNamespace {
46 public:
47  NativeLoaderNamespace()
48      : android_ns_(nullptr), native_bridge_ns_(nullptr) { }
49
50  explicit NativeLoaderNamespace(android_namespace_t* ns)
51      : android_ns_(ns), native_bridge_ns_(nullptr) { }
52
53  explicit NativeLoaderNamespace(native_bridge_namespace_t* ns)
54      : android_ns_(nullptr), native_bridge_ns_(ns) { }
55
56  NativeLoaderNamespace(NativeLoaderNamespace&& that) = default;
57  NativeLoaderNamespace(const NativeLoaderNamespace& that) = default;
58
59  NativeLoaderNamespace& operator=(const NativeLoaderNamespace& that) = default;
60
61  android_namespace_t* get_android_ns() const {
62    CHECK(native_bridge_ns_ == nullptr);
63    return android_ns_;
64  }
65
66  native_bridge_namespace_t* get_native_bridge_ns() const {
67    CHECK(android_ns_ == nullptr);
68    return native_bridge_ns_;
69  }
70
71  bool is_android_namespace() const {
72    return native_bridge_ns_ == nullptr;
73  }
74
75 private:
76  // Only one of them can be not null
77  android_namespace_t* android_ns_;
78  native_bridge_namespace_t* native_bridge_ns_;
79};
80
81static constexpr const char* kPublicNativeLibrariesSystemConfigPathFromRoot =
82                                  "/etc/public.libraries.txt";
83static constexpr const char* kPublicNativeLibrariesVendorConfig =
84                                  "/vendor/etc/public.libraries.txt";
85static constexpr const char* kLlndkNativeLibrariesSystemConfigPathFromRoot =
86                                  "/etc/llndk.libraries.txt";
87static constexpr const char* kVndkspNativeLibrariesSystemConfigPathFromRoot =
88                                  "/etc/vndksp.libraries.txt";
89
90
91// The device may be configured to have the vendor libraries loaded to a separate namespace.
92// For historical reasons this namespace was named sphal but effectively it is intended
93// to use to load vendor libraries to separate namespace with controlled interface between
94// vendor and system namespaces.
95static constexpr const char* kVendorNamespaceName = "sphal";
96
97static constexpr const char* kVndkNamespaceName = "vndk";
98
99static constexpr const char* kClassloaderNamespaceName = "classloader-namespace";
100static constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace";
101
102// (http://b/27588281) This is a workaround for apps using custom classloaders and calling
103// System.load() with an absolute path which is outside of the classloader library search path.
104// This list includes all directories app is allowed to access this way.
105static constexpr const char* kWhitelistedDirectories = "/data:/mnt/expand";
106
107static bool is_debuggable() {
108  char debuggable[PROP_VALUE_MAX];
109  property_get("ro.debuggable", debuggable, "0");
110  return std::string(debuggable) == "1";
111}
112
113class LibraryNamespaces {
114 public:
115  LibraryNamespaces() : initialized_(false) { }
116
117  bool Create(JNIEnv* env,
118              uint32_t target_sdk_version,
119              jobject class_loader,
120              bool is_shared,
121              bool is_for_vendor,
122              jstring java_library_path,
123              jstring java_permitted_path,
124              NativeLoaderNamespace* ns,
125              std::string* error_msg) {
126    std::string library_path; // empty string by default.
127
128    if (java_library_path != nullptr) {
129      ScopedUtfChars library_path_utf_chars(env, java_library_path);
130      library_path = library_path_utf_chars.c_str();
131    }
132
133    // (http://b/27588281) This is a workaround for apps using custom
134    // classloaders and calling System.load() with an absolute path which
135    // is outside of the classloader library search path.
136    //
137    // This part effectively allows such a classloader to access anything
138    // under /data and /mnt/expand
139    std::string permitted_path = kWhitelistedDirectories;
140
141    if (java_permitted_path != nullptr) {
142      ScopedUtfChars path(env, java_permitted_path);
143      if (path.c_str() != nullptr && path.size() > 0) {
144        permitted_path = permitted_path + ":" + path.c_str();
145      }
146    }
147
148    if (!initialized_ && !InitPublicNamespace(library_path.c_str(), error_msg)) {
149      return false;
150    }
151
152    bool found = FindNamespaceByClassLoader(env, class_loader, nullptr);
153
154    LOG_ALWAYS_FATAL_IF(found,
155                        "There is already a namespace associated with this classloader");
156
157    uint64_t namespace_type = ANDROID_NAMESPACE_TYPE_ISOLATED;
158    if (is_shared) {
159      namespace_type |= ANDROID_NAMESPACE_TYPE_SHARED;
160    }
161
162    if (target_sdk_version < 24) {
163      namespace_type |= ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED;
164    }
165
166    NativeLoaderNamespace parent_ns;
167    bool found_parent_namespace = FindParentNamespaceByClassLoader(env, class_loader, &parent_ns);
168
169    bool is_native_bridge = false;
170
171    if (found_parent_namespace) {
172      is_native_bridge = !parent_ns.is_android_namespace();
173    } else if (!library_path.empty()) {
174      is_native_bridge = NativeBridgeIsPathSupported(library_path.c_str());
175    }
176
177    std::string system_exposed_libraries = system_public_libraries_;
178    const char* namespace_name = kClassloaderNamespaceName;
179    android_namespace_t* vndk_ns = nullptr;
180    if (is_for_vendor && !is_shared) {
181      LOG_FATAL_IF(is_native_bridge, "Unbundled vendor apk must not use translated architecture");
182
183      // For vendor apks, give access to the vendor lib even though
184      // they are treated as unbundled; the libs and apks are still bundled
185      // together in the vendor partition.
186#if defined(__LP64__)
187      std::string vendor_lib_path = "/vendor/lib64";
188#else
189      std::string vendor_lib_path = "/vendor/lib";
190#endif
191      library_path = library_path + ":" + vendor_lib_path.c_str();
192      permitted_path = permitted_path + ":" + vendor_lib_path.c_str();
193
194      // Also give access to LLNDK libraries since they are available to vendors
195      system_exposed_libraries = system_exposed_libraries + ":" + system_llndk_libraries_.c_str();
196
197      // Give access to VNDK-SP libraries from the 'vndk' namespace.
198      vndk_ns = android_get_exported_namespace(kVndkNamespaceName);
199      LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr,
200                          "Cannot find \"%s\" namespace for vendor apks", kVndkNamespaceName);
201
202      // Different name is useful for debugging
203      namespace_name = kVendorClassloaderNamespaceName;
204      ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str());
205    }
206
207    NativeLoaderNamespace native_loader_ns;
208    if (!is_native_bridge) {
209      android_namespace_t* ns = android_create_namespace(namespace_name,
210                                                         nullptr,
211                                                         library_path.c_str(),
212                                                         namespace_type,
213                                                         permitted_path.c_str(),
214                                                         parent_ns.get_android_ns());
215      if (ns == nullptr) {
216        *error_msg = dlerror();
217        return false;
218      }
219
220      // Note that when vendor_ns is not configured this function will return nullptr
221      // and it will result in linking vendor_public_libraries_ to the default namespace
222      // which is expected behavior in this case.
223      android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName);
224
225      if (!android_link_namespaces(ns, nullptr, system_exposed_libraries.c_str())) {
226        *error_msg = dlerror();
227        return false;
228      }
229
230      if (vndk_ns != nullptr && !system_vndksp_libraries_.empty()) {
231        // vendor apks are allowed to use VNDK-SP libraries.
232        if (!android_link_namespaces(ns, vndk_ns, system_vndksp_libraries_.c_str())) {
233          *error_msg = dlerror();
234          return false;
235        }
236      }
237
238      if (!vendor_public_libraries_.empty()) {
239        if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) {
240          *error_msg = dlerror();
241          return false;
242        }
243      }
244
245      native_loader_ns = NativeLoaderNamespace(ns);
246    } else {
247      native_bridge_namespace_t* ns = NativeBridgeCreateNamespace(namespace_name,
248                                                                  nullptr,
249                                                                  library_path.c_str(),
250                                                                  namespace_type,
251                                                                  permitted_path.c_str(),
252                                                                  parent_ns.get_native_bridge_ns());
253
254      if (ns == nullptr) {
255        *error_msg = NativeBridgeGetError();
256        return false;
257      }
258
259      native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace();
260
261      if (!NativeBridgeLinkNamespaces(ns, nullptr, system_exposed_libraries.c_str())) {
262        *error_msg = NativeBridgeGetError();
263        return false;
264      }
265
266      if (!vendor_public_libraries_.empty()) {
267        if (!NativeBridgeLinkNamespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) {
268          *error_msg = NativeBridgeGetError();
269          return false;
270        }
271      }
272
273      native_loader_ns = NativeLoaderNamespace(ns);
274    }
275
276    namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), native_loader_ns));
277
278    *ns = native_loader_ns;
279    return true;
280  }
281
282  bool FindNamespaceByClassLoader(JNIEnv* env, jobject class_loader, NativeLoaderNamespace* ns) {
283    auto it = std::find_if(namespaces_.begin(), namespaces_.end(),
284                [&](const std::pair<jweak, NativeLoaderNamespace>& value) {
285                  return env->IsSameObject(value.first, class_loader);
286                });
287    if (it != namespaces_.end()) {
288      if (ns != nullptr) {
289        *ns = it->second;
290      }
291
292      return true;
293    }
294
295    return false;
296  }
297
298  void Initialize() {
299    // Once public namespace is initialized there is no
300    // point in running this code - it will have no effect
301    // on the current list of public libraries.
302    if (initialized_) {
303      return;
304    }
305
306    std::vector<std::string> sonames;
307    const char* android_root_env = getenv("ANDROID_ROOT");
308    std::string root_dir = android_root_env != nullptr ? android_root_env : "/system";
309    std::string public_native_libraries_system_config =
310            root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot;
311    std::string llndk_native_libraries_system_config =
312            root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot;
313    std::string vndksp_native_libraries_system_config =
314            root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot;
315
316    std::string error_msg;
317    LOG_ALWAYS_FATAL_IF(!ReadConfig(public_native_libraries_system_config, &sonames, &error_msg),
318                        "Error reading public native library list from \"%s\": %s",
319                        public_native_libraries_system_config.c_str(), error_msg.c_str());
320
321    // For debuggable platform builds use ANDROID_ADDITIONAL_PUBLIC_LIBRARIES environment
322    // variable to add libraries to the list. This is intended for platform tests only.
323    if (is_debuggable()) {
324      const char* additional_libs = getenv("ANDROID_ADDITIONAL_PUBLIC_LIBRARIES");
325      if (additional_libs != nullptr && additional_libs[0] != '\0') {
326        std::vector<std::string> additional_libs_vector = base::Split(additional_libs, ":");
327        std::copy(additional_libs_vector.begin(),
328                  additional_libs_vector.end(),
329                  std::back_inserter(sonames));
330      }
331    }
332
333    // android_init_namespaces() expects all the public libraries
334    // to be loaded so that they can be found by soname alone.
335    //
336    // TODO(dimitry): this is a bit misleading since we do not know
337    // if the vendor public library is going to be opened from /vendor/lib
338    // we might as well end up loading them from /system/lib
339    // For now we rely on CTS test to catch things like this but
340    // it should probably be addressed in the future.
341    for (const auto& soname : sonames) {
342      LOG_ALWAYS_FATAL_IF(dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE) == nullptr,
343                          "Error preloading public library %s: %s",
344                          soname.c_str(), dlerror());
345    }
346
347    system_public_libraries_ = base::Join(sonames, ':');
348
349    sonames.clear();
350    ReadConfig(kLlndkNativeLibrariesSystemConfigPathFromRoot, &sonames);
351    system_llndk_libraries_ = base::Join(sonames, ':');
352
353    sonames.clear();
354    ReadConfig(kVndkspNativeLibrariesSystemConfigPathFromRoot, &sonames);
355    system_vndksp_libraries_ = base::Join(sonames, ':');
356
357    sonames.clear();
358    // This file is optional, quietly ignore if the file does not exist.
359    ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames);
360
361    vendor_public_libraries_ = base::Join(sonames, ':');
362  }
363
364  void Reset() {
365    namespaces_.clear();
366  }
367
368 private:
369  bool ReadConfig(const std::string& configFile, std::vector<std::string>* sonames,
370                  std::string* error_msg = nullptr) {
371    // Read list of public native libraries from the config file.
372    std::string file_content;
373    if(!base::ReadFileToString(configFile, &file_content)) {
374      if (error_msg) *error_msg = strerror(errno);
375      return false;
376    }
377
378    std::vector<std::string> lines = base::Split(file_content, "\n");
379
380    for (auto& line : lines) {
381      auto trimmed_line = base::Trim(line);
382      if (trimmed_line[0] == '#' || trimmed_line.empty()) {
383        continue;
384      }
385      size_t space_pos = trimmed_line.rfind(' ');
386      if (space_pos != std::string::npos) {
387        std::string type = trimmed_line.substr(space_pos + 1);
388        if (type != "32" && type != "64") {
389          if (error_msg) *error_msg = "Malformed line: " + line;
390          return false;
391        }
392#if defined(__LP64__)
393        // Skip 32 bit public library.
394        if (type == "32") {
395          continue;
396        }
397#else
398        // Skip 64 bit public library.
399        if (type == "64") {
400          continue;
401        }
402#endif
403        trimmed_line.resize(space_pos);
404      }
405
406      sonames->push_back(trimmed_line);
407    }
408
409    return true;
410  }
411
412  bool InitPublicNamespace(const char* library_path, std::string* error_msg) {
413    // Ask native bride if this apps library path should be handled by it
414    bool is_native_bridge = NativeBridgeIsPathSupported(library_path);
415
416    // (http://b/25844435) - Some apps call dlopen from generated code (mono jited
417    // code is one example) unknown to linker in which  case linker uses anonymous
418    // namespace. The second argument specifies the search path for the anonymous
419    // namespace which is the library_path of the classloader.
420    initialized_ = android_init_anonymous_namespace(system_public_libraries_.c_str(),
421                                                    is_native_bridge ? nullptr : library_path);
422    if (!initialized_) {
423      *error_msg = dlerror();
424      return false;
425    }
426
427    // and now initialize native bridge namespaces if necessary.
428    if (NativeBridgeInitialized()) {
429      initialized_ = NativeBridgeInitAnonymousNamespace(system_public_libraries_.c_str(),
430                                                        is_native_bridge ? library_path : nullptr);
431      if (!initialized_) {
432        *error_msg = NativeBridgeGetError();
433      }
434    }
435
436    return initialized_;
437  }
438
439  jobject GetParentClassLoader(JNIEnv* env, jobject class_loader) {
440    jclass class_loader_class = env->FindClass("java/lang/ClassLoader");
441    jmethodID get_parent = env->GetMethodID(class_loader_class,
442                                            "getParent",
443                                            "()Ljava/lang/ClassLoader;");
444
445    return env->CallObjectMethod(class_loader, get_parent);
446  }
447
448  bool FindParentNamespaceByClassLoader(JNIEnv* env,
449                                        jobject class_loader,
450                                        NativeLoaderNamespace* ns) {
451    jobject parent_class_loader = GetParentClassLoader(env, class_loader);
452
453    while (parent_class_loader != nullptr) {
454      if (FindNamespaceByClassLoader(env, parent_class_loader, ns)) {
455        return true;
456      }
457
458      parent_class_loader = GetParentClassLoader(env, parent_class_loader);
459    }
460
461    return false;
462  }
463
464  bool initialized_;
465  std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
466  std::string system_public_libraries_;
467  std::string vendor_public_libraries_;
468  std::string system_llndk_libraries_;
469  std::string system_vndksp_libraries_;
470
471  DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces);
472};
473
474static std::mutex g_namespaces_mutex;
475static LibraryNamespaces* g_namespaces = new LibraryNamespaces;
476#endif
477
478void InitializeNativeLoader() {
479#if defined(__ANDROID__)
480  std::lock_guard<std::mutex> guard(g_namespaces_mutex);
481  g_namespaces->Initialize();
482#endif
483}
484
485void ResetNativeLoader() {
486#if defined(__ANDROID__)
487  std::lock_guard<std::mutex> guard(g_namespaces_mutex);
488  g_namespaces->Reset();
489#endif
490}
491
492jstring CreateClassLoaderNamespace(JNIEnv* env,
493                                   int32_t target_sdk_version,
494                                   jobject class_loader,
495                                   bool is_shared,
496                                   bool is_for_vendor,
497                                   jstring library_path,
498                                   jstring permitted_path) {
499#if defined(__ANDROID__)
500  std::lock_guard<std::mutex> guard(g_namespaces_mutex);
501
502  std::string error_msg;
503  NativeLoaderNamespace ns;
504  bool success = g_namespaces->Create(env,
505                                      target_sdk_version,
506                                      class_loader,
507                                      is_shared,
508                                      is_for_vendor,
509                                      library_path,
510                                      permitted_path,
511                                      &ns,
512                                      &error_msg);
513  if (!success) {
514    return env->NewStringUTF(error_msg.c_str());
515  }
516#else
517  UNUSED(env, target_sdk_version, class_loader, is_shared, is_for_vendor,
518         library_path, permitted_path);
519#endif
520  return nullptr;
521}
522
523void* OpenNativeLibrary(JNIEnv* env,
524                        int32_t target_sdk_version,
525                        const char* path,
526                        jobject class_loader,
527                        jstring library_path,
528                        bool* needs_native_bridge,
529                        std::string* error_msg) {
530#if defined(__ANDROID__)
531  UNUSED(target_sdk_version);
532  if (class_loader == nullptr) {
533    *needs_native_bridge = false;
534    return dlopen(path, RTLD_NOW);
535  }
536
537  std::lock_guard<std::mutex> guard(g_namespaces_mutex);
538  NativeLoaderNamespace ns;
539
540  if (!g_namespaces->FindNamespaceByClassLoader(env, class_loader, &ns)) {
541    // This is the case where the classloader was not created by ApplicationLoaders
542    // In this case we create an isolated not-shared namespace for it.
543    if (!g_namespaces->Create(env,
544                              target_sdk_version,
545                              class_loader,
546                              false /* is_shared */,
547                              false /* is_for_vendor */,
548                              library_path,
549                              nullptr,
550                              &ns,
551                              error_msg)) {
552      return nullptr;
553    }
554  }
555
556  if (ns.is_android_namespace()) {
557    android_dlextinfo extinfo;
558    extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
559    extinfo.library_namespace = ns.get_android_ns();
560
561    void* handle = android_dlopen_ext(path, RTLD_NOW, &extinfo);
562    if (handle == nullptr) {
563      *error_msg = dlerror();
564    }
565    *needs_native_bridge = false;
566    return handle;
567  } else {
568    void* handle = NativeBridgeLoadLibraryExt(path, RTLD_NOW, ns.get_native_bridge_ns());
569    if (handle == nullptr) {
570      *error_msg = NativeBridgeGetError();
571    }
572    *needs_native_bridge = true;
573    return handle;
574  }
575#else
576  UNUSED(env, target_sdk_version, class_loader, library_path);
577  *needs_native_bridge = false;
578  void* handle = dlopen(path, RTLD_NOW);
579  if (handle == nullptr) {
580    if (NativeBridgeIsSupported(path)) {
581      *needs_native_bridge = true;
582      handle = NativeBridgeLoadLibrary(path, RTLD_NOW);
583      if (handle == nullptr) {
584        *error_msg = NativeBridgeGetError();
585      }
586    } else {
587      *needs_native_bridge = false;
588      *error_msg = dlerror();
589    }
590  }
591  return handle;
592#endif
593}
594
595bool CloseNativeLibrary(void* handle, const bool needs_native_bridge) {
596    return needs_native_bridge ? NativeBridgeUnloadLibrary(handle) :
597                                 dlclose(handle);
598}
599
600#if defined(__ANDROID__)
601// native_bridge_namespaces are not supported for callers of this function.
602// This function will return nullptr in the case when application is running
603// on native bridge.
604android_namespace_t* FindNamespaceByClassLoader(JNIEnv* env, jobject class_loader) {
605  std::lock_guard<std::mutex> guard(g_namespaces_mutex);
606  NativeLoaderNamespace ns;
607  if (g_namespaces->FindNamespaceByClassLoader(env, class_loader, &ns)) {
608    return ns.is_android_namespace() ? ns.get_android_ns() : nullptr;
609  }
610
611  return nullptr;
612}
613#endif
614
615}; //  android namespace
616