Loading services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp +183 −269 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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); 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::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()); } } 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; } 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; } } } 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); } 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::invokeTimeMachineStorage(const uint8_t *data, size_t size) { FuzzedDataProvider fdp = FuzzedDataProvider(data, size); 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::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(); } std::shared_ptr<mediametrics::Item> MediaMetricsServiceFuzzer::CreateItem() { std::string key; if (mFdp.ConsumeBool()) { key = mFdp.ConsumeRandomLengthString(kMaxItemLength); } else { key = mFdp.PickValueInArray<std::string>(keyMediaValues); } 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"}); } if (keySet.find(keyValue) == keySet.end()) { setKeyValues(item, keyValue); keySet.insert(keyValue); } } return item; } void MediaMetricsServiceFuzzer::invokeStartsWith() { android::mediametrics::startsWith(mFdp.ConsumeRandomLengthString(kMaxBytes), mFdp.ConsumeRandomLengthString(kMaxBytes)); } void MediaMetricsServiceFuzzer::invokeInstantiate() { auto item = CreateItem(); mMediaMetricsService->submit(item.get()); } 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; Loading @@ -253,65 +202,31 @@ void MediaMetricsServiceFuzzer::invokeTimeMachineStorage(const uint8_t *data, si 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(), (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; })); } 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()); auto item = CreateItem(); (*item).set("event", mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()); // get the actions and execute them auto actions = analyticsActions.getActionsForItem(item); Loading @@ -319,58 +234,57 @@ void MediaMetricsServiceFuzzer::invokeAnalyticsAction(const uint8_t *data, size_ 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; while (fdp.remaining_bytes()) { timedAction.postIn(std::chrono::seconds(fdp.ConsumeIntegral<int32_t>()), timedAction.postIn(std::chrono::seconds(mFdp.ConsumeIntegral<uint32_t>()), [this] { ++mValue; }); timedAction.size(); } } 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); 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(); } } 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; } Loading
services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp +183 −269 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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); 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::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()); } } 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; } 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; } } } 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); } 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::invokeTimeMachineStorage(const uint8_t *data, size_t size) { FuzzedDataProvider fdp = FuzzedDataProvider(data, size); 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::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(); } std::shared_ptr<mediametrics::Item> MediaMetricsServiceFuzzer::CreateItem() { std::string key; if (mFdp.ConsumeBool()) { key = mFdp.ConsumeRandomLengthString(kMaxItemLength); } else { key = mFdp.PickValueInArray<std::string>(keyMediaValues); } 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"}); } if (keySet.find(keyValue) == keySet.end()) { setKeyValues(item, keyValue); keySet.insert(keyValue); } } return item; } void MediaMetricsServiceFuzzer::invokeStartsWith() { android::mediametrics::startsWith(mFdp.ConsumeRandomLengthString(kMaxBytes), mFdp.ConsumeRandomLengthString(kMaxBytes)); } void MediaMetricsServiceFuzzer::invokeInstantiate() { auto item = CreateItem(); mMediaMetricsService->submit(item.get()); } 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; Loading @@ -253,65 +202,31 @@ void MediaMetricsServiceFuzzer::invokeTimeMachineStorage(const uint8_t *data, si 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(), (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; })); } 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()); auto item = CreateItem(); (*item).set("event", mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()); // get the actions and execute them auto actions = analyticsActions.getActionsForItem(item); Loading @@ -319,58 +234,57 @@ void MediaMetricsServiceFuzzer::invokeAnalyticsAction(const uint8_t *data, size_ 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; while (fdp.remaining_bytes()) { timedAction.postIn(std::chrono::seconds(fdp.ConsumeIntegral<int32_t>()), timedAction.postIn(std::chrono::seconds(mFdp.ConsumeIntegral<uint32_t>()), [this] { ++mValue; }); timedAction.size(); } } 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); 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(); } } 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; }