1 /*
2 * Copyright 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 "ProtoFuzzerUtils.h"
18
19 #include <android-base/file.h>
20 #include <android-base/macros.h>
21 #include <android-base/strings.h>
22 #include <vintf/VintfObject.h>
23
24 #define STRINGIFY(x) STRINGIFY_INTERNAL(x)
25 #define STRINGIFY_INTERNAL(x) #x
26
27 using android::FQName;
28 using android::base::GetExecutableDirectory;
29 using android::base::Join;
30 using android::base::Split;
31 using android::vintf::Version;
32 using android::vintf::VintfObject;
33 using std::cerr;
34 using std::cout;
35 using std::string;
36
37 namespace android {
38 namespace vts {
39 namespace fuzzer {
40
41 // TODO(b/145220086): fuzzer should attempt to fuzz all interfaces and instances
42 // it can find.
FindAnyIfaceFQName(const FQName & package_and_version,const vector<CompSpec> & comp_specs)43 static FQName FindAnyIfaceFQName(const FQName &package_and_version,
44 const vector<CompSpec> &comp_specs) {
45 for (const auto &spec : comp_specs) {
46 auto package = package_and_version.package();
47 auto major_version = package_and_version.getPackageMajorVersion();
48 auto minor_version = package_and_version.getPackageMinorVersion();
49
50 if (package == spec.package() &&
51 major_version == spec.component_type_version_major() &&
52 minor_version == spec.component_type_version_minor()) {
53 auto iface_name = spec.component_name();
54 auto instance_names =
55 VintfObject::GetDeviceHalManifest()->getHidlInstances(
56 package,
57 Version(spec.component_type_version_major(),
58 spec.component_type_version_minor()),
59 iface_name);
60
61 if (!instance_names.empty()) {
62 auto version =
63 std::to_string(major_version) + "." + std::to_string(minor_version);
64 return FQName{package, version, iface_name};
65 }
66 }
67 }
68 return FQName{};
69 }
70
71 // Returns path to base directory where fuzzer specs are installed.
GetSpecBaseDir()72 static inline const string &GetSpecBaseDir() {
73 static const string spec_base_dir = GetExecutableDirectory() + "/data/";
74 return spec_base_dir;
75 }
76
77 // Parses a column-separated list of packages into a list of corresponding
78 // directories.
ParseDirs(const string & packages)79 static vector<string> ParseDirs(const string &packages) {
80 vector<string> result{};
81
82 for (const auto &package : Split(packages, ":")) {
83 FQName fq_name;
84 if (!FQName::parse(package, &fq_name)) {
85 cerr << "package list is malformed" << endl;
86 std::abort();
87 }
88
89 vector<string> components = fq_name.getPackageAndVersionComponents(false);
90 string spec_dir = GetSpecBaseDir() + Join(components, '/');
91 result.emplace_back(std::move(spec_dir));
92 }
93 return result;
94 }
95
ExtractProtoFuzzerStaticParams(int argc,char ** argv)96 ProtoFuzzerParams ExtractProtoFuzzerStaticParams(int argc, char **argv) {
97 FQName package_and_version;
98 if (!FQName::parse(STRINGIFY(STATIC_TARGET_FQ_NAME), &package_and_version)) {
99 cerr << "STATIC_TARGET_FQ_NAME is malformed" << endl;
100 std::abort();
101 }
102
103 string spec_data_list = STRINGIFY(STATIC_SPEC_DATA);
104 if (spec_data_list.empty()) {
105 cerr << "STATIC_SPEC_DATA is malformed" << endl;
106 std::abort();
107 }
108
109 ProtoFuzzerParams params;
110 params.comp_specs_ = ExtractCompSpecs(ParseDirs(spec_data_list));
111
112 // Find first interface in the given package that fits the bill.
113 params.target_fq_name_ =
114 FindAnyIfaceFQName(package_and_version, params.comp_specs_);
115 if (!params.target_fq_name_.isFullyQualified()) {
116 cerr << "HAL service name not available in VINTF." << endl;
117 std::exit(0);
118 }
119
120 // Hard-coded values
121 params.exec_size_ = 16;
122 return params;
123 }
124
125 } // namespace fuzzer
126 } // namespace vts
127 } // namespace android
128