• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <android/hardware/power/Boost.h>
17 #include <fuzzbinder/libbinder_driver.h>
18 #include <gui/Surface.h>
19 #include <gui/SurfaceComposerClient.h>
20 #include <libgui_fuzzer_utils.h>
21 #include "android-base/stringprintf.h"
22 
23 using namespace android;
24 
25 constexpr int32_t kRandomStringMaxBytes = 256;
26 
27 constexpr ui::ColorMode kColormodes[] = {ui::ColorMode::NATIVE,
28                                          ui::ColorMode::STANDARD_BT601_625,
29                                          ui::ColorMode::STANDARD_BT601_625_UNADJUSTED,
30                                          ui::ColorMode::STANDARD_BT601_525,
31                                          ui::ColorMode::STANDARD_BT601_525_UNADJUSTED,
32                                          ui::ColorMode::STANDARD_BT709,
33                                          ui::ColorMode::DCI_P3,
34                                          ui::ColorMode::SRGB,
35                                          ui::ColorMode::ADOBE_RGB,
36                                          ui::ColorMode::DISPLAY_P3,
37                                          ui::ColorMode::BT2020,
38                                          ui::ColorMode::BT2100_PQ,
39                                          ui::ColorMode::BT2100_HLG,
40                                          ui::ColorMode::DISPLAY_BT2020};
41 
42 constexpr hardware::power::Boost kBoost[] = {
43         hardware::power::Boost::INTERACTION,   hardware::power::Boost::DISPLAY_UPDATE_IMMINENT,
44         hardware::power::Boost::ML_ACC,        hardware::power::Boost::AUDIO_LAUNCH,
45         hardware::power::Boost::CAMERA_LAUNCH, hardware::power::Boost::CAMERA_SHOT,
46 };
47 
48 constexpr gui::TouchOcclusionMode kMode[] = {
49         gui::TouchOcclusionMode::BLOCK_UNTRUSTED,
50         gui::TouchOcclusionMode::USE_OPACITY,
51         gui::TouchOcclusionMode::ALLOW,
52 };
53 
54 constexpr gui::WindowInfo::Flag kFlags[] = {
55         gui::WindowInfo::Flag::ALLOW_LOCK_WHILE_SCREEN_ON,
56         gui::WindowInfo::Flag::DIM_BEHIND,
57         gui::WindowInfo::Flag::BLUR_BEHIND,
58         gui::WindowInfo::Flag::NOT_FOCUSABLE,
59         gui::WindowInfo::Flag::NOT_TOUCHABLE,
60         gui::WindowInfo::Flag::NOT_TOUCH_MODAL,
61         gui::WindowInfo::Flag::TOUCHABLE_WHEN_WAKING,
62         gui::WindowInfo::Flag::KEEP_SCREEN_ON,
63         gui::WindowInfo::Flag::LAYOUT_IN_SCREEN,
64         gui::WindowInfo::Flag::LAYOUT_NO_LIMITS,
65         gui::WindowInfo::Flag::FULLSCREEN,
66         gui::WindowInfo::Flag::FORCE_NOT_FULLSCREEN,
67         gui::WindowInfo::Flag::DITHER,
68         gui::WindowInfo::Flag::SECURE,
69         gui::WindowInfo::Flag::SCALED,
70         gui::WindowInfo::Flag::IGNORE_CHEEK_PRESSES,
71         gui::WindowInfo::Flag::LAYOUT_INSET_DECOR,
72         gui::WindowInfo::Flag::ALT_FOCUSABLE_IM,
73         gui::WindowInfo::Flag::WATCH_OUTSIDE_TOUCH,
74         gui::WindowInfo::Flag::SHOW_WHEN_LOCKED,
75         gui::WindowInfo::Flag::SHOW_WALLPAPER,
76         gui::WindowInfo::Flag::TURN_SCREEN_ON,
77         gui::WindowInfo::Flag::DISMISS_KEYGUARD,
78         gui::WindowInfo::Flag::SPLIT_TOUCH,
79         gui::WindowInfo::Flag::HARDWARE_ACCELERATED,
80         gui::WindowInfo::Flag::LAYOUT_IN_OVERSCAN,
81         gui::WindowInfo::Flag::TRANSLUCENT_STATUS,
82         gui::WindowInfo::Flag::TRANSLUCENT_NAVIGATION,
83         gui::WindowInfo::Flag::LOCAL_FOCUS_MODE,
84         gui::WindowInfo::Flag::SLIPPERY,
85         gui::WindowInfo::Flag::LAYOUT_ATTACHED_IN_DECOR,
86         gui::WindowInfo::Flag::DRAWS_SYSTEM_BAR_BACKGROUNDS,
87 };
88 
89 constexpr gui::WindowInfo::Type kType[] = {
90         gui::WindowInfo::Type::UNKNOWN,
91         gui::WindowInfo::Type::FIRST_APPLICATION_WINDOW,
92         gui::WindowInfo::Type::BASE_APPLICATION,
93         gui::WindowInfo::Type::APPLICATION,
94         gui::WindowInfo::Type::APPLICATION_STARTING,
95         gui::WindowInfo::Type::LAST_APPLICATION_WINDOW,
96         gui::WindowInfo::Type::FIRST_SUB_WINDOW,
97         gui::WindowInfo::Type::APPLICATION_PANEL,
98         gui::WindowInfo::Type::APPLICATION_MEDIA,
99         gui::WindowInfo::Type::APPLICATION_SUB_PANEL,
100         gui::WindowInfo::Type::APPLICATION_ATTACHED_DIALOG,
101         gui::WindowInfo::Type::APPLICATION_MEDIA_OVERLAY,
102 };
103 
104 constexpr gui::WindowInfo::InputConfig kFeatures[] = {
105         gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL,
106         gui::WindowInfo::InputConfig::DISABLE_USER_ACTIVITY,
107         gui::WindowInfo::InputConfig::DROP_INPUT,
108         gui::WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED,
109         gui::WindowInfo::InputConfig::SPY,
110         gui::WindowInfo::InputConfig::INTERCEPTS_STYLUS,
111 };
112 
113 class SurfaceComposerClientFuzzer {
114 public:
SurfaceComposerClientFuzzer(const uint8_t * data,size_t size)115     SurfaceComposerClientFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
116     void process();
117 
118 private:
119     void invokeSurfaceComposerClient();
120     void invokeSurfaceComposerClientBinder();
121     void invokeSurfaceComposerTransaction();
122     void getWindowInfo(gui::WindowInfo*);
123     sp<SurfaceControl> makeSurfaceControl();
124     BlurRegion getBlurRegion();
125     void fuzzOnPullAtom();
126     gui::DisplayModeSpecs getDisplayModeSpecs();
127 
128     FuzzedDataProvider mFdp;
129 };
130 
getDisplayModeSpecs()131 gui::DisplayModeSpecs SurfaceComposerClientFuzzer::getDisplayModeSpecs() {
132     const auto getRefreshRateRange = [&] {
133         gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange range;
134         range.min = mFdp.ConsumeFloatingPoint<float>();
135         range.max = mFdp.ConsumeFloatingPoint<float>();
136         return range;
137     };
138 
139     const auto getRefreshRateRanges = [&] {
140         gui::DisplayModeSpecs::RefreshRateRanges ranges;
141         ranges.physical = getRefreshRateRange();
142         ranges.render = getRefreshRateRange();
143         return ranges;
144     };
145 
146     String8 displayName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str());
147     sp<IBinder> displayToken =
148             SurfaceComposerClient::createDisplay(displayName, mFdp.ConsumeBool() /*secure*/);
149     gui::DisplayModeSpecs specs;
150     specs.defaultMode = mFdp.ConsumeIntegral<int32_t>();
151     specs.allowGroupSwitching = mFdp.ConsumeBool();
152     specs.primaryRanges = getRefreshRateRanges();
153     specs.appRequestRanges = getRefreshRateRanges();
154     return specs;
155 }
156 
getBlurRegion()157 BlurRegion SurfaceComposerClientFuzzer::getBlurRegion() {
158     int32_t left = mFdp.ConsumeIntegral<int32_t>();
159     int32_t right = mFdp.ConsumeIntegral<int32_t>();
160     int32_t top = mFdp.ConsumeIntegral<int32_t>();
161     int32_t bottom = mFdp.ConsumeIntegral<int32_t>();
162     uint32_t blurRadius = mFdp.ConsumeIntegral<uint32_t>();
163     float alpha = mFdp.ConsumeFloatingPoint<float>();
164     float cornerRadiusTL = mFdp.ConsumeFloatingPoint<float>();
165     float cornerRadiusTR = mFdp.ConsumeFloatingPoint<float>();
166     float cornerRadiusBL = mFdp.ConsumeFloatingPoint<float>();
167     float cornerRadiusBR = mFdp.ConsumeFloatingPoint<float>();
168     return BlurRegion{blurRadius,     cornerRadiusTL, cornerRadiusTR, cornerRadiusBL,
169                       cornerRadiusBR, alpha,          left,           top,
170                       right,          bottom};
171 }
172 
getWindowInfo(gui::WindowInfo * windowInfo)173 void SurfaceComposerClientFuzzer::getWindowInfo(gui::WindowInfo* windowInfo) {
174     windowInfo->id = mFdp.ConsumeIntegral<int32_t>();
175     windowInfo->name = mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes);
176     windowInfo->layoutParamsFlags = mFdp.PickValueInArray(kFlags);
177     windowInfo->layoutParamsType = mFdp.PickValueInArray(kType);
178     windowInfo->frameLeft = mFdp.ConsumeIntegral<int32_t>();
179     windowInfo->frameTop = mFdp.ConsumeIntegral<int32_t>();
180     windowInfo->frameRight = mFdp.ConsumeIntegral<int32_t>();
181     windowInfo->frameBottom = mFdp.ConsumeIntegral<int32_t>();
182     windowInfo->surfaceInset = mFdp.ConsumeIntegral<int32_t>();
183     windowInfo->alpha = mFdp.ConsumeFloatingPointInRange<float>(0, 1);
184     ui::Transform transform(mFdp.PickValueInArray(kOrientation));
185     windowInfo->transform = transform;
186     windowInfo->touchableRegion = Region(getRect(&mFdp));
187     windowInfo->replaceTouchableRegionWithCrop = mFdp.ConsumeBool();
188     windowInfo->touchOcclusionMode = mFdp.PickValueInArray(kMode);
189     windowInfo->ownerPid = gui::Pid{mFdp.ConsumeIntegral<pid_t>()};
190     windowInfo->ownerUid = gui::Uid{mFdp.ConsumeIntegral<uid_t>()};
191     windowInfo->packageName = mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes);
192     windowInfo->inputConfig = mFdp.PickValueInArray(kFeatures);
193 }
194 
makeSurfaceControl()195 sp<SurfaceControl> SurfaceComposerClientFuzzer::makeSurfaceControl() {
196     sp<IBinder> handle;
197     const sp<FakeBnSurfaceComposerClient> testClient(new FakeBnSurfaceComposerClient());
198     sp<SurfaceComposerClient> client = new SurfaceComposerClient(testClient);
199     sp<BnGraphicBufferProducer> producer;
200     uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
201     uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
202     uint32_t transformHint = mFdp.ConsumeIntegral<uint32_t>();
203     uint32_t flags = mFdp.ConsumeIntegral<uint32_t>();
204     int32_t format = mFdp.ConsumeIntegral<int32_t>();
205     int32_t layerId = mFdp.ConsumeIntegral<int32_t>();
206     std::string layerName = base::StringPrintf("#%d", layerId);
207     return new SurfaceControl(client, handle, layerId, layerName, width, height, format,
208                               transformHint, flags);
209 }
210 
invokeSurfaceComposerTransaction()211 void SurfaceComposerClientFuzzer::invokeSurfaceComposerTransaction() {
212     sp<SurfaceControl> surface = makeSurfaceControl();
213 
214     SurfaceComposerClient::Transaction transaction;
215     int32_t layer = mFdp.ConsumeIntegral<int32_t>();
216     transaction.setLayer(surface, layer);
217 
218     sp<SurfaceControl> relativeSurface = makeSurfaceControl();
219     transaction.setRelativeLayer(surface, relativeSurface, layer);
220 
221     Region transparentRegion(getRect(&mFdp));
222     transaction.setTransparentRegionHint(surface, transparentRegion);
223     transaction.setAlpha(surface, mFdp.ConsumeFloatingPoint<float>());
224 
225     transaction.setCornerRadius(surface, mFdp.ConsumeFloatingPoint<float>());
226     transaction.setBackgroundBlurRadius(surface, mFdp.ConsumeFloatingPoint<float>());
227     std::vector<BlurRegion> regions;
228     uint32_t vectorSize = mFdp.ConsumeIntegralInRange<uint32_t>(0, 100);
229     regions.resize(vectorSize);
230     for (size_t idx = 0; idx < vectorSize; ++idx) {
231         regions.push_back(getBlurRegion());
232     }
233     transaction.setBlurRegions(surface, regions);
234 
235     transaction.setLayerStack(surface, {mFdp.ConsumeIntegral<uint32_t>()});
236     half3 color = {mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
237                    mFdp.ConsumeIntegral<uint32_t>()};
238     transaction.setColor(surface, color);
239     transaction.setBackgroundColor(surface, color, mFdp.ConsumeFloatingPoint<float>(),
240                                    mFdp.PickValueInArray(kDataspaces));
241 
242     transaction.setApi(surface, mFdp.ConsumeIntegral<int32_t>());
243     transaction.setFrameRateSelectionPriority(surface, mFdp.ConsumeIntegral<int32_t>());
244     transaction.setColorSpaceAgnostic(surface, mFdp.ConsumeBool() /*agnostic*/);
245 
246     gui::WindowInfo windowInfo;
247     getWindowInfo(&windowInfo);
248     transaction.setInputWindowInfo(surface, windowInfo);
249     Parcel windowParcel;
250     windowInfo.writeToParcel(&windowParcel);
251     windowParcel.setDataPosition(0);
252     windowInfo.readFromParcel(&windowParcel);
253 
254     windowInfo.addTouchableRegion(getRect(&mFdp));
255     int32_t pointX = mFdp.ConsumeIntegral<int32_t>();
256     int32_t pointY = mFdp.ConsumeIntegral<int32_t>();
257     windowInfo.touchableRegionContainsPoint(pointX, pointY);
258     windowInfo.frameContainsPoint(pointX, pointY);
259 
260     Parcel transactionParcel;
261     transaction.writeToParcel(&transactionParcel);
262     transactionParcel.setDataPosition(0);
263     transaction.readFromParcel(&transactionParcel);
264     SurfaceComposerClient::Transaction::createFromParcel(&transactionParcel);
265 }
266 
fuzzOnPullAtom()267 void SurfaceComposerClientFuzzer::fuzzOnPullAtom() {
268     std::string outData;
269     bool success;
270     SurfaceComposerClient::onPullAtom(mFdp.ConsumeIntegral<int32_t>(), &outData, &success);
271 }
272 
invokeSurfaceComposerClient()273 void SurfaceComposerClientFuzzer::invokeSurfaceComposerClient() {
274     String8 displayName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str());
275     sp<IBinder> displayToken =
276             SurfaceComposerClient::createDisplay(displayName, mFdp.ConsumeBool() /*secure*/);
277     SurfaceComposerClient::setDesiredDisplayModeSpecs(displayToken, getDisplayModeSpecs());
278 
279     ui::ColorMode colorMode = mFdp.PickValueInArray(kColormodes);
280     SurfaceComposerClient::setActiveColorMode(displayToken, colorMode);
281     SurfaceComposerClient::setAutoLowLatencyMode(displayToken, mFdp.ConsumeBool() /*on*/);
282     SurfaceComposerClient::setGameContentType(displayToken, mFdp.ConsumeBool() /*on*/);
283     SurfaceComposerClient::setDisplayPowerMode(displayToken, mFdp.ConsumeIntegral<int32_t>());
284     SurfaceComposerClient::doUncacheBufferTransaction(mFdp.ConsumeIntegral<uint64_t>());
285 
286     SurfaceComposerClient::setDisplayBrightness(displayToken, getBrightness(&mFdp));
287     hardware::power::Boost boostId = mFdp.PickValueInArray(kBoost);
288     SurfaceComposerClient::notifyPowerBoost((int32_t)boostId);
289 
290     String8 surfaceName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str());
291     sp<BBinder> handle(new BBinder());
292     sp<BnGraphicBufferProducer> producer;
293     sp<Surface> surfaceParent(
294             new Surface(producer, mFdp.ConsumeBool() /*controlledByApp*/, handle));
295 
296     fuzzOnPullAtom();
297     SurfaceComposerClient::setDisplayContentSamplingEnabled(displayToken,
298                                                             mFdp.ConsumeBool() /*enable*/,
299                                                             mFdp.ConsumeIntegral<uint8_t>(),
300                                                             mFdp.ConsumeIntegral<uint64_t>());
301 
302     sp<IBinder> stopLayerHandle;
303     sp<gui::IRegionSamplingListener> listener = sp<gui::IRegionSamplingListenerDefault>::make();
304     sp<gui::IRegionSamplingListenerDelegator> sampleListener =
305             new gui::IRegionSamplingListenerDelegator(listener);
306     SurfaceComposerClient::addRegionSamplingListener(getRect(&mFdp), stopLayerHandle,
307                                                      sampleListener);
308     sp<gui::IFpsListenerDefault> fpsListener;
309     SurfaceComposerClient::addFpsListener(mFdp.ConsumeIntegral<int32_t>(), fpsListener);
310 }
311 
invokeSurfaceComposerClientBinder()312 void SurfaceComposerClientFuzzer::invokeSurfaceComposerClientBinder() {
313     sp<FakeBnSurfaceComposerClient> client(new FakeBnSurfaceComposerClient());
314     fuzzService(client.get(), std::move(mFdp));
315 }
316 
process()317 void SurfaceComposerClientFuzzer::process() {
318     invokeSurfaceComposerClient();
319     invokeSurfaceComposerTransaction();
320     invokeSurfaceComposerClientBinder();
321 }
322 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)323 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
324     SurfaceComposerClientFuzzer surfaceComposerClientFuzzer(data, size);
325     surfaceComposerClientFuzzer.process();
326     return 0;
327 }
328