Home | History | Annotate | Download | only in linker
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include "linker_namespaces.h"
     30 #include "linker_globals.h"
     31 #include "linker_soinfo.h"
     32 #include "linker_utils.h"
     33 
     34 #include <dlfcn.h>
     35 
     36 bool android_namespace_t::is_accessible(const std::string& file) {
     37   if (!is_isolated_) {
     38     return true;
     39   }
     40 
     41   for (const auto& dir : ld_library_paths_) {
     42     if (file_is_in_dir(file, dir)) {
     43       return true;
     44     }
     45   }
     46 
     47   for (const auto& dir : default_library_paths_) {
     48     if (file_is_in_dir(file, dir)) {
     49       return true;
     50     }
     51   }
     52 
     53   for (const auto& dir : permitted_paths_) {
     54     if (file_is_under_dir(file, dir)) {
     55       return true;
     56     }
     57   }
     58 
     59   return false;
     60 }
     61 
     62 bool android_namespace_t::is_accessible(soinfo* s) {
     63   auto is_accessible_ftor = [this] (soinfo* si) {
     64     // This is workaround for apps hacking into soinfo list.
     65     // and inserting their own entries into it. (http://b/37191433)
     66     if (!si->has_min_version(3)) {
     67       DL_WARN("Warning: invalid soinfo version for \"%s\" (assuming inaccessible)",
     68               si->get_soname());
     69       return false;
     70     }
     71 
     72     if (si->get_primary_namespace() == this) {
     73       return true;
     74     }
     75 
     76     const android_namespace_list_t& secondary_namespaces = si->get_secondary_namespaces();
     77     if (secondary_namespaces.find(this) != secondary_namespaces.end()) {
     78       return true;
     79     }
     80 
     81     return false;
     82   };
     83 
     84   if (is_accessible_ftor(s)) {
     85     return true;
     86   }
     87 
     88   return !s->get_parents().visit([&](soinfo* si) {
     89     return !is_accessible_ftor(si);
     90   });
     91 }
     92 
     93 // TODO: this is slightly unusual way to construct
     94 // the global group for relocation. Not every RTLD_GLOBAL
     95 // library is included in this group for backwards-compatibility
     96 // reasons.
     97 //
     98 // This group consists of the main executable, LD_PRELOADs
     99 // and libraries with the DF_1_GLOBAL flag set.
    100 soinfo_list_t android_namespace_t::get_global_group() {
    101   soinfo_list_t global_group;
    102   soinfo_list().for_each([&](soinfo* si) {
    103     if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
    104       global_group.push_back(si);
    105     }
    106   });
    107 
    108   return global_group;
    109 }
    110 
    111 // This function provides a list of libraries to be shared
    112 // by the namespace. For the default namespace this is the global
    113 // group (see get_global_group). For all others this is a group
    114 // of RTLD_GLOBAL libraries (which includes the global group from
    115 // the default namespace).
    116 soinfo_list_t android_namespace_t::get_shared_group() {
    117   if (this == &g_default_namespace) {
    118     return get_global_group();
    119   }
    120 
    121   soinfo_list_t shared_group;
    122   soinfo_list().for_each([&](soinfo* si) {
    123     if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
    124       shared_group.push_back(si);
    125     }
    126   });
    127 
    128   return shared_group;
    129 }
    130