blob: c620032eef4a3aba7cc645fef3b06642a0a0526c [file] [log] [blame]
Harry Cuttsccb75e82023-06-23 14:08:06 +00001/*
2 * Copyright 2023 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
17#include <limits>
Harry Cuttsf61c0472023-07-10 14:45:15 +000018#include <memory>
Harry Cuttsccb75e82023-06-23 14:08:06 +000019#include <string>
20#include <vector>
21
22#include <linux/input-event-codes.h>
23
Harry Cuttsf61c0472023-07-10 14:45:15 +000024#include <InputDevice.h>
Harry Cuttse36d8352023-07-10 13:28:45 +000025#include <InputReaderBase.h>
Harry Cuttsccb75e82023-06-23 14:08:06 +000026#include <MapperHelpers.h>
27#include <TouchpadInputMapper.h>
28
29namespace android {
30
31namespace {
32
Harry Cuttsf61c0472023-07-10 14:45:15 +000033void setAxisInfo(ThreadSafeFuzzedDataProvider& fdp, FuzzEventHub& eventHub, int32_t id, int axis) {
Harry Cuttsccb75e82023-06-23 14:08:06 +000034 if (fdp.ConsumeBool()) {
Harry Cuttsf61c0472023-07-10 14:45:15 +000035 eventHub.setAbsoluteAxisInfo(id, axis,
36 RawAbsoluteAxisInfo{
37 .valid = fdp.ConsumeBool(),
38 .minValue = fdp.ConsumeIntegral<int32_t>(),
39 .maxValue = fdp.ConsumeIntegral<int32_t>(),
40 .flat = fdp.ConsumeIntegral<int32_t>(),
41 .fuzz = fdp.ConsumeIntegral<int32_t>(),
42 .resolution = fdp.ConsumeIntegral<int32_t>(),
43 });
Harry Cuttsccb75e82023-06-23 14:08:06 +000044 }
45}
46
Harry Cuttsf61c0472023-07-10 14:45:15 +000047void setAxisInfos(ThreadSafeFuzzedDataProvider& fdp, FuzzEventHub& eventHub, int32_t id) {
48 setAxisInfo(fdp, eventHub, id, ABS_MT_SLOT);
49 setAxisInfo(fdp, eventHub, id, ABS_MT_POSITION_X);
50 setAxisInfo(fdp, eventHub, id, ABS_MT_POSITION_Y);
51 setAxisInfo(fdp, eventHub, id, ABS_MT_PRESSURE);
52 setAxisInfo(fdp, eventHub, id, ABS_MT_ORIENTATION);
53 setAxisInfo(fdp, eventHub, id, ABS_MT_TOUCH_MAJOR);
54 setAxisInfo(fdp, eventHub, id, ABS_MT_TOUCH_MINOR);
55 setAxisInfo(fdp, eventHub, id, ABS_MT_WIDTH_MAJOR);
56 setAxisInfo(fdp, eventHub, id, ABS_MT_WIDTH_MINOR);
Harry Cuttsccb75e82023-06-23 14:08:06 +000057}
58
59const std::vector<std::string> boolPropertiesToFuzz = {
60 "gestureProp.Compute_Surface_Area_from_Pressure",
61 "gestureProp.Drumroll_Suppression_Enable",
62 "gestureProp.Fling_Buffer_Suppress_Zero_Length_Scrolls",
63 "gestureProp.Stationary_Wiggle_Filter_Enabled",
64};
65const std::vector<std::string> doublePropertiesToFuzz = {
66 "gestureProp.Fake_Timestamp_Delta",
67 "gestureProp.Finger_Moving_Energy",
68 "gestureProp.Finger_Moving_Hysteresis",
69 "gestureProp.IIR_a1",
70 "gestureProp.IIR_a2",
71 "gestureProp.IIR_b0",
72 "gestureProp.IIR_b1",
73 "gestureProp.IIR_b2",
74 "gestureProp.IIR_b3",
75 "gestureProp.Max_Allowed_Pressure_Change_Per_Sec",
76 "gestureProp.Max_Hysteresis_Pressure_Per_Sec",
77 "gestureProp.Max_Stationary_Move_Speed",
78 "gestureProp.Max_Stationary_Move_Speed_Hysteresis",
79 "gestureProp.Max_Stationary_Move_Suppress_Distance",
80 "gestureProp.Multiple_Palm_Width",
81 "gestureProp.Palm_Edge_Zone_Width",
82 "gestureProp.Palm_Eval_Timeout",
83 "gestureProp.Palm_Pressure",
84 "gestureProp.Palm_Width",
85 "gestureProp.Pressure_Calibration_Offset",
86 "gestureProp.Pressure_Calibration_Slope",
87 "gestureProp.Tap_Exclusion_Border_Width",
88 "gestureProp.Touchpad_Device_Output_Bias_on_X-Axis",
89 "gestureProp.Touchpad_Device_Output_Bias_on_Y-Axis",
90 "gestureProp.Two_Finger_Vertical_Close_Distance_Thresh",
91};
92
Harry Cuttsf61c0472023-07-10 14:45:15 +000093void setDeviceSpecificConfig(ThreadSafeFuzzedDataProvider& fdp, FuzzEventHub& eventHub) {
Harry Cuttsccb75e82023-06-23 14:08:06 +000094 // There are a great many gesture properties offered by the Gestures library, all of which could
95 // potentially be set in Input Device Configuration files. Maintaining a complete list is
96 // impractical, so instead we only fuzz properties which are used in at least one IDC file, or
97 // which are likely to be used in future (e.g. ones for controlling palm rejection).
98
99 if (fdp.ConsumeBool()) {
Harry Cuttsf61c0472023-07-10 14:45:15 +0000100 eventHub.addProperty("gestureProp.Touchpad_Stack_Version",
101 std::to_string(fdp.ConsumeIntegral<int>()));
Harry Cuttsccb75e82023-06-23 14:08:06 +0000102 }
103
104 for (auto& propertyName : boolPropertiesToFuzz) {
105 if (fdp.ConsumeBool()) {
Harry Cuttsf61c0472023-07-10 14:45:15 +0000106 eventHub.addProperty(propertyName, fdp.ConsumeBool() ? "1" : "0");
Harry Cuttsccb75e82023-06-23 14:08:06 +0000107 }
108 }
109
110 for (auto& propertyName : doublePropertiesToFuzz) {
111 if (fdp.ConsumeBool()) {
Harry Cuttsf61c0472023-07-10 14:45:15 +0000112 eventHub.addProperty(propertyName, std::to_string(fdp.ConsumeFloatingPoint<double>()));
Harry Cuttsccb75e82023-06-23 14:08:06 +0000113 }
114 }
115
116 if (fdp.ConsumeBool()) {
Harry Cuttsf61c0472023-07-10 14:45:15 +0000117 eventHub.addProperty("gestureProp." + fdp.ConsumeRandomLengthString(),
118 std::to_string(fdp.ConsumeIntegral<int>()));
Harry Cuttsccb75e82023-06-23 14:08:06 +0000119 }
120}
121
122void setTouchpadSettings(ThreadSafeFuzzedDataProvider& fdp, InputReaderConfiguration& config) {
123 config.touchpadPointerSpeed = fdp.ConsumeIntegralInRange(-7, 7);
124 config.touchpadNaturalScrollingEnabled = fdp.ConsumeBool();
125 config.touchpadTapToClickEnabled = fdp.ConsumeBool();
Harry Cuttse0e799d2024-01-24 16:27:56 +0000126 config.touchpadTapDraggingEnabled = fdp.ConsumeBool();
Harry Cuttsccb75e82023-06-23 14:08:06 +0000127 config.touchpadRightClickZoneEnabled = fdp.ConsumeBool();
Hiroki Sato25040232024-02-22 17:21:22 +0900128
129 config.pointerCaptureRequest.window = fdp.ConsumeBool() ? sp<BBinder>::make() : nullptr;
130 config.pointerCaptureRequest.seq = fdp.ConsumeIntegral<uint32_t>();
Harry Cuttsccb75e82023-06-23 14:08:06 +0000131}
132
133} // namespace
134
135extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
136 std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp =
137 std::make_shared<ThreadSafeFuzzedDataProvider>(data, size);
Harry Cuttsf61c0472023-07-10 14:45:15 +0000138
139 // Create mocked objects to support the fuzzed input mapper.
140 std::shared_ptr<FuzzEventHub> eventHub = std::make_shared<FuzzEventHub>(fdp);
141 FuzzInputReaderContext context(eventHub, fdp);
142 InputDevice device = getFuzzedInputDevice(*fdp, &context);
143
144 setAxisInfos(*fdp, *eventHub.get(), device.getId());
145 setDeviceSpecificConfig(*fdp, *eventHub.get());
Harry Cuttsccb75e82023-06-23 14:08:06 +0000146
Harry Cuttse36d8352023-07-10 13:28:45 +0000147 InputReaderConfiguration policyConfig;
Harry Cuttsccb75e82023-06-23 14:08:06 +0000148 // Some settings are fuzzed here, as well as in the main loop, to provide randomized data to the
149 // TouchpadInputMapper constructor.
150 setTouchpadSettings(*fdp, policyConfig);
Harry Cuttsf61c0472023-07-10 14:45:15 +0000151 TouchpadInputMapper& mapper =
152 getMapperForDevice<ThreadSafeFuzzedDataProvider, TouchpadInputMapper>(*fdp, device,
153 policyConfig);
Harry Cuttsccb75e82023-06-23 14:08:06 +0000154
155 // Loop through mapper operations until randomness is exhausted.
156 while (fdp->remaining_bytes() > 0) {
157 fdp->PickValueInArray<std::function<void()>>({
158 [&]() -> void {
159 std::string dump;
160 mapper.dump(dump);
161 },
162 [&]() -> void {
163 InputDeviceInfo info;
164 mapper.populateDeviceInfo(info);
165 },
166 [&]() -> void { mapper.getSources(); },
167 [&]() -> void {
168 setTouchpadSettings(*fdp, policyConfig);
Harry Cuttsccb75e82023-06-23 14:08:06 +0000169 std::list<NotifyArgs> unused =
170 mapper.reconfigure(fdp->ConsumeIntegral<nsecs_t>(), policyConfig,
171 InputReaderConfiguration::Change(
172 fdp->ConsumeIntegral<uint32_t>()));
173 },
174 [&]() -> void {
175 std::list<NotifyArgs> unused = mapper.reset(fdp->ConsumeIntegral<nsecs_t>());
176 },
177 [&]() -> void {
178 RawEvent event = getFuzzedRawEvent(*fdp);
Harry Cuttsa32a1192024-06-04 15:10:31 +0000179 std::list<NotifyArgs> unused = mapper.process(event);
Harry Cuttsccb75e82023-06-23 14:08:06 +0000180 },
181 })();
182 }
183
184 return 0;
185}
186
187} // namespace android