Merge "Refactored mediametrics_service_fuzzer" into main am: f9e0df6c53 am: b7b6291fea
Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/3079504
Change-Id: Ia8ebbd5abaccb763ea25d064ac2323d0c36ad6fa
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp b/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp
index c6793a9..c7b4297 100644
--- a/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp
+++ b/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp
@@ -17,6 +17,7 @@
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
+#include <binder/IPCThreadState.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <media/MediaMetricsItem.h>
#include <mediametricsservice/AudioTypes.h>
@@ -26,210 +27,158 @@
#include <string.h>
#include <utils/Log.h>
#include <algorithm>
+#include <set>
using namespace android;
+static constexpr size_t STATSD_LOG_LINES_MAX = 48;
+static unsigned long long kPackedCallingUid = (unsigned long long)AID_SYSTEM << 32;
+constexpr int8_t kMaxBytes = 100;
+constexpr int8_t kMinBytes = 0;
+constexpr size_t kMaxItemLength = 16;
// low water mark
constexpr size_t kLogItemsLowWater = 1;
// high water mark
constexpr size_t kLogItemsHighWater = 2;
-constexpr size_t kMaxItemLength = 16;
-constexpr size_t kMaxApis = 64;
+
+/*
+ * Concatenating strings to generate keys in such a way that the
+ * lambda function inside AudioAnalytics() added in the 'mAction' object is covered
+ */
+
+std::string keyMediaValues[] = {
+ "metrics.manager",
+ "mediadrm",
+ "audio.device.a2dp",
+ AMEDIAMETRICS_KEY_AUDIO_MIDI,
+ AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER "*",
+ AMEDIAMETRICS_KEY_PREFIX_AUDIO_THREAD "*",
+ AMEDIAMETRICS_KEY_AUDIO_FLINGER,
+ AMEDIAMETRICS_KEY_AUDIO_POLICY,
+ AMEDIAMETRICS_KEY_PREFIX_AUDIO_TRACK "*",
+ AMEDIAMETRICS_KEY_PREFIX_AUDIO_RECORD "*",
+ AMEDIAMETRICS_KEY_PREFIX_AUDIO_STREAM "*",
+ AMEDIAMETRICS_KEY_PREFIX_AUDIO_DEVICE
+ "postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent",
+};
+
+std::string keyMediaAction[] = {
+ "createAudioPatch",
+ "connected",
+ AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE,
+ AMEDIAMETRICS_PROP_EVENT_VALUE_TIMEOUT,
+ AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR,
+ AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAAUDIOSTREAM,
+ AMEDIAMETRICS_PROP_EVENT_VALUE_DEVICECLOSED,
+ AMEDIAMETRICS_PROP_EVENT_VALUE_SETVOICEVOLUME,
+ AMEDIAMETRICS_PROP_EVENT_VALUE_SETMODE,
+ AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAUDIOINTERVALGROUP,
+};
class MediaMetricsServiceFuzzer {
- public:
- void invokeStartsWith(const uint8_t *data, size_t size);
- void invokeInstantiate(const uint8_t *data, size_t size);
- void invokePackageInstallerCheck(const uint8_t *data, size_t size);
- void invokeItemManipulation(const uint8_t *data, size_t size);
- void invokeItemExpansion(const uint8_t *data, size_t size);
- void invokeTimeMachineStorage(const uint8_t *data, size_t size);
- void invokeTransactionLog(const uint8_t *data, size_t size);
- void invokeAnalyticsAction(const uint8_t *data, size_t size);
- void invokeAudioAnalytics(const uint8_t *data, size_t size);
- void invokeTimedAction(const uint8_t *data, size_t size);
- void process(const uint8_t *data, size_t size);
+ public:
+ MediaMetricsServiceFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void process();
+ void invokeStartsWith();
+ void invokeInstantiate();
+ void invokePackageInstallerCheck();
+ void invokeTimeMachineStorage();
+ void invokeTransactionLog();
+ void invokeAnalyticsAction();
+ void invokeAudioAnalytics();
+ void invokeTimedAction();
+ void setKeyValues(std::shared_ptr<mediametrics::Item>& item, std::string keyValue);
+ std::shared_ptr<mediametrics::Item> CreateItem();
+ sp<MediaMetricsService> mMediaMetricsService;
+ FuzzedDataProvider mFdp;
std::atomic_int mValue = 0;
};
-void MediaMetricsServiceFuzzer::invokeStartsWith(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- while (fdp.remaining_bytes()) {
- android::mediametrics::startsWith(fdp.ConsumeRandomLengthString(),
- fdp.ConsumeRandomLengthString());
- }
+void MediaMetricsServiceFuzzer::setKeyValues(std::shared_ptr<mediametrics::Item>& item,
+ std::string keyValue) {
+ auto invokeActionAPIs = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() { item->setInt32(keyValue.c_str(), mFdp.ConsumeIntegral<int32_t>()); },
+ [&]() { item->addInt32(keyValue.c_str(), mFdp.ConsumeIntegral<int32_t>()); },
+ [&]() { item->setInt64(keyValue.c_str(), mFdp.ConsumeIntegral<int64_t>()); },
+ [&]() { item->addInt64(keyValue.c_str(), mFdp.ConsumeIntegral<int64_t>()); },
+ [&]() { item->setDouble(keyValue.c_str(), mFdp.ConsumeFloatingPoint<double>()); },
+ [&]() { item->addDouble(keyValue.c_str(), mFdp.ConsumeFloatingPoint<double>()); },
+ [&]() { item->setTimestamp(mFdp.ConsumeIntegral<int64_t>()); },
+ [&]() {
+ std::string value = mFdp.ConsumeBool()
+ ? mFdp.ConsumeRandomLengthString(kMaxBytes)
+ : mFdp.PickValueInArray<std::string>(keyMediaAction);
+ item->setCString(keyValue.c_str(), value.c_str());
+ },
+ [&]() {
+ item->setRate(keyValue.c_str(), mFdp.ConsumeIntegral<int64_t>(),
+ mFdp.ConsumeIntegral<int64_t>());
+ },
+ [&]() {
+ mediametrics::LogItem<1> itemTemp(mFdp.ConsumeRandomLengthString(kMaxBytes));
+ itemTemp.setPid(mFdp.ConsumeIntegral<int16_t>())
+ .setUid(mFdp.ConsumeIntegral<int16_t>());
+
+ int32_t i = mFdp.ConsumeIntegral<int32_t>();
+ itemTemp.set(std::to_string(i).c_str(), (int32_t)i);
+ itemTemp.updateHeader();
+ (void)item->readFromByteString(itemTemp.getBuffer(), itemTemp.getLength());
+ },
+
+ });
+ invokeActionAPIs();
}
-void MediaMetricsServiceFuzzer::invokeInstantiate(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- sp mediaMetricsService = new MediaMetricsService();
-
- while (fdp.remaining_bytes()) {
- std::unique_ptr<mediametrics::Item> random_key(
- mediametrics::Item::create(fdp.ConsumeRandomLengthString()));
- mediaMetricsService->submit(random_key.get());
- random_key->setInt32(fdp.ConsumeRandomLengthString().c_str(),
- fdp.ConsumeIntegral<int32_t>());
- mediaMetricsService->submit(random_key.get());
-
- std::unique_ptr<mediametrics::Item> audiotrack_key(
- mediametrics::Item::create("audiotrack"));
- mediaMetricsService->submit(audiotrack_key.get());
- audiotrack_key->addInt32(fdp.ConsumeRandomLengthString().c_str(),
- fdp.ConsumeIntegral<int32_t>());
- mediaMetricsService->submit(audiotrack_key.get());
+std::shared_ptr<mediametrics::Item> MediaMetricsServiceFuzzer::CreateItem() {
+ std::string key;
+ if (mFdp.ConsumeBool()) {
+ key = mFdp.ConsumeRandomLengthString(kMaxItemLength);
+ } else {
+ key = mFdp.PickValueInArray<std::string>(keyMediaValues);
}
-}
-void MediaMetricsServiceFuzzer::invokePackageInstallerCheck(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- while (fdp.remaining_bytes()) {
- MediaMetricsService::useUidForPackage(fdp.ConsumeRandomLengthString().c_str(),
- fdp.ConsumeRandomLengthString().c_str());
- }
-}
-
-void MediaMetricsServiceFuzzer::invokeItemManipulation(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-
- mediametrics::Item item(fdp.ConsumeRandomLengthString().c_str());
- while (fdp.remaining_bytes()) {
- const uint8_t action = fdp.ConsumeIntegralInRange<uint8_t>(0, 16);
- const std::string key = fdp.ConsumeRandomLengthString();
- if (fdp.remaining_bytes() < 1 || key.length() < 1) {
- break;
+ std::shared_ptr<mediametrics::Item> item = std::make_shared<mediametrics::Item>(key.c_str());
+ size_t numKeys = mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes);
+ std::set<std::string> keySet;
+ for (size_t i = 0; i < numKeys; ++i) {
+ std::string keyValue;
+ if (mFdp.ConsumeBool()) {
+ keyValue = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ } else {
+ keyValue = mFdp.PickValueInArray<std::string>(
+ {AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_STATE, "logSessionIkeyd"});
}
- switch (action) {
- case 0: {
- item.setInt32(key.c_str(), fdp.ConsumeIntegral<int32_t>());
- break;
- }
- case 1: {
- item.addInt32(key.c_str(), fdp.ConsumeIntegral<int32_t>());
- break;
- }
- case 2: {
- int32_t i32 = 0;
- item.getInt32(key.c_str(), &i32);
- break;
- }
- case 3: {
- item.setInt64(key.c_str(), fdp.ConsumeIntegral<int64_t>());
- break;
- }
- case 4: {
- item.addInt64(key.c_str(), fdp.ConsumeIntegral<int64_t>());
- break;
- }
- case 5: {
- int64_t i64 = 0;
- item.getInt64(key.c_str(), &i64);
- break;
- }
- case 6: {
- item.setDouble(key.c_str(), fdp.ConsumeFloatingPoint<double>());
- break;
- }
- case 7: {
- item.addDouble(key.c_str(), fdp.ConsumeFloatingPoint<double>());
- break;
- }
- case 8: {
- double d = 0;
- item.getDouble(key.c_str(), &d);
- break;
- }
- case 9: {
- item.setCString(key.c_str(), fdp.ConsumeRandomLengthString().c_str());
- break;
- }
- case 10: {
- char *s = nullptr;
- item.getCString(key.c_str(), &s);
- if (s) free(s);
- break;
- }
- case 11: {
- std::string s;
- item.getString(key.c_str(), &s);
- break;
- }
- case 12: {
- item.setRate(key.c_str(), fdp.ConsumeIntegral<int64_t>(),
- fdp.ConsumeIntegral<int64_t>());
- break;
- }
- case 13: {
- int64_t b = 0, h = 0;
- double d = 0;
- item.getRate(key.c_str(), &b, &h, &d);
- break;
- }
- case 14: {
- (void)item.filter(key.c_str());
- break;
- }
- case 15: {
- const char *arr[1] = {""};
- arr[0] = const_cast<char *>(key.c_str());
- (void)item.filterNot(1, arr);
- break;
- }
- case 16: {
- (void)item.toString().c_str();
- break;
- }
+ if (keySet.find(keyValue) == keySet.end()) {
+ setKeyValues(item, keyValue);
+ keySet.insert(keyValue);
}
}
-
- Parcel p;
- mediametrics::Item item2;
-
- (void)item.writeToParcel(&p);
- p.setDataPosition(0); // rewind for reading
- (void)item2.readFromParcel(p);
-
- char *byteData = nullptr;
- size_t length = 0;
- (void)item.writeToByteString(&byteData, &length);
- (void)item2.readFromByteString(byteData, length);
- if (byteData) {
- free(byteData);
- }
-
- sp mediaMetricsService = new MediaMetricsService();
- mediaMetricsService->submit(&item2);
+ return item;
}
-void MediaMetricsServiceFuzzer::invokeItemExpansion(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-
- mediametrics::LogItem<1> item("FuzzItem");
- item.setPid(fdp.ConsumeIntegral<int16_t>()).setUid(fdp.ConsumeIntegral<int16_t>());
-
- while (fdp.remaining_bytes()) {
- int32_t i = fdp.ConsumeIntegral<int32_t>();
- item.set(std::to_string(i).c_str(), (int32_t)i);
- }
- item.updateHeader();
-
- mediametrics::Item item2;
- (void)item2.readFromByteString(item.getBuffer(), item.getLength());
-
- sp mediaMetricsService = new MediaMetricsService();
- mediaMetricsService->submit(&item2);
+void MediaMetricsServiceFuzzer::invokeStartsWith() {
+ android::mediametrics::startsWith(mFdp.ConsumeRandomLengthString(kMaxBytes),
+ mFdp.ConsumeRandomLengthString(kMaxBytes));
}
-void MediaMetricsServiceFuzzer::invokeTimeMachineStorage(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+void MediaMetricsServiceFuzzer::invokeInstantiate() {
+ auto item = CreateItem();
+ mMediaMetricsService->submit(item.get());
+}
- auto item = std::make_shared<mediametrics::Item>("FuzzKey");
- int32_t i32 = fdp.ConsumeIntegral<int32_t>();
- int64_t i64 = fdp.ConsumeIntegral<int64_t>();
- double d = fdp.ConsumeFloatingPoint<double>();
- std::string str = fdp.ConsumeRandomLengthString();
- std::pair<int64_t, int64_t> pair(fdp.ConsumeIntegral<int64_t>(),
- fdp.ConsumeIntegral<int64_t>());
+void MediaMetricsServiceFuzzer::invokePackageInstallerCheck() {
+ MediaMetricsService::useUidForPackage(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str(),
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str());
+}
+
+void MediaMetricsServiceFuzzer::invokeTimeMachineStorage() {
+ auto item = CreateItem();
+ int32_t i32 = mFdp.ConsumeIntegral<int32_t>();
+ int64_t i64 = mFdp.ConsumeIntegral<int64_t>();
+ double d = mFdp.ConsumeFloatingPoint<double>();
+ std::string str = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ std::pair<int64_t, int64_t> pair(mFdp.ConsumeIntegral<int64_t>(),
+ mFdp.ConsumeIntegral<int64_t>());
(*item).set("i32", i32).set("i64", i64).set("double", d).set("string", str).set("rate", pair);
android::mediametrics::TimeMachine timeMachine;
@@ -253,124 +202,89 @@
timeMachine.get("Key.string", &str, -1);
}
-void MediaMetricsServiceFuzzer::invokeTransactionLog(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-
- auto item = std::make_shared<mediametrics::Item>("Key1");
- (*item)
- .set("one", fdp.ConsumeIntegral<int32_t>())
- .set("two", fdp.ConsumeIntegral<int32_t>())
- .setTimestamp(fdp.ConsumeIntegral<int32_t>());
+void MediaMetricsServiceFuzzer::invokeTransactionLog() {
+ auto item = CreateItem();
android::mediametrics::TransactionLog transactionLog(
kLogItemsLowWater, kLogItemsHighWater); // keep at most 2 items
transactionLog.size();
transactionLog.put(item);
- transactionLog.size();
-
- auto item2 = std::make_shared<mediametrics::Item>("Key2");
- (*item2)
- .set("three", fdp.ConsumeIntegral<int32_t>())
- .set("[Key1]three", fdp.ConsumeIntegral<int32_t>())
- .setTimestamp(fdp.ConsumeIntegral<int32_t>());
-
- transactionLog.put(item2);
- transactionLog.size();
-
- auto item3 = std::make_shared<mediametrics::Item>("Key3");
- (*item3)
- .set("six", fdp.ConsumeIntegral<int32_t>())
- .set("[Key1]four", fdp.ConsumeIntegral<int32_t>()) // affects Key1
- .set("[Key1]five", fdp.ConsumeIntegral<int32_t>()) // affects key1
- .setTimestamp(fdp.ConsumeIntegral<int32_t>());
-
- transactionLog.put(item3);
- transactionLog.size();
}
-void MediaMetricsServiceFuzzer::invokeAnalyticsAction(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-
+void MediaMetricsServiceFuzzer::invokeAnalyticsAction() {
mediametrics::AnalyticsActions analyticsActions;
bool action = false;
- while (fdp.remaining_bytes()) {
- analyticsActions.addAction(
- (fdp.ConsumeRandomLengthString() + std::string(".event")).c_str(),
- fdp.ConsumeRandomLengthString(),
+ analyticsActions.addAction(
+ (mFdp.ConsumeRandomLengthString(kMaxBytes) + std::string(".event")).c_str(),
+ mFdp.ConsumeRandomLengthString(kMaxBytes),
std::make_shared<mediametrics::AnalyticsActions::Function>(
- [&](const std::shared_ptr<const android::mediametrics::Item> &) {
- action = true;
- }));
- }
+ [&](const std::shared_ptr<const android::mediametrics::Item>&) {
+ action = true;
+ }));
- FuzzedDataProvider fdp2 = FuzzedDataProvider(data, size);
- size_t apiCount = 0;
- while (fdp2.remaining_bytes() && ++apiCount <= kMaxApis) {
- // make a test item
- auto item = std::make_shared<mediametrics::Item>(
- fdp2.ConsumeRandomLengthString(kMaxItemLength).c_str());
- (*item).set("event", fdp2.ConsumeRandomLengthString().c_str());
+ // make a test item
+ auto item = CreateItem();
+ (*item).set("event", mFdp.ConsumeRandomLengthString(kMaxBytes).c_str());
- // get the actions and execute them
- auto actions = analyticsActions.getActionsForItem(item);
- for (const auto &action : actions) {
- action->operator()(item);
+ // get the actions and execute them
+ auto actions = analyticsActions.getActionsForItem(item);
+ for (const auto& action : actions) {
+ action->operator()(item);
}
- }
}
-void MediaMetricsServiceFuzzer::invokeAudioAnalytics(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+void MediaMetricsServiceFuzzer::invokeAudioAnalytics() {
+ int32_t maxLogLine = mFdp.ConsumeIntegralInRange<int32_t>(0, STATSD_LOG_LINES_MAX);
std::shared_ptr<android::mediametrics::StatsdLog> statsdLog =
- std::make_shared<android::mediametrics::StatsdLog>(10);
+ std::make_shared<android::mediametrics::StatsdLog>(maxLogLine);
android::mediametrics::AudioAnalytics audioAnalytics{statsdLog};
- while (fdp.remaining_bytes()) {
- auto item = std::make_shared<mediametrics::Item>(fdp.ConsumeRandomLengthString().c_str());
- int32_t transactionUid = fdp.ConsumeIntegral<int32_t>(); // arbitrary
- (*item)
- .set(fdp.ConsumeRandomLengthString().c_str(), fdp.ConsumeIntegral<int32_t>())
- .set(fdp.ConsumeRandomLengthString().c_str(), fdp.ConsumeIntegral<int32_t>())
- .set(AMEDIAMETRICS_PROP_ALLOWUID, transactionUid)
- .setUid(transactionUid)
- .setTimestamp(fdp.ConsumeIntegral<int32_t>());
- audioAnalytics.submit(item, fdp.ConsumeBool());
+ auto item = CreateItem();
+ Parcel parcel;
+ item->writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ if (mFdp.ConsumeBool()) {
+ item->readFromParcel(parcel);
}
-
- audioAnalytics.dump(1000);
+ audioAnalytics.submit(item, mFdp.ConsumeBool());
}
-void MediaMetricsServiceFuzzer::invokeTimedAction(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+void MediaMetricsServiceFuzzer::invokeTimedAction() {
android::mediametrics::TimedAction timedAction;
+ timedAction.postIn(std::chrono::seconds(mFdp.ConsumeIntegral<uint32_t>()),
+ [this] { ++mValue; });
+ timedAction.size();
+}
- while (fdp.remaining_bytes()) {
- timedAction.postIn(std::chrono::seconds(fdp.ConsumeIntegral<int32_t>()),
- [this] { ++mValue; });
- timedAction.size();
+void MediaMetricsServiceFuzzer::process() {
+ mMediaMetricsService = sp<MediaMetricsService>::make();
+
+ if (mFdp.ConsumeBool()) {
+ IPCThreadState::self()->restoreCallingIdentity(kPackedCallingUid);
+ } else {
+ IPCThreadState::self()->restoreCallingIdentity(mFdp.ConsumeIntegral<size_t>());
+ }
+ while (mFdp.remaining_bytes()) {
+ auto invokeAPIs = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() { invokeStartsWith(); },
+ [&]() { invokeInstantiate(); },
+ [&]() { invokePackageInstallerCheck(); },
+ [&]() { invokeTimeMachineStorage(); },
+ [&]() { invokeTransactionLog(); },
+ [&]() { invokeAudioAnalytics(); },
+ [&]() { invokeTimedAction(); },
+ });
+ invokeAPIs();
}
}
-void MediaMetricsServiceFuzzer::process(const uint8_t *data, size_t size) {
- invokeStartsWith(data, size);
- invokeInstantiate(data, size);
- invokePackageInstallerCheck(data, size);
- invokeItemManipulation(data, size);
- invokeItemExpansion(data, size);
- invokeTimeMachineStorage(data, size);
- invokeTransactionLog(data, size);
- invokeAnalyticsAction(data, size);
- invokeAudioAnalytics(data, size);
- invokeTimedAction(data, size);
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size < 1) {
return 0;
}
- MediaMetricsServiceFuzzer mediaMetricsServiceFuzzer;
- mediaMetricsServiceFuzzer.process(data, size);
+ MediaMetricsServiceFuzzer mediaMetricsServiceFuzzer(data, size);
+ mediaMetricsServiceFuzzer.process();
return 0;
}