You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
4.5 KiB
163 lines
4.5 KiB
/*
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "linkerconfig/namespace.h"
|
|
|
|
#include <android-base/strings.h>
|
|
|
|
#include "linkerconfig/apex.h"
|
|
#include "linkerconfig/log.h"
|
|
|
|
using android::base::Result;
|
|
|
|
namespace {
|
|
constexpr const char* kDataAsanPath = "/data/asan";
|
|
|
|
Result<void> VerifyIfApexNamespaceContainsAllSharedLink(
|
|
const android::linkerconfig::modules::Namespace& ns) {
|
|
auto apex_name = ns.GetApexSource();
|
|
// If namespace is not from APEX there is no need to check this.
|
|
if (apex_name == "") {
|
|
return {};
|
|
}
|
|
|
|
const auto& links = ns.Links();
|
|
for (const auto& link : links) {
|
|
if (link.IsAllSharedLibsAllowed()) {
|
|
return Errorf(
|
|
"APEX namespace {} is not allowed to have link with all shared libs "
|
|
"allowed.",
|
|
ns.GetName());
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
} // namespace
|
|
|
|
namespace android {
|
|
namespace linkerconfig {
|
|
namespace modules {
|
|
|
|
void InitializeWithApex(Namespace& ns, const ApexInfo& apex_info) {
|
|
ns.AddSearchPath(apex_info.path + "/${LIB}");
|
|
ns.AddPermittedPath(apex_info.path + "/${LIB}");
|
|
ns.AddPermittedPath("/system/${LIB}");
|
|
for (const auto& permitted_path : apex_info.permitted_paths) {
|
|
ns.AddPermittedPath(permitted_path);
|
|
}
|
|
if (apex_info.has_shared_lib) {
|
|
ns.AddPermittedPath("/apex");
|
|
}
|
|
ns.AddProvides(apex_info.provide_libs);
|
|
ns.AddRequires(apex_info.require_libs);
|
|
ns.SetApexSource(apex_info.name);
|
|
}
|
|
|
|
Link& Namespace::GetLink(const std::string& target_namespace) {
|
|
for (auto& link : links_) {
|
|
if (link.To() == target_namespace) {
|
|
return link;
|
|
}
|
|
}
|
|
return links_.emplace_back(name_, target_namespace);
|
|
}
|
|
|
|
void Namespace::WriteConfig(ConfigWriter& writer) {
|
|
auto verify_result = VerifyContents();
|
|
if (!verify_result.ok()) {
|
|
LOG(ERROR) << "Namespace " << name_
|
|
<< " is not valid : " << verify_result.error();
|
|
return;
|
|
}
|
|
|
|
const auto prefix = "namespace." + name_ + ".";
|
|
|
|
writer.WriteLine(prefix + "isolated = " + (is_isolated_ ? "true" : "false"));
|
|
|
|
if (is_visible_) {
|
|
writer.WriteLine(prefix + "visible = true");
|
|
}
|
|
|
|
writer.WriteVars(prefix + "search.paths", search_paths_);
|
|
writer.WriteVars(prefix + "permitted.paths", permitted_paths_);
|
|
writer.WriteVars(prefix + "asan.search.paths", asan_search_paths_);
|
|
writer.WriteVars(prefix + "asan.permitted.paths", asan_permitted_paths_);
|
|
writer.WriteVars(prefix + "allowed_libs", allowed_libs_);
|
|
|
|
std::vector<std::string> link_list;
|
|
link_list.reserve(links_.size());
|
|
for (const auto& link : links_) {
|
|
if (link.Empty()) continue;
|
|
link_list.push_back(link.To());
|
|
}
|
|
if (!link_list.empty()) {
|
|
writer.WriteLine(prefix + "links = " + android::base::Join(link_list, ","));
|
|
for (const auto& link : links_) {
|
|
if (link.Empty()) continue;
|
|
link.WriteConfig(writer);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Namespace::AddSearchPath(const std::string& path) {
|
|
search_paths_.push_back(path);
|
|
|
|
if (RequiresAsanPath(path)) {
|
|
asan_search_paths_.push_back(CreateAsanPath(path));
|
|
}
|
|
asan_search_paths_.push_back(path);
|
|
}
|
|
|
|
void Namespace::AddPermittedPath(const std::string& path) {
|
|
permitted_paths_.push_back(path);
|
|
|
|
if (RequiresAsanPath(path)) {
|
|
asan_permitted_paths_.push_back(CreateAsanPath(path));
|
|
}
|
|
asan_permitted_paths_.push_back(path);
|
|
}
|
|
|
|
void Namespace::AddAllowedLib(const std::string& path) {
|
|
allowed_libs_.push_back(path);
|
|
}
|
|
|
|
std::string Namespace::GetName() const {
|
|
return name_;
|
|
}
|
|
|
|
bool Namespace::RequiresAsanPath(const std::string& path) {
|
|
return !android::base::StartsWith(path, "/apex");
|
|
}
|
|
|
|
const std::string Namespace::CreateAsanPath(const std::string& path) {
|
|
return kDataAsanPath + path;
|
|
}
|
|
|
|
Result<void> Namespace::VerifyContents() {
|
|
auto apex_with_all_shared_link =
|
|
VerifyIfApexNamespaceContainsAllSharedLink(*this);
|
|
if (!apex_with_all_shared_link.ok()) {
|
|
return apex_with_all_shared_link.error();
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
} // namespace modules
|
|
} // namespace linkerconfig
|
|
} // namespace android
|