xref: /aosp_15_r20/system/linkerconfig/modules/namespace.cc (revision e5eeaa8e05bc25a862c0c861bda7c8a6bfb42dad)
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