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