1 /*
2  * Copyright (C) 2019 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 "linkerconfig/namespace.h"
18 
19 #include <android-base/strings.h>
20 
21 #include "linkerconfig/apex.h"
22 #include "linkerconfig/log.h"
23 
24 namespace {
25 constexpr const char* kDataAsanPath = "/data/asan";
26 }  // namespace
27 
28 namespace android {
29 namespace linkerconfig {
30 namespace modules {
31 
InitializeWithApex(Namespace & ns,const ApexInfo & apex_info)32 void InitializeWithApex(Namespace& ns, const ApexInfo& apex_info) {
33   ns.AddSearchPath(apex_info.path + "/${LIB}");
34   ns.AddPermittedPath(apex_info.path + "/${LIB}");
35   ns.AddPermittedPath("/system/${LIB}");
36   ns.AddProvides(apex_info.provide_libs);
37   ns.AddRequires(apex_info.require_libs);
38 }
39 
GetLink(const std::string & target_namespace)40 Link& Namespace::GetLink(const std::string& target_namespace) {
41   for (auto& link : links_) {
42     if (link.To() == target_namespace) {
43       return link;
44     }
45   }
46   return links_.emplace_back(name_, target_namespace);
47 }
48 
WriteConfig(ConfigWriter & writer)49 void Namespace::WriteConfig(ConfigWriter& writer) {
50   const auto prefix = "namespace." + name_ + ".";
51 
52   writer.WriteLine(prefix + "isolated = " + (is_isolated_ ? "true" : "false"));
53 
54   if (is_visible_) {
55     writer.WriteLine(prefix + "visible = true");
56   }
57 
58   writer.WriteVars(prefix + "search.paths", search_paths_);
59   writer.WriteVars(prefix + "permitted.paths", permitted_paths_);
60   writer.WriteVars(prefix + "asan.search.paths", asan_search_paths_);
61   writer.WriteVars(prefix + "asan.permitted.paths", asan_permitted_paths_);
62   writer.WriteVars(prefix + "whitelisted", whitelisted_);
63 
64   if (!links_.empty()) {
65     std::vector<std::string> link_list;
66     link_list.reserve(links_.size());
67     for (const auto& link : links_) {
68       link_list.push_back(link.To());
69     }
70     writer.WriteLine(prefix + "links = " + android::base::Join(link_list, ","));
71 
72     for (const auto& link : links_) {
73       link.WriteConfig(writer);
74     }
75   }
76 }
77 
AddSearchPath(const std::string & path)78 void Namespace::AddSearchPath(const std::string& path) {
79   search_paths_.push_back(path);
80 
81   if (RequiresAsanPath(path)) {
82     asan_search_paths_.push_back(CreateAsanPath(path));
83   }
84   asan_search_paths_.push_back(path);
85 }
86 
AddPermittedPath(const std::string & path)87 void Namespace::AddPermittedPath(const std::string& path) {
88   permitted_paths_.push_back(path);
89 
90   if (RequiresAsanPath(path)) {
91     asan_permitted_paths_.push_back(CreateAsanPath(path));
92   }
93   asan_permitted_paths_.push_back(path);
94 }
95 
AddWhitelisted(const std::string & path)96 void Namespace::AddWhitelisted(const std::string& path) {
97   whitelisted_.push_back(path);
98 }
99 
GetName() const100 std::string Namespace::GetName() const {
101   return name_;
102 }
103 
RequiresAsanPath(const std::string & path)104 bool Namespace::RequiresAsanPath(const std::string& path) {
105   return !android::base::StartsWith(path, "/apex");
106 }
107 
CreateAsanPath(const std::string & path)108 const std::string Namespace::CreateAsanPath(const std::string& path) {
109   return kDataAsanPath + path;
110 }
111 
112 }  // namespace modules
113 }  // namespace linkerconfig
114 }  // namespace android
115