diff options
| author | android-build-team Robot <android-build-team-robot@google.com> | 2017-06-06 07:26:20 +0000 |
|---|---|---|
| committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-06-06 07:26:20 +0000 |
| commit | 997eeef72136ececfc63b304523f157c12065c35 (patch) | |
| tree | ac26a4ef2c2bcdb9847e0f469288de6776378dfd | |
| parent | 58e4de34d0e93a6b4af801b5b1f42f0e4e99058e (diff) | |
| parent | 818ab4417f7726a0e93f7d7cf7b24515ee5e2ad8 (diff) | |
| download | platform_test_vts-testcase_fuzz-oreo-dr3-release.tar.gz platform_test_vts-testcase_fuzz-oreo-dr3-release.tar.bz2 platform_test_vts-testcase_fuzz-oreo-dr3-release.zip | |
release-request-2b9eb364-e73f-4091-8ad7-435c885e6bd0-for-git_oc-dr1-release-4070602 snap-temp-L36900000070867203android-8.0.0_r34android-8.0.0_r33android-8.0.0_r27android-8.0.0_r26android-8.0.0_r25android-8.0.0_r24android-8.0.0_r23android-8.0.0_r22android-8.0.0_r21oreo-dr3-releaseoreo-dr2-releaseoreo-dr1-release
Change-Id: Ie9a366d480a0c211375757a92225e32dd030ab3e
| -rw-r--r-- | iface_fuzzer/ProtoFuzzerRunner.cpp | 121 | ||||
| -rw-r--r-- | iface_fuzzer/include/ProtoFuzzerRunner.h | 9 |
2 files changed, 103 insertions, 27 deletions
diff --git a/iface_fuzzer/ProtoFuzzerRunner.cpp b/iface_fuzzer/ProtoFuzzerRunner.cpp index bdd8345..eb8deb1 100644 --- a/iface_fuzzer/ProtoFuzzerRunner.cpp +++ b/iface_fuzzer/ProtoFuzzerRunner.cpp @@ -67,33 +67,33 @@ static string GetServiceName(const CompSpec &comp_spec) { return service_name; } -static FuzzerBase *InitHalDriver(const CompSpec &comp_spec, bool binder_mode) { +static void *Dlopen(string lib_name) { const char *error; - string driver_name = GetDriverName(comp_spec); - void *handle = dlopen(driver_name.c_str(), RTLD_LAZY); + // Clear dlerror(). + dlerror(); + void *handle = dlopen(lib_name.c_str(), RTLD_LAZY); if (!handle) { cerr << __func__ << ": " << dlerror() << endl; - cerr << __func__ << ": Can't load shared library: " << driver_name << endl; + cerr << __func__ << ": Can't load shared library: " << lib_name << endl; exit(1); } + return handle; +} +static void *Dlsym(void *handle, string function_name) { + const char *error; // Clear dlerror(). dlerror(); - string function_name = GetFunctionNamePrefix(comp_spec); - using loader_func = FuzzerBase *(*)(); - auto hal_loader = (loader_func)dlsym(handle, function_name.c_str()); + void *function = dlsym(handle, function_name.c_str()); if ((error = dlerror()) != NULL) { cerr << __func__ << ": Can't find: " << function_name << endl; cerr << error << endl; exit(1); } + return function; +} - FuzzerBase *hal = hal_loader(); - string service_name = GetServiceName(comp_spec); - cerr << "HAL name: " << comp_spec.package() << endl - << "Interface name: " << comp_spec.component_name() << endl - << "Service name: " << service_name << endl; - +static void GetService(FuzzerBase *hal, string service_name, bool binder_mode) { // For fuzzing, only passthrough mode provides coverage. // If binder mode is not requested, attempt to open HAL in passthrough mode. // If the attempt fails, fall back to binder mode. @@ -103,7 +103,7 @@ static FuzzerBase *InitHalDriver(const CompSpec &comp_spec, bool binder_mode) { << "Falling back to binder mode." << endl; } else { cerr << "HAL opened in passthrough mode." << endl; - return hal; + return; } } @@ -112,6 +112,30 @@ static FuzzerBase *InitHalDriver(const CompSpec &comp_spec, bool binder_mode) { exit(1); } else { cerr << "HAL opened in binder mode." << endl; + return; + } +} + +FuzzerBase *ProtoFuzzerRunner::LoadInterface(const CompSpec &comp_spec, + uint64_t hidl_service = 0) { + FuzzerBase *hal; + const char *error; + // Clear dlerror(). + dlerror(); + + // FuzzerBase can be constructed with or without an argument. + // Using different FuzzerBase constructors requires dlsym'ing different + // symbols from the driver library. + string function_name = GetFunctionNamePrefix(comp_spec); + if (hidl_service) { + function_name += "with_arg"; + using loader_func = FuzzerBase *(*)(uint64_t); + auto hal_loader = (loader_func)Dlsym(driver_handle_, function_name.c_str()); + hal = hal_loader(hidl_service); + } else { + using loader_func = FuzzerBase *(*)(); + auto hal_loader = (loader_func)Dlsym(driver_handle_, function_name.c_str()); + hal = hal_loader(); } return hal; } @@ -127,7 +151,18 @@ ProtoFuzzerRunner::ProtoFuzzerRunner(const vector<CompSpec> &comp_specs) { void ProtoFuzzerRunner::Init(const string &iface_name, bool binder_mode) { const CompSpec *comp_spec = FindCompSpec(iface_name); - std::shared_ptr<FuzzerBase> hal{InitHalDriver(*comp_spec, binder_mode)}; + // dlopen VTS driver library. + string driver_name = GetDriverName(*comp_spec); + driver_handle_ = Dlopen(driver_name); + + std::shared_ptr<FuzzerBase> hal{LoadInterface(*comp_spec)}; + string service_name = GetServiceName(*comp_spec); + cerr << "HAL name: " << comp_spec->package() << endl + << "Interface name: " << comp_spec->component_name() << endl + << "Service name: " << service_name << endl; + + // This should only be done for top-level interfaces. + GetService(hal.get(), service_name, binder_mode); // Register this interface as opened by the runner. opened_ifaces_[iface_name] = { @@ -136,19 +171,51 @@ void ProtoFuzzerRunner::Init(const string &iface_name, bool binder_mode) { } void ProtoFuzzerRunner::Execute(const ExecSpec &exec_spec) { - for (const auto &iface_func_call : exec_spec.function_call()) { - string iface_name = iface_func_call.hidl_interface_name(); - const FuncSpec &func_spec = iface_func_call.api(); - - auto iface_desc = opened_ifaces_.find(iface_name); - if (iface_desc == opened_ifaces_.end()) { - cerr << "Interface is not open: " << iface_name << endl; - exit(1); - } - cout << iface_func_call.DebugString() << endl; + for (const auto &func_call : exec_spec.function_call()) { + Execute(func_call); + } +} + +void ProtoFuzzerRunner::Execute(const FuncCall &func_call) { + string iface_name = func_call.hidl_interface_name(); + const FuncSpec &func_spec = func_call.api(); + + auto iface_desc = opened_ifaces_.find(iface_name); + if (iface_desc == opened_ifaces_.end()) { + cerr << "Interface is not open: " << iface_name << endl; + exit(1); + } + cout << func_call.DebugString() << endl; + + FuncSpec result{}; + iface_desc->second.hal_->CallFunction(func_spec, "", &result); - FuncSpec result{}; - iface_desc->second.hal_->CallFunction(func_spec, "", &result); + ProcessReturnValue(result); +} + +static string StripNamespace(const string &type) { + size_t idx = type.find_last_of(':'); + if (idx == string::npos) { + return ""; + } + return type.substr(idx + 1); +} + +void ProtoFuzzerRunner::ProcessReturnValue(const FuncSpec &result) { + for (const auto &var : result.return_type_hidl()) { + if (var.has_hidl_interface_pointer() && var.has_predefined_type()) { + uint64_t hidl_service = var.hidl_interface_pointer(); + string type = var.predefined_type(); + string iface_name = StripNamespace(type); + + const CompSpec *comp_spec = FindCompSpec(iface_name); + std::shared_ptr<FuzzerBase> hal{LoadInterface(*comp_spec, hidl_service)}; + + // Register this interface as opened by the runner. + opened_ifaces_[iface_name] = { + .comp_spec_ = comp_spec, .hal_ = hal, + }; + } } } diff --git a/iface_fuzzer/include/ProtoFuzzerRunner.h b/iface_fuzzer/include/ProtoFuzzerRunner.h index 06af6b9..124b2b9 100644 --- a/iface_fuzzer/include/ProtoFuzzerRunner.h +++ b/iface_fuzzer/include/ProtoFuzzerRunner.h @@ -45,6 +45,8 @@ class ProtoFuzzerRunner { void Init(const std::string &, bool); // Call every API from call sequence specified by the ExecSpec. void Execute(const ExecSpec &); + // Execute the specified interface function call. + void Execute(const FuncCall &); // Accessor to interface descriptor table containing currently opened // interfaces. const IfaceDescTbl &GetOpenedIfaces() const { return opened_ifaces_; } @@ -52,11 +54,18 @@ class ProtoFuzzerRunner { private: // Looks up interface spec by name. const CompSpec *FindCompSpec(std::string); + // Processes return value from a function call. + void ProcessReturnValue(const FuncSpec &result); + // Loads the interface corresponding to the given VTS spec. Interface is + // constructed with the given argument. + FuzzerBase *LoadInterface(const CompSpec &, uint64_t); // Keeps track of opened interfaces. IfaceDescTbl opened_ifaces_; // All loaded VTS specs indexed by name. std::unordered_map<std::string, CompSpec> comp_specs_; + // Handle to the driver library. + void *driver_handle_; }; } // namespace fuzzer |
