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