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