/* * Copyright 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 "ProtoFuzzerUtils.h" #include #include #include #include #define STRINGIFY(x) STRINGIFY_INTERNAL(x) #define STRINGIFY_INTERNAL(x) #x using android::FQName; using android::base::GetExecutableDirectory; using android::base::Join; using android::base::Split; using android::hardware::getAllHalInstanceNames; using std::cerr; using std::cout; using std::string; namespace android { namespace vts { namespace fuzzer { // TODO(b/145220086): fuzzer should attempt to fuzz all interfaces and instances // it can find. static FQName FindAnyIfaceFQName(const FQName &package_and_version, const vector &comp_specs) { for (const auto &spec : comp_specs) { auto package = package_and_version.package(); auto major_version = package_and_version.getPackageMajorVersion(); auto minor_version = package_and_version.getPackageMinorVersion(); if (package == spec.package() && major_version == spec.component_type_version_major() && minor_version == spec.component_type_version_minor()) { auto iface_name = spec.component_name(); auto descriptor = package_and_version.string() + "::" + iface_name; auto instance_names = getAllHalInstanceNames(descriptor); if (!instance_names.empty()) { auto version = std::to_string(major_version) + "." + std::to_string(minor_version); return FQName{package, version, iface_name}; } } } return FQName{}; } // Returns path to base directory where fuzzer specs are installed. static inline const string &GetSpecBaseDir() { static const string spec_base_dir = GetExecutableDirectory() + "/data/"; return spec_base_dir; } // Parses a column-separated list of packages into a list of corresponding // directories. static vector ParseDirs(const string &packages) { vector result{}; for (const auto &package : Split(packages, ":")) { FQName fq_name; if (!FQName::parse(package, &fq_name)) { cerr << "package list is malformed" << endl; std::abort(); } vector components = fq_name.getPackageAndVersionComponents(false); string spec_dir = GetSpecBaseDir() + Join(components, '/'); result.emplace_back(std::move(spec_dir)); } return result; } ProtoFuzzerParams ExtractProtoFuzzerStaticParams(int argc, char **argv) { FQName package_and_version; if (!FQName::parse(STRINGIFY(STATIC_TARGET_FQ_NAME), &package_and_version)) { cerr << "STATIC_TARGET_FQ_NAME is malformed" << endl; std::abort(); } string spec_data_list = STRINGIFY(STATIC_SPEC_DATA); if (spec_data_list.empty()) { cerr << "STATIC_SPEC_DATA is malformed" << endl; std::abort(); } ProtoFuzzerParams params; params.comp_specs_ = ExtractCompSpecs(ParseDirs(spec_data_list)); // Find first interface in the given package that fits the bill. params.target_fq_name_ = FindAnyIfaceFQName(package_and_version, params.comp_specs_); if (!params.target_fq_name_.isFullyQualified()) { cerr << "HAL service name not available in VINTF." << endl; std::exit(0); } // Hard-coded values params.exec_size_ = 16; return params; } } // namespace fuzzer } // namespace vts } // namespace android