/* * Copyright 2022 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 #include #include #include #include #include "android-base/stringprintf.h" using namespace android; constexpr int32_t kRandomStringMaxBytes = 256; constexpr ui::ColorMode kColormodes[] = {ui::ColorMode::NATIVE, ui::ColorMode::STANDARD_BT601_625, ui::ColorMode::STANDARD_BT601_625_UNADJUSTED, ui::ColorMode::STANDARD_BT601_525, ui::ColorMode::STANDARD_BT601_525_UNADJUSTED, ui::ColorMode::STANDARD_BT709, ui::ColorMode::DCI_P3, ui::ColorMode::SRGB, ui::ColorMode::ADOBE_RGB, ui::ColorMode::DISPLAY_P3, ui::ColorMode::BT2020, ui::ColorMode::BT2100_PQ, ui::ColorMode::BT2100_HLG, ui::ColorMode::DISPLAY_BT2020}; constexpr hardware::power::Boost kBoost[] = { hardware::power::Boost::INTERACTION, hardware::power::Boost::DISPLAY_UPDATE_IMMINENT, hardware::power::Boost::ML_ACC, hardware::power::Boost::AUDIO_LAUNCH, hardware::power::Boost::CAMERA_LAUNCH, hardware::power::Boost::CAMERA_SHOT, }; constexpr gui::TouchOcclusionMode kMode[] = { gui::TouchOcclusionMode::BLOCK_UNTRUSTED, gui::TouchOcclusionMode::USE_OPACITY, gui::TouchOcclusionMode::ALLOW, }; constexpr gui::WindowInfo::Flag kFlags[] = { gui::WindowInfo::Flag::ALLOW_LOCK_WHILE_SCREEN_ON, gui::WindowInfo::Flag::DIM_BEHIND, gui::WindowInfo::Flag::BLUR_BEHIND, gui::WindowInfo::Flag::NOT_FOCUSABLE, gui::WindowInfo::Flag::NOT_TOUCHABLE, gui::WindowInfo::Flag::NOT_TOUCH_MODAL, gui::WindowInfo::Flag::TOUCHABLE_WHEN_WAKING, gui::WindowInfo::Flag::KEEP_SCREEN_ON, gui::WindowInfo::Flag::LAYOUT_IN_SCREEN, gui::WindowInfo::Flag::LAYOUT_NO_LIMITS, gui::WindowInfo::Flag::FULLSCREEN, gui::WindowInfo::Flag::FORCE_NOT_FULLSCREEN, gui::WindowInfo::Flag::DITHER, gui::WindowInfo::Flag::SECURE, gui::WindowInfo::Flag::SCALED, gui::WindowInfo::Flag::IGNORE_CHEEK_PRESSES, gui::WindowInfo::Flag::LAYOUT_INSET_DECOR, gui::WindowInfo::Flag::ALT_FOCUSABLE_IM, gui::WindowInfo::Flag::WATCH_OUTSIDE_TOUCH, gui::WindowInfo::Flag::SHOW_WHEN_LOCKED, gui::WindowInfo::Flag::SHOW_WALLPAPER, gui::WindowInfo::Flag::TURN_SCREEN_ON, gui::WindowInfo::Flag::DISMISS_KEYGUARD, gui::WindowInfo::Flag::SPLIT_TOUCH, gui::WindowInfo::Flag::HARDWARE_ACCELERATED, gui::WindowInfo::Flag::LAYOUT_IN_OVERSCAN, gui::WindowInfo::Flag::TRANSLUCENT_STATUS, gui::WindowInfo::Flag::TRANSLUCENT_NAVIGATION, gui::WindowInfo::Flag::LOCAL_FOCUS_MODE, gui::WindowInfo::Flag::SLIPPERY, gui::WindowInfo::Flag::LAYOUT_ATTACHED_IN_DECOR, gui::WindowInfo::Flag::DRAWS_SYSTEM_BAR_BACKGROUNDS, }; constexpr gui::WindowInfo::Type kType[] = { gui::WindowInfo::Type::UNKNOWN, gui::WindowInfo::Type::FIRST_APPLICATION_WINDOW, gui::WindowInfo::Type::BASE_APPLICATION, gui::WindowInfo::Type::APPLICATION, gui::WindowInfo::Type::APPLICATION_STARTING, gui::WindowInfo::Type::LAST_APPLICATION_WINDOW, gui::WindowInfo::Type::FIRST_SUB_WINDOW, gui::WindowInfo::Type::APPLICATION_PANEL, gui::WindowInfo::Type::APPLICATION_MEDIA, gui::WindowInfo::Type::APPLICATION_SUB_PANEL, gui::WindowInfo::Type::APPLICATION_ATTACHED_DIALOG, gui::WindowInfo::Type::APPLICATION_MEDIA_OVERLAY, }; constexpr gui::WindowInfo::InputConfig kFeatures[] = { gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL, gui::WindowInfo::InputConfig::DISABLE_USER_ACTIVITY, gui::WindowInfo::InputConfig::DROP_INPUT, gui::WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED, gui::WindowInfo::InputConfig::SPY, gui::WindowInfo::InputConfig::INTERCEPTS_STYLUS, }; class SurfaceComposerClientFuzzer { public: SurfaceComposerClientFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){}; void process(); private: void invokeSurfaceComposerClient(); void invokeSurfaceComposerClientBinder(); void invokeSurfaceComposerTransaction(); void getWindowInfo(gui::WindowInfo*); sp makeSurfaceControl(); BlurRegion getBlurRegion(); void fuzzOnPullAtom(); gui::DisplayModeSpecs getDisplayModeSpecs(); FuzzedDataProvider mFdp; }; gui::DisplayModeSpecs SurfaceComposerClientFuzzer::getDisplayModeSpecs() { const auto getRefreshRateRange = [&] { gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange range; range.min = mFdp.ConsumeFloatingPoint(); range.max = mFdp.ConsumeFloatingPoint(); return range; }; const auto getRefreshRateRanges = [&] { gui::DisplayModeSpecs::RefreshRateRanges ranges; ranges.physical = getRefreshRateRange(); ranges.render = getRefreshRateRange(); return ranges; }; String8 displayName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str()); sp displayToken = SurfaceComposerClient::createDisplay(displayName, mFdp.ConsumeBool() /*secure*/); gui::DisplayModeSpecs specs; specs.defaultMode = mFdp.ConsumeIntegral(); specs.allowGroupSwitching = mFdp.ConsumeBool(); specs.primaryRanges = getRefreshRateRanges(); specs.appRequestRanges = getRefreshRateRanges(); return specs; } BlurRegion SurfaceComposerClientFuzzer::getBlurRegion() { int32_t left = mFdp.ConsumeIntegral(); int32_t right = mFdp.ConsumeIntegral(); int32_t top = mFdp.ConsumeIntegral(); int32_t bottom = mFdp.ConsumeIntegral(); uint32_t blurRadius = mFdp.ConsumeIntegral(); float alpha = mFdp.ConsumeFloatingPoint(); float cornerRadiusTL = mFdp.ConsumeFloatingPoint(); float cornerRadiusTR = mFdp.ConsumeFloatingPoint(); float cornerRadiusBL = mFdp.ConsumeFloatingPoint(); float cornerRadiusBR = mFdp.ConsumeFloatingPoint(); return BlurRegion{blurRadius, cornerRadiusTL, cornerRadiusTR, cornerRadiusBL, cornerRadiusBR, alpha, left, top, right, bottom}; } void SurfaceComposerClientFuzzer::getWindowInfo(gui::WindowInfo* windowInfo) { windowInfo->id = mFdp.ConsumeIntegral(); windowInfo->name = mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes); windowInfo->layoutParamsFlags = mFdp.PickValueInArray(kFlags); windowInfo->layoutParamsType = mFdp.PickValueInArray(kType); windowInfo->frameLeft = mFdp.ConsumeIntegral(); windowInfo->frameTop = mFdp.ConsumeIntegral(); windowInfo->frameRight = mFdp.ConsumeIntegral(); windowInfo->frameBottom = mFdp.ConsumeIntegral(); windowInfo->surfaceInset = mFdp.ConsumeIntegral(); windowInfo->alpha = mFdp.ConsumeFloatingPointInRange(0, 1); ui::Transform transform(mFdp.PickValueInArray(kOrientation)); windowInfo->transform = transform; windowInfo->touchableRegion = Region(getRect(&mFdp)); windowInfo->replaceTouchableRegionWithCrop = mFdp.ConsumeBool(); windowInfo->touchOcclusionMode = mFdp.PickValueInArray(kMode); windowInfo->ownerPid = gui::Pid{mFdp.ConsumeIntegral()}; windowInfo->ownerUid = gui::Uid{mFdp.ConsumeIntegral()}; windowInfo->packageName = mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes); windowInfo->inputConfig = mFdp.PickValueInArray(kFeatures); } sp SurfaceComposerClientFuzzer::makeSurfaceControl() { sp handle; const sp testClient(new FakeBnSurfaceComposerClient()); sp client = new SurfaceComposerClient(testClient); sp producer; uint32_t width = mFdp.ConsumeIntegral(); uint32_t height = mFdp.ConsumeIntegral(); uint32_t transformHint = mFdp.ConsumeIntegral(); uint32_t flags = mFdp.ConsumeIntegral(); int32_t format = mFdp.ConsumeIntegral(); int32_t layerId = mFdp.ConsumeIntegral(); std::string layerName = base::StringPrintf("#%d", layerId); return new SurfaceControl(client, handle, layerId, layerName, width, height, format, transformHint, flags); } void SurfaceComposerClientFuzzer::invokeSurfaceComposerTransaction() { sp surface = makeSurfaceControl(); SurfaceComposerClient::Transaction transaction; int32_t layer = mFdp.ConsumeIntegral(); transaction.setLayer(surface, layer); sp relativeSurface = makeSurfaceControl(); transaction.setRelativeLayer(surface, relativeSurface, layer); Region transparentRegion(getRect(&mFdp)); transaction.setTransparentRegionHint(surface, transparentRegion); transaction.setAlpha(surface, mFdp.ConsumeFloatingPoint()); transaction.setCornerRadius(surface, mFdp.ConsumeFloatingPoint()); transaction.setBackgroundBlurRadius(surface, mFdp.ConsumeFloatingPoint()); std::vector regions; uint32_t vectorSize = mFdp.ConsumeIntegralInRange(0, 100); regions.resize(vectorSize); for (size_t idx = 0; idx < vectorSize; ++idx) { regions.push_back(getBlurRegion()); } transaction.setBlurRegions(surface, regions); transaction.setLayerStack(surface, {mFdp.ConsumeIntegral()}); half3 color = {mFdp.ConsumeIntegral(), mFdp.ConsumeIntegral(), mFdp.ConsumeIntegral()}; transaction.setColor(surface, color); transaction.setBackgroundColor(surface, color, mFdp.ConsumeFloatingPoint(), mFdp.PickValueInArray(kDataspaces)); transaction.setApi(surface, mFdp.ConsumeIntegral()); transaction.setFrameRateSelectionPriority(surface, mFdp.ConsumeIntegral()); transaction.setColorSpaceAgnostic(surface, mFdp.ConsumeBool() /*agnostic*/); gui::WindowInfo windowInfo; getWindowInfo(&windowInfo); transaction.setInputWindowInfo(surface, windowInfo); Parcel windowParcel; windowInfo.writeToParcel(&windowParcel); windowParcel.setDataPosition(0); windowInfo.readFromParcel(&windowParcel); windowInfo.addTouchableRegion(getRect(&mFdp)); int32_t pointX = mFdp.ConsumeIntegral(); int32_t pointY = mFdp.ConsumeIntegral(); windowInfo.touchableRegionContainsPoint(pointX, pointY); windowInfo.frameContainsPoint(pointX, pointY); Parcel transactionParcel; transaction.writeToParcel(&transactionParcel); transactionParcel.setDataPosition(0); transaction.readFromParcel(&transactionParcel); SurfaceComposerClient::Transaction::createFromParcel(&transactionParcel); } void SurfaceComposerClientFuzzer::fuzzOnPullAtom() { std::string outData; bool success; SurfaceComposerClient::onPullAtom(mFdp.ConsumeIntegral(), &outData, &success); } void SurfaceComposerClientFuzzer::invokeSurfaceComposerClient() { String8 displayName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str()); sp displayToken = SurfaceComposerClient::createDisplay(displayName, mFdp.ConsumeBool() /*secure*/); SurfaceComposerClient::setDesiredDisplayModeSpecs(displayToken, getDisplayModeSpecs()); ui::ColorMode colorMode = mFdp.PickValueInArray(kColormodes); SurfaceComposerClient::setActiveColorMode(displayToken, colorMode); SurfaceComposerClient::setAutoLowLatencyMode(displayToken, mFdp.ConsumeBool() /*on*/); SurfaceComposerClient::setGameContentType(displayToken, mFdp.ConsumeBool() /*on*/); SurfaceComposerClient::setDisplayPowerMode(displayToken, mFdp.ConsumeIntegral()); SurfaceComposerClient::doUncacheBufferTransaction(mFdp.ConsumeIntegral()); SurfaceComposerClient::setDisplayBrightness(displayToken, getBrightness(&mFdp)); hardware::power::Boost boostId = mFdp.PickValueInArray(kBoost); SurfaceComposerClient::notifyPowerBoost((int32_t)boostId); String8 surfaceName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str()); sp handle(new BBinder()); sp producer; sp surfaceParent( new Surface(producer, mFdp.ConsumeBool() /*controlledByApp*/, handle)); fuzzOnPullAtom(); SurfaceComposerClient::setDisplayContentSamplingEnabled(displayToken, mFdp.ConsumeBool() /*enable*/, mFdp.ConsumeIntegral(), mFdp.ConsumeIntegral()); sp stopLayerHandle; sp listener = sp::make(); sp sampleListener = new gui::IRegionSamplingListenerDelegator(listener); SurfaceComposerClient::addRegionSamplingListener(getRect(&mFdp), stopLayerHandle, sampleListener); sp fpsListener; SurfaceComposerClient::addFpsListener(mFdp.ConsumeIntegral(), fpsListener); } void SurfaceComposerClientFuzzer::invokeSurfaceComposerClientBinder() { sp client(new FakeBnSurfaceComposerClient()); fuzzService(client.get(), std::move(mFdp)); } void SurfaceComposerClientFuzzer::process() { invokeSurfaceComposerClient(); invokeSurfaceComposerTransaction(); invokeSurfaceComposerClientBinder(); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { SurfaceComposerClientFuzzer surfaceComposerClientFuzzer(data, size); surfaceComposerClientFuzzer.process(); return 0; }