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
26 constexpr const char* kDataAsanPath = "/data/asan";
27
FindFromPathList(const std::vector<std::string> & list,const std::string & path)28 bool FindFromPathList(const std::vector<std::string>& list,
29 const std::string& path) {
30 for (auto& path_member : list) {
31 for (auto& path_item : android::base::Split(path_member, ":")) {
32 if (path_item == path) return true;
33 }
34 }
35
36 return false;
37 }
38
39 } // namespace
40
41 namespace android {
42 namespace linkerconfig {
43 namespace modules {
44
InitializeWithApex(Namespace & ns,const ApexInfo & apex_info)45 void InitializeWithApex(Namespace& ns, const ApexInfo& apex_info) {
46 ns.AddSearchPath(apex_info.path + "/${LIB}");
47 ns.AddPermittedPath(apex_info.path + "/${LIB}");
48 ns.AddPermittedPath("/system/${LIB}");
49 ns.AddProvides(apex_info.provide_libs);
50 ns.AddRequires(apex_info.require_libs);
51 }
52
GetLink(const std::string & target_namespace)53 Link& Namespace::GetLink(const std::string& target_namespace) {
54 for (auto& link : links_) {
55 if (link.To() == target_namespace) {
56 return link;
57 }
58 }
59 return links_.emplace_back(name_, target_namespace);
60 }
61
WriteConfig(ConfigWriter & writer)62 void Namespace::WriteConfig(ConfigWriter& writer) {
63 const auto prefix = "namespace." + name_ + ".";
64
65 writer.WriteLine(prefix + "isolated = " + (is_isolated_ ? "true" : "false"));
66
67 if (is_visible_) {
68 writer.WriteLine(prefix + "visible = true");
69 }
70
71 writer.WriteVars(prefix + "search.paths", search_paths_);
72 writer.WriteVars(prefix + "permitted.paths", permitted_paths_);
73 writer.WriteVars(prefix + "asan.search.paths", asan_search_paths_);
74 writer.WriteVars(prefix + "asan.permitted.paths", asan_permitted_paths_);
75 writer.WriteVars(prefix + "whitelisted", whitelisted_);
76
77 if (!links_.empty()) {
78 std::vector<std::string> link_list;
79 link_list.reserve(links_.size());
80 for (const auto& link : links_) {
81 link_list.push_back(link.To());
82 }
83 writer.WriteLine(prefix + "links = " + android::base::Join(link_list, ","));
84
85 for (const auto& link : links_) {
86 link.WriteConfig(writer);
87 }
88 }
89 }
90
AddSearchPath(const std::string & path,AsanPath path_from_asan)91 void Namespace::AddSearchPath(const std::string& path, AsanPath path_from_asan) {
92 search_paths_.push_back(path);
93
94 switch (path_from_asan) {
95 case AsanPath::NONE:
96 break;
97 case AsanPath::SAME_PATH:
98 asan_search_paths_.push_back(path);
99 break;
100 case AsanPath::WITH_DATA_ASAN:
101 asan_search_paths_.push_back(kDataAsanPath + path);
102 asan_search_paths_.push_back(path);
103 break;
104 }
105 }
106
AddPermittedPath(const std::string & path,AsanPath path_from_asan)107 void Namespace::AddPermittedPath(const std::string& path,
108 AsanPath path_from_asan) {
109 permitted_paths_.push_back(path);
110
111 switch (path_from_asan) {
112 case AsanPath::NONE:
113 break;
114 case AsanPath::SAME_PATH:
115 asan_permitted_paths_.push_back(path);
116 break;
117 case AsanPath::WITH_DATA_ASAN:
118 asan_permitted_paths_.push_back(kDataAsanPath + path);
119 asan_permitted_paths_.push_back(path);
120 break;
121 }
122 }
123
AddWhitelisted(const std::string & path)124 void Namespace::AddWhitelisted(const std::string& path) {
125 whitelisted_.push_back(path);
126 }
127
GetName() const128 std::string Namespace::GetName() const {
129 return name_;
130 }
131
ContainsSearchPath(const std::string & path,AsanPath path_from_asan)132 bool Namespace::ContainsSearchPath(const std::string& path,
133 AsanPath path_from_asan) {
134 return FindFromPathList(search_paths_, path) &&
135 (path_from_asan == AsanPath::NONE ||
136 FindFromPathList(asan_search_paths_, path)) &&
137 (path_from_asan != AsanPath::WITH_DATA_ASAN ||
138 FindFromPathList(asan_search_paths_, kDataAsanPath + path));
139 }
140
ContainsPermittedPath(const std::string & path,AsanPath path_from_asan)141 bool Namespace::ContainsPermittedPath(const std::string& path,
142 AsanPath path_from_asan) {
143 return FindFromPathList(permitted_paths_, path) &&
144 (path_from_asan == AsanPath::NONE ||
145 FindFromPathList(asan_permitted_paths_, path)) &&
146 (path_from_asan != AsanPath::WITH_DATA_ASAN ||
147 FindFromPathList(asan_permitted_paths_, kDataAsanPath + path));
148 }
149
150 } // namespace modules
151 } // namespace linkerconfig
152 } // namespace android
153