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 "surfacebuffer_fuzzer.h"
17
18 #include <securec.h>
19
20 #include "surface_buffer.h"
21 #include "surface_buffer_impl.h"
22 #include "buffer_extra_data.h"
23 #include "buffer_extra_data_impl.h"
24 #include <message_parcel.h>
25 #include <iostream>
26
27 namespace OHOS {
28 namespace {
29 const uint8_t* g_data = nullptr;
30 size_t g_size = 0;
31 size_t g_pos;
32 constexpr size_t STR_LEN = 10;
33 }
34
35 /*
36 * describe: get data from outside untrusted data(g_data) which size is according to sizeof(T)
37 * tips: only support basic type
38 */
39 template<class T>
GetData()40 T GetData()
41 {
42 T object {};
43 size_t objectSize = sizeof(object);
44 if (g_data == nullptr || objectSize > g_size - g_pos) {
45 return object;
46 }
47 errno_t ret = memcpy_s(&object, objectSize, g_data + g_pos, objectSize);
48 if (ret != EOK) {
49 return {};
50 }
51 g_pos += objectSize;
52 return object;
53 }
54
55 /*
56 * get a string from g_data
57 */
GetStringFromData(int strlen)58 std::string GetStringFromData(int strlen)
59 {
60 char cstr[strlen];
61 cstr[strlen - 1] = '\0';
62 for (int i = 0; i < strlen - 1; i++) {
63 char tmp = GetData<char>();
64 if (tmp == '\0') {
65 tmp = '1';
66 }
67 cstr[i] = tmp;
68 }
69 std::string str(cstr);
70 return str;
71 }
72
DoSomethingInterestingWithMyAPI(const uint8_t * data,size_t size)73 bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
74 {
75 if (data == nullptr) {
76 return false;
77 }
78
79 // initialize
80 g_data = data;
81 g_size = size;
82 g_pos = 0;
83
84 // get data
85 uint32_t seqNum = GetData<uint32_t>();
86 GraphicColorGamut colorGamut = GetData<GraphicColorGamut>();
87 GraphicTransformType transform = GetData<GraphicTransformType>();
88 int32_t width = GetData<int32_t>();
89 int32_t height = GetData<int32_t>();
90 BufferRequestConfig config = GetData<BufferRequestConfig>();
91 std::string keyInt32 = GetStringFromData(STR_LEN);
92 int32_t valueInt32 = GetData<int32_t>();
93 std::string keyInt64 = GetStringFromData(STR_LEN);
94 int64_t valueInt64 = GetData<int64_t>();
95 std::string keyDouble = GetStringFromData(STR_LEN);
96 double valueDouble = GetData<double>();
97 std::string keyStr = GetStringFromData(STR_LEN);
98 std::string valueStr = GetStringFromData(STR_LEN);
99
100 // test
101 sptr<SurfaceBuffer> surfaceBuffer = new SurfaceBufferImpl(seqNum);
102 surfaceBuffer->SetSurfaceBufferColorGamut(colorGamut);
103 surfaceBuffer->SetSurfaceBufferTransform(transform);
104 surfaceBuffer->SetSurfaceBufferWidth(width);
105 surfaceBuffer->SetSurfaceBufferHeight(height);
106 surfaceBuffer->Alloc(config);
107 sptr<BufferExtraData> bedata = new BufferExtraDataImpl();
108 bedata->ExtraSet(keyInt32, valueInt32);
109 bedata->ExtraSet(keyInt64, valueInt64);
110 bedata->ExtraSet(keyDouble, valueDouble);
111 bedata->ExtraSet(keyStr, valueStr);
112 surfaceBuffer->SetExtraData(bedata);
113 MessageParcel parcel;
114 surfaceBuffer->WriteToMessageParcel(parcel);
115 surfaceBuffer->ReadFromMessageParcel(parcel);
116
117 return true;
118 }
119 }
120
121 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)122 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
123 {
124 /* Run your code on data */
125 OHOS::DoSomethingInterestingWithMyAPI(data, size);
126 return 0;
127 }
128
129