1*e5eeaa8eSAndroid Build Coastguard Worker /*
2*e5eeaa8eSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*e5eeaa8eSAndroid Build Coastguard Worker *
4*e5eeaa8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*e5eeaa8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*e5eeaa8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*e5eeaa8eSAndroid Build Coastguard Worker *
8*e5eeaa8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*e5eeaa8eSAndroid Build Coastguard Worker *
10*e5eeaa8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*e5eeaa8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*e5eeaa8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e5eeaa8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*e5eeaa8eSAndroid Build Coastguard Worker * limitations under the License.
15*e5eeaa8eSAndroid Build Coastguard Worker */
16*e5eeaa8eSAndroid Build Coastguard Worker
17*e5eeaa8eSAndroid Build Coastguard Worker #include "linkerconfig/namespace.h"
18*e5eeaa8eSAndroid Build Coastguard Worker
19*e5eeaa8eSAndroid Build Coastguard Worker #include <android-base/strings.h>
20*e5eeaa8eSAndroid Build Coastguard Worker
21*e5eeaa8eSAndroid Build Coastguard Worker #include "linkerconfig/apex.h"
22*e5eeaa8eSAndroid Build Coastguard Worker #include "linkerconfig/environment.h"
23*e5eeaa8eSAndroid Build Coastguard Worker #include "linkerconfig/log.h"
24*e5eeaa8eSAndroid Build Coastguard Worker
25*e5eeaa8eSAndroid Build Coastguard Worker using android::base::Result;
26*e5eeaa8eSAndroid Build Coastguard Worker
27*e5eeaa8eSAndroid Build Coastguard Worker namespace {
28*e5eeaa8eSAndroid Build Coastguard Worker constexpr const char* kDataAsanPath = "/data/asan";
29*e5eeaa8eSAndroid Build Coastguard Worker
VerifyIfApexNamespaceContainsAllSharedLink(const android::linkerconfig::modules::Namespace & ns)30*e5eeaa8eSAndroid Build Coastguard Worker Result<void> VerifyIfApexNamespaceContainsAllSharedLink(
31*e5eeaa8eSAndroid Build Coastguard Worker const android::linkerconfig::modules::Namespace& ns) {
32*e5eeaa8eSAndroid Build Coastguard Worker auto apex = ns.GetApexSource();
33*e5eeaa8eSAndroid Build Coastguard Worker // If namespace is not from APEX there is no need to check this.
34*e5eeaa8eSAndroid Build Coastguard Worker // Vendor apexes are allowed to use 'allow_all_shared_libs'.
35*e5eeaa8eSAndroid Build Coastguard Worker if (apex.name == "" || apex.in_vendor) {
36*e5eeaa8eSAndroid Build Coastguard Worker return {};
37*e5eeaa8eSAndroid Build Coastguard Worker }
38*e5eeaa8eSAndroid Build Coastguard Worker
39*e5eeaa8eSAndroid Build Coastguard Worker const auto& links = ns.Links();
40*e5eeaa8eSAndroid Build Coastguard Worker for (const auto& link : links) {
41*e5eeaa8eSAndroid Build Coastguard Worker if (link.IsAllSharedLibsAllowed()) {
42*e5eeaa8eSAndroid Build Coastguard Worker return Errorf(
43*e5eeaa8eSAndroid Build Coastguard Worker "APEX namespace {} is not allowed to have link with all shared libs "
44*e5eeaa8eSAndroid Build Coastguard Worker "allowed.",
45*e5eeaa8eSAndroid Build Coastguard Worker ns.GetName());
46*e5eeaa8eSAndroid Build Coastguard Worker }
47*e5eeaa8eSAndroid Build Coastguard Worker }
48*e5eeaa8eSAndroid Build Coastguard Worker return {};
49*e5eeaa8eSAndroid Build Coastguard Worker }
50*e5eeaa8eSAndroid Build Coastguard Worker
51*e5eeaa8eSAndroid Build Coastguard Worker } // namespace
52*e5eeaa8eSAndroid Build Coastguard Worker
53*e5eeaa8eSAndroid Build Coastguard Worker namespace android {
54*e5eeaa8eSAndroid Build Coastguard Worker namespace linkerconfig {
55*e5eeaa8eSAndroid Build Coastguard Worker namespace modules {
56*e5eeaa8eSAndroid Build Coastguard Worker
InitializeWithApex(Namespace & ns,const ApexInfo & apex_info)57*e5eeaa8eSAndroid Build Coastguard Worker void InitializeWithApex(Namespace& ns, const ApexInfo& apex_info) {
58*e5eeaa8eSAndroid Build Coastguard Worker ns.AddSearchPath(apex_info.path + "/${LIB}");
59*e5eeaa8eSAndroid Build Coastguard Worker if (apex_info.InVendor()) {
60*e5eeaa8eSAndroid Build Coastguard Worker // Adding an additional subdir(hw) to make the migration easier because
61*e5eeaa8eSAndroid Build Coastguard Worker // many vendor modules today are installed in ./hw subdir.
62*e5eeaa8eSAndroid Build Coastguard Worker ns.AddSearchPath(apex_info.path + "/${LIB}/hw");
63*e5eeaa8eSAndroid Build Coastguard Worker }
64*e5eeaa8eSAndroid Build Coastguard Worker ns.AddPermittedPath(apex_info.path + "/${LIB}");
65*e5eeaa8eSAndroid Build Coastguard Worker ns.AddPermittedPath("/system/${LIB}");
66*e5eeaa8eSAndroid Build Coastguard Worker ns.AddPermittedPath("/system_ext/${LIB}");
67*e5eeaa8eSAndroid Build Coastguard Worker for (const auto& permitted_path : apex_info.permitted_paths) {
68*e5eeaa8eSAndroid Build Coastguard Worker ns.AddPermittedPath(permitted_path);
69*e5eeaa8eSAndroid Build Coastguard Worker }
70*e5eeaa8eSAndroid Build Coastguard Worker if (apex_info.has_shared_lib) {
71*e5eeaa8eSAndroid Build Coastguard Worker ns.AddPermittedPath("/apex");
72*e5eeaa8eSAndroid Build Coastguard Worker }
73*e5eeaa8eSAndroid Build Coastguard Worker ns.AddProvides(apex_info.provide_libs);
74*e5eeaa8eSAndroid Build Coastguard Worker ns.AddRequires(apex_info.require_libs);
75*e5eeaa8eSAndroid Build Coastguard Worker ns.SetApexSource(ApexSource{apex_info.name, apex_info.InVendor()});
76*e5eeaa8eSAndroid Build Coastguard Worker }
77*e5eeaa8eSAndroid Build Coastguard Worker
GetLink(const std::string & target_namespace)78*e5eeaa8eSAndroid Build Coastguard Worker Link& Namespace::GetLink(const std::string& target_namespace) {
79*e5eeaa8eSAndroid Build Coastguard Worker for (auto& link : links_) {
80*e5eeaa8eSAndroid Build Coastguard Worker if (link.To() == target_namespace) {
81*e5eeaa8eSAndroid Build Coastguard Worker return link;
82*e5eeaa8eSAndroid Build Coastguard Worker }
83*e5eeaa8eSAndroid Build Coastguard Worker }
84*e5eeaa8eSAndroid Build Coastguard Worker return links_.emplace_back(name_, target_namespace);
85*e5eeaa8eSAndroid Build Coastguard Worker }
86*e5eeaa8eSAndroid Build Coastguard Worker
WriteConfig(ConfigWriter & writer) const87*e5eeaa8eSAndroid Build Coastguard Worker void Namespace::WriteConfig(ConfigWriter& writer) const {
88*e5eeaa8eSAndroid Build Coastguard Worker auto verify_result = VerifyContents();
89*e5eeaa8eSAndroid Build Coastguard Worker if (!verify_result.ok()) {
90*e5eeaa8eSAndroid Build Coastguard Worker LOG(ERROR) << "Namespace " << name_
91*e5eeaa8eSAndroid Build Coastguard Worker << " is not valid : " << verify_result.error();
92*e5eeaa8eSAndroid Build Coastguard Worker return;
93*e5eeaa8eSAndroid Build Coastguard Worker }
94*e5eeaa8eSAndroid Build Coastguard Worker
95*e5eeaa8eSAndroid Build Coastguard Worker const auto prefix = "namespace." + name_ + ".";
96*e5eeaa8eSAndroid Build Coastguard Worker
97*e5eeaa8eSAndroid Build Coastguard Worker writer.WriteLine(prefix + "isolated = " + (is_isolated_ ? "true" : "false"));
98*e5eeaa8eSAndroid Build Coastguard Worker
99*e5eeaa8eSAndroid Build Coastguard Worker if (is_visible_) {
100*e5eeaa8eSAndroid Build Coastguard Worker writer.WriteLine(prefix + "visible = true");
101*e5eeaa8eSAndroid Build Coastguard Worker }
102*e5eeaa8eSAndroid Build Coastguard Worker
103*e5eeaa8eSAndroid Build Coastguard Worker writer.WriteVars(prefix + "search.paths", search_paths_);
104*e5eeaa8eSAndroid Build Coastguard Worker writer.WriteVars(prefix + "permitted.paths", permitted_paths_);
105*e5eeaa8eSAndroid Build Coastguard Worker writer.WriteVars(prefix + "asan.search.paths", asan_search_paths_);
106*e5eeaa8eSAndroid Build Coastguard Worker writer.WriteVars(prefix + "asan.permitted.paths", asan_permitted_paths_);
107*e5eeaa8eSAndroid Build Coastguard Worker writer.WriteVars(prefix + "hwasan.search.paths", search_paths_, "/hwasan");
108*e5eeaa8eSAndroid Build Coastguard Worker writer.WriteVars(
109*e5eeaa8eSAndroid Build Coastguard Worker prefix + "hwasan.permitted.paths", permitted_paths_, "/hwasan");
110*e5eeaa8eSAndroid Build Coastguard Worker writer.WriteVars(prefix + "allowed_libs", allowed_libs_);
111*e5eeaa8eSAndroid Build Coastguard Worker
112*e5eeaa8eSAndroid Build Coastguard Worker std::vector<std::string> link_list;
113*e5eeaa8eSAndroid Build Coastguard Worker link_list.reserve(links_.size());
114*e5eeaa8eSAndroid Build Coastguard Worker for (const auto& link : links_) {
115*e5eeaa8eSAndroid Build Coastguard Worker if (link.Empty()) continue;
116*e5eeaa8eSAndroid Build Coastguard Worker if (link.To() == name_) {
117*e5eeaa8eSAndroid Build Coastguard Worker LOG(WARNING) << "Ignore link to self namespace : " << name_;
118*e5eeaa8eSAndroid Build Coastguard Worker continue;
119*e5eeaa8eSAndroid Build Coastguard Worker }
120*e5eeaa8eSAndroid Build Coastguard Worker link_list.push_back(link.To());
121*e5eeaa8eSAndroid Build Coastguard Worker }
122*e5eeaa8eSAndroid Build Coastguard Worker if (!link_list.empty()) {
123*e5eeaa8eSAndroid Build Coastguard Worker writer.WriteLine(prefix + "links = " + android::base::Join(link_list, ","));
124*e5eeaa8eSAndroid Build Coastguard Worker for (const auto& link : links_) {
125*e5eeaa8eSAndroid Build Coastguard Worker if (link.Empty()) continue;
126*e5eeaa8eSAndroid Build Coastguard Worker if (link.To() == name_) continue;
127*e5eeaa8eSAndroid Build Coastguard Worker link.WriteConfig(writer);
128*e5eeaa8eSAndroid Build Coastguard Worker }
129*e5eeaa8eSAndroid Build Coastguard Worker }
130*e5eeaa8eSAndroid Build Coastguard Worker }
131*e5eeaa8eSAndroid Build Coastguard Worker
AddSearchPath(const std::string & path)132*e5eeaa8eSAndroid Build Coastguard Worker void Namespace::AddSearchPath(const std::string& path) {
133*e5eeaa8eSAndroid Build Coastguard Worker search_paths_.push_back(path);
134*e5eeaa8eSAndroid Build Coastguard Worker
135*e5eeaa8eSAndroid Build Coastguard Worker if (RequiresAsanPath(path)) {
136*e5eeaa8eSAndroid Build Coastguard Worker asan_search_paths_.push_back(CreateAsanPath(path));
137*e5eeaa8eSAndroid Build Coastguard Worker }
138*e5eeaa8eSAndroid Build Coastguard Worker asan_search_paths_.push_back(path);
139*e5eeaa8eSAndroid Build Coastguard Worker }
140*e5eeaa8eSAndroid Build Coastguard Worker
AddPermittedPath(const std::string & path)141*e5eeaa8eSAndroid Build Coastguard Worker void Namespace::AddPermittedPath(const std::string& path) {
142*e5eeaa8eSAndroid Build Coastguard Worker permitted_paths_.push_back(path);
143*e5eeaa8eSAndroid Build Coastguard Worker
144*e5eeaa8eSAndroid Build Coastguard Worker if (RequiresAsanPath(path)) {
145*e5eeaa8eSAndroid Build Coastguard Worker asan_permitted_paths_.push_back(CreateAsanPath(path));
146*e5eeaa8eSAndroid Build Coastguard Worker }
147*e5eeaa8eSAndroid Build Coastguard Worker asan_permitted_paths_.push_back(path);
148*e5eeaa8eSAndroid Build Coastguard Worker }
149*e5eeaa8eSAndroid Build Coastguard Worker
AddAllowedLib(const std::string & path)150*e5eeaa8eSAndroid Build Coastguard Worker void Namespace::AddAllowedLib(const std::string& path) {
151*e5eeaa8eSAndroid Build Coastguard Worker allowed_libs_.push_back(path);
152*e5eeaa8eSAndroid Build Coastguard Worker }
153*e5eeaa8eSAndroid Build Coastguard Worker
GetName() const154*e5eeaa8eSAndroid Build Coastguard Worker std::string Namespace::GetName() const {
155*e5eeaa8eSAndroid Build Coastguard Worker return name_;
156*e5eeaa8eSAndroid Build Coastguard Worker }
157*e5eeaa8eSAndroid Build Coastguard Worker
RequiresAsanPath(const std::string & path)158*e5eeaa8eSAndroid Build Coastguard Worker bool Namespace::RequiresAsanPath(const std::string& path) {
159*e5eeaa8eSAndroid Build Coastguard Worker return !android::base::StartsWith(path, "/apex");
160*e5eeaa8eSAndroid Build Coastguard Worker }
161*e5eeaa8eSAndroid Build Coastguard Worker
CreateAsanPath(const std::string & path)162*e5eeaa8eSAndroid Build Coastguard Worker const std::string Namespace::CreateAsanPath(const std::string& path) {
163*e5eeaa8eSAndroid Build Coastguard Worker return kDataAsanPath + path;
164*e5eeaa8eSAndroid Build Coastguard Worker }
165*e5eeaa8eSAndroid Build Coastguard Worker
VerifyContents() const166*e5eeaa8eSAndroid Build Coastguard Worker Result<void> Namespace::VerifyContents() const {
167*e5eeaa8eSAndroid Build Coastguard Worker auto apex_with_all_shared_link =
168*e5eeaa8eSAndroid Build Coastguard Worker VerifyIfApexNamespaceContainsAllSharedLink(*this);
169*e5eeaa8eSAndroid Build Coastguard Worker if (!apex_with_all_shared_link.ok()) {
170*e5eeaa8eSAndroid Build Coastguard Worker return apex_with_all_shared_link.error();
171*e5eeaa8eSAndroid Build Coastguard Worker }
172*e5eeaa8eSAndroid Build Coastguard Worker
173*e5eeaa8eSAndroid Build Coastguard Worker return {};
174*e5eeaa8eSAndroid Build Coastguard Worker }
175*e5eeaa8eSAndroid Build Coastguard Worker
176*e5eeaa8eSAndroid Build Coastguard Worker } // namespace modules
177*e5eeaa8eSAndroid Build Coastguard Worker } // namespace linkerconfig
178*e5eeaa8eSAndroid Build Coastguard Worker } // namespace android
179