1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "nativewindow_fuzzer.h"
17 
18 #include <securec.h>
19 #include <vector>
20 #include <string>
21 
22 #include "ipc_inner_object.h"
23 #include "ipc_cparcel.h"
24 #include "data_generate.h"
25 #include "surface.h"
26 #include "surface_buffer.h"
27 #include "surface_buffer_impl.h"
28 #include "ibuffer_producer.h"
29 #include "iconsumer_surface.h"
30 #include "native_window.h"
31 
32 using namespace g_fuzzCommon;
33 namespace OHOS {
34     namespace {
35         constexpr uint32_t MATRIX_SIZE = 16;
36         constexpr size_t STR_LEN = 10;
37         constexpr int DEFAULT_FENCE = 100;
38         const uint8_t* g_data = nullptr;
39         size_t g_size = 0;
40         size_t g_pos;
41     }
42 
HandleOpt(OHNativeWindow * nativeWindow)43     void HandleOpt(OHNativeWindow *nativeWindow)
44     {
45         int code = SET_USAGE;
46         uint64_t usage = GetData<uint64_t>();
47         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, usage);
48         code = SET_BUFFER_GEOMETRY;
49         int32_t height = GetData<int32_t>();
50         int32_t width = GetData<int32_t>();
51         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, height, width);
52         code = SET_FORMAT;
53         int32_t format = GetData<int32_t>();
54         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, format);
55         code = SET_STRIDE;
56         int32_t stride = GetData<int32_t>();
57         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride);
58         code = GET_USAGE;
59         uint64_t usageGet = BUFFER_USAGE_CPU_WRITE;
60         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, &usageGet);
61         code = GET_BUFFER_GEOMETRY;
62         int32_t heightGet = 0;
63         int32_t widthGet = 0;
64         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, &heightGet, &widthGet);
65         code = GET_FORMAT;
66         int32_t formatGet = GRAPHIC_PIXEL_FMT_CLUT8;
67         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, &formatGet);
68         code = SET_STRIDE;
69         int32_t strideSet = 0x8;
70         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, strideSet);
71         code = GET_STRIDE;
72         int32_t strideGet = 0;
73         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, &strideGet);
74         code = SET_TIMEOUT;
75         int32_t timeoutSet = GetData<int32_t>();
76         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, timeoutSet);
77         code = SET_COLOR_GAMUT;
78         int32_t colorGamutSet = GetData<int32_t>();
79         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, colorGamutSet);
80         code = SET_TRANSFORM;
81         int32_t transform = GetData<int32_t>();
82         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, transform);
83     }
84 
HandleOpt1(OHNativeWindow * nativeWindow)85     void HandleOpt1(OHNativeWindow *nativeWindow)
86     {
87         int code = SET_UI_TIMESTAMP;
88         uint64_t uiTimestamp = GetData<uint64_t>();
89         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, uiTimestamp);
90         code = SET_DESIRED_PRESENT_TIMESTAMP;
91         int64_t desiredPresentTimestamp = GetData<int64_t>();
92         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, desiredPresentTimestamp);
93         code = SET_SOURCE_TYPE;
94         OHSurfaceSource typeSet = GetData<OHSurfaceSource>();
95         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, typeSet);
96         code = GET_SOURCE_TYPE;
97         OHSurfaceSource typeGet = OHSurfaceSource::OH_SURFACE_SOURCE_DEFAULT;
98         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, &typeGet);
99         code = SET_APP_FRAMEWORK_TYPE;
100         const char* frameWorkTypeSet = GetData<const char*>();
101         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, frameWorkTypeSet);
102         code = GET_TIMEOUT;
103         int32_t timeoutGet = 0;
104         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, &timeoutGet);
105         code = GET_COLOR_GAMUT;
106         int32_t colorGamutGet = 0;
107         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, &colorGamutGet);
108         code = GET_TRANSFORM;
109         int32_t transformTmp = 0;
110         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, &transformTmp);
111         code = GET_BUFFERQUEUE_SIZE;
112         int32_t queueSize = 0;
113         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, &queueSize);
114         code = GET_APP_FRAMEWORK_TYPE;
115         const char* frameWorkTypeGet;
116         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, &frameWorkTypeGet);
117         code = SET_HDR_WHITE_POINT_BRIGHTNESS;
118         float brightness = GetData<float>();
119         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, brightness);
120         code = SET_SDR_WHITE_POINT_BRIGHTNESS;
121         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, brightness);
122     }
123 
NativeWindowFuzzTest(OHNativeWindow * nativeWindow,OHNativeWindowBuffer * nwBuffer)124     void NativeWindowFuzzTest(OHNativeWindow *nativeWindow, OHNativeWindowBuffer *nwBuffer)
125     {
126         // get data
127         int fenceFd = GetData<int>() % 32768; // maximum fd of linux is 32768
128         // fd 0,1,2 represent stdin, stdout and stderr respectively, they should not be closed.
129         if (fenceFd >= 0 && fenceFd <= 2) {
130             fenceFd = DEFAULT_FENCE;
131         }
132 
133         Region::Rect rect = GetData<Region::Rect>();
134         Region region = {.rects = &rect, .rectNumber = 1};
135         OHScalingMode scalingMode = GetData<OHScalingMode>();
136         OHScalingModeV2 scalingModeV2 = GetData<OHScalingModeV2>();
137         NativeWindowRequestBuffer(nativeWindow, &nwBuffer, &fenceFd);
138         NativeWindowFlushBuffer(nativeWindow, nwBuffer, fenceFd, region);
139         NativeWindowCancelBuffer(nativeWindow, nwBuffer);
140         GetBufferHandleFromNative(nwBuffer);
141         float matrix[MATRIX_SIZE] = {0};
142         for (size_t i = 0; i < MATRIX_SIZE; ++i) {
143             matrix[i] = GetData<float>();
144         }
145         GetLastFlushedBuffer(nativeWindow, &nwBuffer, &fenceFd, matrix);
146         GetLastFlushedBufferV2(nativeWindow, &nwBuffer, &fenceFd, matrix);
147         NativeWindowAttachBuffer(nativeWindow, nwBuffer);
148         NativeWindowDetachBuffer(nativeWindow, nwBuffer);
149         uint32_t sequence = GetData<uint32_t>();
150         NativeWindowSetScalingMode(nativeWindow, sequence, scalingMode);
151         NativeWindowSetScalingModeV2(nativeWindow, scalingModeV2);
152         OH_NativeBuffer_TransformType transform = GetData<OH_NativeBuffer_TransformType>();
153         NativeWindowSetTransformHint(nativeWindow, transform);
154         NativeWindowGetTransformHint(nativeWindow, &transform);
155     }
156 
NativeWindowFuzzTest1(OHNativeWindow * nativeWindow,OHNativeWindowBuffer * nwBuffer)157     void NativeWindowFuzzTest1(OHNativeWindow *nativeWindow, OHNativeWindowBuffer *nwBuffer)
158     {
159         uint64_t surfaceId = 0;
160         GetSurfaceId(nativeWindow, &surfaceId);
161         OHHDRMetaData metaData = GetData<OHHDRMetaData>();
162         OHHDRMetadataKey key = GetData<OHHDRMetadataKey>();
163         uint8_t metaData2[STR_LEN];
164         for (uint64_t i = 0; i < STR_LEN; i++) {
165             metaData2[i] = GetData<uint8_t>();
166         }
167         uint32_t reserveInts = GetData<uint32_t>() % 0x100000; // no more than 0x100000
168         int32_t width = GetData<int32_t>();
169         int32_t height = GetData<int32_t>();
170         NativeWindowSetRequestWidthAndHeight(nativeWindow, width, height);
171         NativeWindowGetDefaultWidthAndHeight(nativeWindow, &width, &height);
172         NativeWindowSetBufferHold(nativeWindow);
173         OHIPCParcel *parcel = OH_IPCParcel_Create();
174         NativeWindowWriteToParcel(nativeWindow, parcel);
175         NativeWindowReadFromParcel(parcel, &nativeWindow);
176         OH_IPCParcel_Destroy(parcel);
177         OHNativeWindow *nativeWindowTmp;
178         CreateNativeWindowFromSurfaceId(surfaceId, &nativeWindowTmp);
179         DestoryNativeWindow(nativeWindowTmp);
180         OH_NativeBuffer_ColorSpace space = GetData<OH_NativeBuffer_ColorSpace>();
181         OH_NativeWindow_SetColorSpace(nativeWindow, space);
182         OH_NativeWindow_GetColorSpace(nativeWindow, &space);
183         OH_NativeBuffer_MetadataKey metaKey = GetData<OH_NativeBuffer_MetadataKey>();
184         int32_t len = GetData<int32_t>();
185         uint8_t buff[len];
186         for (int i = 0; i < len; ++i) {
187             buff[i] = GetData<uint8_t>();
188         }
189         OH_NativeWindow_SetMetadataValue(nativeWindow, metaKey, len, buff);
190         uint8_t *checkMetaData;
191         OH_NativeWindow_GetMetadataValue(nativeWindow, metaKey, &len, &checkMetaData);
192         delete checkMetaData;
193         std::vector<OHHDRMetaData> metaDatas = {metaData};
194         uint32_t sequence = GetData<uint32_t>();
195         NativeWindowSetMetaData(nativeWindow, sequence, metaDatas.size(), metaDatas.data());
196         NativeWindowSetMetaDataSet(nativeWindow, sequence, key, STR_LEN, metaData2);
197         OHExtDataHandle *handle = reinterpret_cast<OHExtDataHandle *>(AllocExtDataHandle(reserveInts));
198         NativeWindowSetTunnelHandle(nativeWindow, reinterpret_cast<OHExtDataHandle *>(handle));
199         FreeExtDataHandle(reinterpret_cast<GraphicExtDataHandle *>(handle));
200         NativeWindowDisconnect(nativeWindow);
201         DestroyNativeWindowBuffer(nwBuffer);
202     }
203 
DoSomethingInterestingWithMyAPI(const uint8_t * data,size_t size)204     bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
205     {
206         if (data == nullptr) {
207             return false;
208         }
209 
210         // initialize
211         g_data = data;
212         g_size = size;
213         g_pos = 0;
214 
215         // test
216         sptr<OHOS::IConsumerSurface> cSurface = IConsumerSurface::Create();
217         sptr<IBufferConsumerListener> listener = new BufferConsumerListener();
218         cSurface->RegisterConsumerListener(listener);
219         sptr<OHOS::IBufferProducer> producer = cSurface->GetProducer();
220         sptr<OHOS::Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
221         cSurface->SetDefaultWidthAndHeight(0x100, 0x100); // width and height is 0x100
222         OHNativeWindow* nativeWindow = CreateNativeWindowFromSurface(&pSurface);
223         uint32_t seqNum = GetData<uint32_t>();
224         sptr<OHOS::SurfaceBuffer> sBuffer = new SurfaceBufferImpl(seqNum);
225         OHNativeWindowBuffer* nwBuffer = CreateNativeWindowBufferFromSurfaceBuffer(&sBuffer);
226         DestroyNativeWindowBuffer(nwBuffer);
227         nwBuffer = nullptr;
228         HandleOpt(nativeWindow);
229         HandleOpt1(nativeWindow);
230         NativeWindowFuzzTest(nativeWindow, nwBuffer);
231         NativeWindowFuzzTest1(nativeWindow, nwBuffer);
232         DestoryNativeWindow(nativeWindow);
233         return true;
234     }
235 } // namespace OHOS
236 
237 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)238 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
239 {
240     /* Run your code on data */
241     OHOS::DoSomethingInterestingWithMyAPI(data, size);
242     return 0;
243 }
244 
245