diff options
| -rw-r--r-- | libs/vibrator/Android.bp | 9 | ||||
| -rw-r--r-- | libs/vibrator/fuzzer/Android.bp | 43 | ||||
| -rw-r--r-- | libs/vibrator/fuzzer/README.md | 65 | ||||
| -rw-r--r-- | libs/vibrator/fuzzer/vibrator_fuzzer.cpp | 130 |
4 files changed, 246 insertions, 1 deletions
diff --git a/libs/vibrator/Android.bp b/libs/vibrator/Android.bp index e95a080957..33ab8bab51 100644 --- a/libs/vibrator/Android.bp +++ b/libs/vibrator/Android.bp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -cc_library_shared { +cc_library { name: "libvibrator", shared_libs: [ @@ -45,4 +45,11 @@ cc_library_shared { ], export_include_dirs: ["include"], + + host_supported: true, + target: { + darwin: { + enabled: false, + }, + }, } diff --git a/libs/vibrator/fuzzer/Android.bp b/libs/vibrator/fuzzer/Android.bp new file mode 100644 index 0000000000..802015180e --- /dev/null +++ b/libs/vibrator/fuzzer/Android.bp @@ -0,0 +1,43 @@ +/****************************************************************************** + * + * Copyright (C) 2020 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. + * + ***************************************************************************** + */ + +cc_fuzz { + name: "vibrator_fuzzer", + + host_supported: true, + + srcs: [ + "vibrator_fuzzer.cpp", + ], + + static_libs: [ + "liblog", + "libvibrator", + ], + + shared_libs: [ + "libbinder", + "libbase", + "libutils", + ], + + fuzz_config: { + componentid: 155276, + }, +} diff --git a/libs/vibrator/fuzzer/README.md b/libs/vibrator/fuzzer/README.md new file mode 100644 index 0000000000..43eb2d2919 --- /dev/null +++ b/libs/vibrator/fuzzer/README.md @@ -0,0 +1,65 @@ +# Fuzzer for libvibrator + +## Plugin Design Considerations +This fuzzer fuzzes native code present in libvibrator and does not cover the Java implementation ExternalVibration +The fuzzer plugin is designed based on the understanding of the +library and tries to achieve the following: + +##### Maximize code coverage +The configuration parameters are not hardcoded, but instead selected based on +incoming data. This ensures more code paths are reached by the fuzzer. + +libvibrator supports the following parameters: +1. Uid (parameter name: `uid`) +2. Package Name (parameter name: `pkg`) +3. Audio Content Type (parameter name: `content_type`) +4. Audio Usage (parameter name: `usage`) +5. Audio Source (parameter name: `source`) +6. Audio flags (parameter name: `flags`) + +| Parameter| Valid Values| Configured Value| +|------------- |-------------| ----- | +| `uid` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider | +| `pkg` | Any std::string value | Value obtained from FuzzedDataProvider | +| `content_type` | 0.`AUDIO_CONTENT_TYPE_UNKNOWN` 1.`AUDIO_CONTENT_TYPE_SPEECH` 2.`AUDIO_CONTENT_TYPE_MUSIC` 3.`AUDIO_CONTENT_TYPE_MOVIE` 4.`AUDIO_CONTENT_TYPE_SONIFICATION`| Value obtained from FuzzedDataProvider in the range 0 to 4| +| `usage` | 0.`AUDIO_USAGE_UNKNOWN` 1.`AUDIO_USAGE_MEDIA` 2.`AUDIO_USAGE_VOICE_COMMUNICATION` 3.`AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING` 4.`AUDIO_USAGE_ALARM` 5.`AUDIO_USAGE_NOTIFICATION` 6.`AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE` 7.`AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST` 8.`AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT` 9.`AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED` 10.`AUDIO_USAGE_NOTIFICATION_EVENT` 11.`AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY` 12.`AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE` 13.`AUDIO_USAGE_ASSISTANCE_SONIFICATION` 14.`AUDIO_USAGE_GAME` 15.`AUDIO_USAGE_VIRTUAL_SOURCE` 16.`AUDIO_USAGE_ASSISTANT` 17.`AUDIO_USAGE_CALL_ASSISTANT` 18.`AUDIO_USAGE_EMERGENCY` 19.`AUDIO_USAGE_SAFETY` 20.`AUDIO_USAGE_VEHICLE_STATUS` 21.`AUDIO_USAGE_ANNOUNCEMENT`| Value obtained from FuzzedDataProvider in the range 0 to 21| +| `source` | 0.`AUDIO_SOURCE_DEFAULT` 1.`AUDIO_SOURCE_MIC` 2.`AUDIO_SOURCE_VOICE_UPLINK` 3.`AUDIO_SOURCE_VOICE_DOWNLINK` 4.`AUDIO_SOURCE_VOICE_CALL` 5.`AUDIO_SOURCE_CAMCORDER` 6.`AUDIO_SOURCE_VOICE_RECOGNITION` 7.`AUDIO_SOURCE_VOICE_COMMUNICATION` 8.`AUDIO_SOURCE_REMOTE_SUBMIX` 9.`AUDIO_SOURCE_UNPROCESSED` 10.`AUDIO_SOURCE_VOICE_PERFORMANCE` 11.`AUDIO_SOURCE_ECHO_REFERENCE` 12.`AUDIO_SOURCE_FM_TUNER` | Value obtained from FuzzedDataProvider in the range 0 to 12 | +| `flags` | `UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider | + +This also ensures that the plugin is always deterministic for any given input. + +##### Maximize utilization of input data +The plugin tolerates any kind of input (empty, huge, +malformed, etc) and doesn't `exit()` on any input and thereby increasing the +chance of identifying vulnerabilities. + +## Build + +This describes steps to build vibrator_fuzzer binary. + +### Android + +#### Steps to build +Build the fuzzer +``` + $ mm -j$(nproc) vibrator_fuzzer +``` + +#### Steps to run +Create a directory CORPUS_DIR and copy some files to that folder +Push this directory to device. + +To run on device +``` + $ adb sync data + $ adb shell /data/fuzz/arm64/vibrator_fuzzer/vibrator_fuzzer CORPUS_DIR +``` + +To run on host +``` + $ $ANDROID_HOST_OUT/fuzz/x86_64/vibrator_fuzzer/vibrator_fuzzer CORPUS_DIR +``` + +## References: + * http://llvm.org/docs/LibFuzzer.html + * https://github.com/google/oss-fuzz diff --git a/libs/vibrator/fuzzer/vibrator_fuzzer.cpp b/libs/vibrator/fuzzer/vibrator_fuzzer.cpp new file mode 100644 index 0000000000..68b3ca601e --- /dev/null +++ b/libs/vibrator/fuzzer/vibrator_fuzzer.cpp @@ -0,0 +1,130 @@ +/****************************************************************************** + * + * Copyright (C) 2020 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 <binder/Parcel.h> +#include <fuzzer/FuzzedDataProvider.h> +#include <vibrator/ExternalVibration.h> + +using namespace android; + +constexpr size_t MAX_STRING_LENGTH = 100; +constexpr audio_content_type_t AUDIO_CONTENT_TYPE[] = {AUDIO_CONTENT_TYPE_UNKNOWN, + AUDIO_CONTENT_TYPE_SPEECH, + AUDIO_CONTENT_TYPE_MUSIC, + AUDIO_CONTENT_TYPE_MOVIE, + AUDIO_CONTENT_TYPE_SONIFICATION}; +constexpr audio_usage_t AUDIO_USAGE[] = { + AUDIO_USAGE_UNKNOWN, + AUDIO_USAGE_MEDIA, + AUDIO_USAGE_VOICE_COMMUNICATION, + AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING, + AUDIO_USAGE_ALARM, + AUDIO_USAGE_NOTIFICATION, + AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, + AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST, + AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT, + AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED, + AUDIO_USAGE_NOTIFICATION_EVENT, + AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY, + AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, + AUDIO_USAGE_ASSISTANCE_SONIFICATION, + AUDIO_USAGE_GAME, + AUDIO_USAGE_VIRTUAL_SOURCE, + AUDIO_USAGE_ASSISTANT, + AUDIO_USAGE_CALL_ASSISTANT, + AUDIO_USAGE_EMERGENCY, + AUDIO_USAGE_SAFETY, + AUDIO_USAGE_VEHICLE_STATUS, + AUDIO_USAGE_ANNOUNCEMENT, +}; +constexpr audio_source_t AUDIO_SOURCE[] = { + AUDIO_SOURCE_DEFAULT, AUDIO_SOURCE_MIC, + AUDIO_SOURCE_VOICE_UPLINK, AUDIO_SOURCE_VOICE_DOWNLINK, + AUDIO_SOURCE_VOICE_CALL, AUDIO_SOURCE_CAMCORDER, + AUDIO_SOURCE_VOICE_RECOGNITION, AUDIO_SOURCE_VOICE_COMMUNICATION, + AUDIO_SOURCE_REMOTE_SUBMIX, AUDIO_SOURCE_UNPROCESSED, + AUDIO_SOURCE_VOICE_PERFORMANCE, AUDIO_SOURCE_ECHO_REFERENCE, + AUDIO_SOURCE_FM_TUNER, +}; +constexpr size_t NUM_AUDIO_CONTENT_TYPE = std::size(AUDIO_CONTENT_TYPE); +constexpr size_t NUM_AUDIO_USAGE = std::size(AUDIO_USAGE); +constexpr size_t NUM_AUDIO_SOURCE = std::size(AUDIO_SOURCE); + +class TestVibrationController : public os::IExternalVibrationController { +public: + explicit TestVibrationController() {} + IBinder *onAsBinder() override { return nullptr; } + binder::Status mute(/*out*/ bool *ret) override { + *ret = false; + return binder::Status::ok(); + }; + binder::Status unmute(/*out*/ bool *ret) override { + *ret = false; + return binder::Status::ok(); + }; +}; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size < 1) { + return 0; + } + FuzzedDataProvider fdp = FuzzedDataProvider(data, size); + // Initialize the parameters using FuzzedDataProvider + int32_t uid = fdp.ConsumeIntegral<int32_t>(); + std::string pkg = fdp.ConsumeRandomLengthString(MAX_STRING_LENGTH); + audio_attributes_t attributes; + attributes.content_type = + AUDIO_CONTENT_TYPE[fdp.ConsumeIntegralInRange<uint32_t>(0, NUM_AUDIO_CONTENT_TYPE - 1)]; + attributes.usage = AUDIO_USAGE[fdp.ConsumeIntegralInRange<uint32_t>(0, NUM_AUDIO_USAGE - 1)]; + attributes.source = AUDIO_SOURCE[fdp.ConsumeIntegralInRange<uint32_t>(0, NUM_AUDIO_SOURCE - 1)]; + attributes.flags = static_cast<audio_flags_mask_t>(fdp.ConsumeIntegral<uint32_t>()); + + // Create an instance of TestVibrationController + sp<TestVibrationController> vibrationController = new TestVibrationController(); + if (!vibrationController) { + return 0; + } + + // Set all the parameters in the constructor call + sp<os::ExternalVibration> extVibration = + new os::ExternalVibration(uid, pkg, attributes, vibrationController); + if (!extVibration) { + return 0; + } + + // Get all the parameters that were previously set + extVibration->getUid(); + extVibration->getPackage(); + extVibration->getAudioAttributes(); + extVibration->getController(); + + // Set the parameters in a Parcel object and send it to libvibrator + // This parcel shall be read by libvibrator + Parcel parcel; + parcel.writeInt32(uid); + parcel.writeString16(String16(pkg.c_str())); + parcel.writeStrongBinder(IInterface::asBinder(vibrationController)); + parcel.setDataPosition(0); + extVibration->readFromParcel(&parcel); + + // Send a Parcel to libvibrator + // Parameters shall be written to this parcel by libvibrator + extVibration->writeToParcel(&parcel); + return 0; +} |