blob: ef9663a8d64005973dd2802635f2ab872545d07c [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>
18#include <string>
19#include <vector>
20
21#include <linux/input-event-codes.h>
22
23#include <FuzzContainer.h>
24#include <MapperHelpers.h>
25#include <TouchpadInputMapper.h>
26
27namespace android {
28
29namespace {
30
31void setAxisInfo(ThreadSafeFuzzedDataProvider& fdp, FuzzContainer& fuzzer, int axis) {
32 if (fdp.ConsumeBool()) {
33 fuzzer.setAbsoluteAxisInfo(axis,
34 RawAbsoluteAxisInfo{
35 .valid = fdp.ConsumeBool(),
36 .minValue = fdp.ConsumeIntegral<int32_t>(),
37 .maxValue = fdp.ConsumeIntegral<int32_t>(),
38 .flat = fdp.ConsumeIntegral<int32_t>(),
39 .fuzz = fdp.ConsumeIntegral<int32_t>(),
40 .resolution = fdp.ConsumeIntegral<int32_t>(),
41 });
42 }
43}
44
45void setAxisInfos(ThreadSafeFuzzedDataProvider& fdp, FuzzContainer& fuzzer) {
46 setAxisInfo(fdp, fuzzer, ABS_MT_SLOT);
47 setAxisInfo(fdp, fuzzer, ABS_MT_POSITION_X);
48 setAxisInfo(fdp, fuzzer, ABS_MT_POSITION_Y);
49 setAxisInfo(fdp, fuzzer, ABS_MT_PRESSURE);
50 setAxisInfo(fdp, fuzzer, ABS_MT_ORIENTATION);
51 setAxisInfo(fdp, fuzzer, ABS_MT_TOUCH_MAJOR);
52 setAxisInfo(fdp, fuzzer, ABS_MT_TOUCH_MINOR);
53 setAxisInfo(fdp, fuzzer, ABS_MT_WIDTH_MAJOR);
54 setAxisInfo(fdp, fuzzer, ABS_MT_WIDTH_MINOR);
55}
56
57const std::vector<std::string> boolPropertiesToFuzz = {
58 "gestureProp.Compute_Surface_Area_from_Pressure",
59 "gestureProp.Drumroll_Suppression_Enable",
60 "gestureProp.Fling_Buffer_Suppress_Zero_Length_Scrolls",
61 "gestureProp.Stationary_Wiggle_Filter_Enabled",
62};
63const std::vector<std::string> doublePropertiesToFuzz = {
64 "gestureProp.Fake_Timestamp_Delta",
65 "gestureProp.Finger_Moving_Energy",
66 "gestureProp.Finger_Moving_Hysteresis",
67 "gestureProp.IIR_a1",
68 "gestureProp.IIR_a2",
69 "gestureProp.IIR_b0",
70 "gestureProp.IIR_b1",
71 "gestureProp.IIR_b2",
72 "gestureProp.IIR_b3",
73 "gestureProp.Max_Allowed_Pressure_Change_Per_Sec",
74 "gestureProp.Max_Hysteresis_Pressure_Per_Sec",
75 "gestureProp.Max_Stationary_Move_Speed",
76 "gestureProp.Max_Stationary_Move_Speed_Hysteresis",
77 "gestureProp.Max_Stationary_Move_Suppress_Distance",
78 "gestureProp.Multiple_Palm_Width",
79 "gestureProp.Palm_Edge_Zone_Width",
80 "gestureProp.Palm_Eval_Timeout",
81 "gestureProp.Palm_Pressure",
82 "gestureProp.Palm_Width",
83 "gestureProp.Pressure_Calibration_Offset",
84 "gestureProp.Pressure_Calibration_Slope",
85 "gestureProp.Tap_Exclusion_Border_Width",
86 "gestureProp.Touchpad_Device_Output_Bias_on_X-Axis",
87 "gestureProp.Touchpad_Device_Output_Bias_on_Y-Axis",
88 "gestureProp.Two_Finger_Vertical_Close_Distance_Thresh",
89};
90
91void setDeviceSpecificConfig(ThreadSafeFuzzedDataProvider& fdp, FuzzContainer& fuzzer) {
92 // There are a great many gesture properties offered by the Gestures library, all of which could
93 // potentially be set in Input Device Configuration files. Maintaining a complete list is
94 // impractical, so instead we only fuzz properties which are used in at least one IDC file, or
95 // which are likely to be used in future (e.g. ones for controlling palm rejection).
96
97 if (fdp.ConsumeBool()) {
98 fuzzer.addProperty("gestureProp.Touchpad_Stack_Version",
99 std::to_string(fdp.ConsumeIntegral<int>()));
100 }
101
102 for (auto& propertyName : boolPropertiesToFuzz) {
103 if (fdp.ConsumeBool()) {
104 fuzzer.addProperty(propertyName, fdp.ConsumeBool() ? "1" : "0");
105 }
106 }
107
108 for (auto& propertyName : doublePropertiesToFuzz) {
109 if (fdp.ConsumeBool()) {
110 fuzzer.addProperty(propertyName, std::to_string(fdp.ConsumeFloatingPoint<double>()));
111 }
112 }
113
114 if (fdp.ConsumeBool()) {
115 fuzzer.addProperty("gestureProp." + fdp.ConsumeRandomLengthString(),
116 std::to_string(fdp.ConsumeIntegral<int>()));
117 }
118}
119
120void setTouchpadSettings(ThreadSafeFuzzedDataProvider& fdp, InputReaderConfiguration& config) {
121 config.touchpadPointerSpeed = fdp.ConsumeIntegralInRange(-7, 7);
122 config.touchpadNaturalScrollingEnabled = fdp.ConsumeBool();
123 config.touchpadTapToClickEnabled = fdp.ConsumeBool();
124 config.touchpadRightClickZoneEnabled = fdp.ConsumeBool();
125}
126
127} // namespace
128
129extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
130 std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp =
131 std::make_shared<ThreadSafeFuzzedDataProvider>(data, size);
132 FuzzContainer fuzzer(fdp);
133 setAxisInfos(*fdp, fuzzer);
134 setDeviceSpecificConfig(*fdp, fuzzer);
135
136 auto policyConfig = fuzzer.getPolicyConfig();
137 // Some settings are fuzzed here, as well as in the main loop, to provide randomized data to the
138 // TouchpadInputMapper constructor.
139 setTouchpadSettings(*fdp, policyConfig);
140 policyConfig.pointerCaptureRequest.enable = fdp->ConsumeBool();
141 TouchpadInputMapper& mapper = fuzzer.getMapper<TouchpadInputMapper>(policyConfig);
142
143 // Loop through mapper operations until randomness is exhausted.
144 while (fdp->remaining_bytes() > 0) {
145 fdp->PickValueInArray<std::function<void()>>({
146 [&]() -> void {
147 std::string dump;
148 mapper.dump(dump);
149 },
150 [&]() -> void {
151 InputDeviceInfo info;
152 mapper.populateDeviceInfo(info);
153 },
154 [&]() -> void { mapper.getSources(); },
155 [&]() -> void {
156 setTouchpadSettings(*fdp, policyConfig);
157 policyConfig.pointerCaptureRequest.enable = fdp->ConsumeBool();
158 std::list<NotifyArgs> unused =
159 mapper.reconfigure(fdp->ConsumeIntegral<nsecs_t>(), policyConfig,
160 InputReaderConfiguration::Change(
161 fdp->ConsumeIntegral<uint32_t>()));
162 },
163 [&]() -> void {
164 std::list<NotifyArgs> unused = mapper.reset(fdp->ConsumeIntegral<nsecs_t>());
165 },
166 [&]() -> void {
167 RawEvent event = getFuzzedRawEvent(*fdp);
168 std::list<NotifyArgs> unused = mapper.process(&event);
169 },
170 })();
171 }
172
173 return 0;
174}
175
176} // namespace android