1 /*
2  * Copyright (c) 2024 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 "servicereverse_fuzzer.h"
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <cstring>
21 
22 #include <climits>
23 #include "message_parcel.h"
24 #include "b_session_backup.h"
25 #include "b_session_restore.h"
26 #include "b_incremental_backup_session.h"
27 #include "b_incremental_restore_session.h"
28 #include "i_service_reverse_ipc_interface_code.h"
29 #include "service_reverse_stub.h"
30 #include "service_reverse.h"
31 #include "securec.h"
32 #include "system_ability.h"
33 
34 using namespace OHOS::FileManagement::Backup;
35 
36 namespace OHOS {
37 constexpr size_t FOO_MAX_LEN = 1024;
38 constexpr size_t U32_AT_SIZE = 4;
39 constexpr uint8_t MAX_CALL_TRANSACTION = 24;
40 constexpr int32_t SHIFT_FIRST = 24;
41 constexpr int32_t SHIFT_SECOND = 16;
42 constexpr int32_t SHIFT_THIRD = 8;
43 constexpr int32_t ZERO_NUM = 0;
44 constexpr int32_t FIRST_NUM = 1;
45 constexpr int32_t SECOND_NUM = 2;
46 constexpr int32_t THIRD_NUM = 3;
47 
ConvertToUint32(const uint8_t * ptr)48 uint32_t ConvertToUint32(const uint8_t* ptr)
49 {
50     if (ptr == nullptr) {
51         return 0;
52     }
53     return (ptr[ZERO_NUM] << SHIFT_FIRST) | (ptr[FIRST_NUM] << SHIFT_SECOND) |
54         (ptr[SECOND_NUM] << SHIFT_THIRD) | (ptr[THIRD_NUM]);
55 }
56 
BackupFuzzTest(const uint8_t * data,size_t size)57 bool BackupFuzzTest(const uint8_t *data, size_t size)
58 {
59     uint32_t code = ConvertToUint32(data);
60     if (code > static_cast<uint32_t>(IServiceReverseInterfaceCode::SERVICER_BACKUP_ON_TASK_FINISHED)) {
61         return true;
62     }
63 
64     MessageParcel datas;
65     datas.WriteInterfaceToken(ServiceReverseStub::GetDescriptor());
66     datas.WriteBuffer(data, size);
67     datas.RewindRead(0);
68     MessageParcel reply;
69     MessageOption option;
70 
71     BSessionBackup::Callbacks callbacks;
72     std::shared_ptr<ServiceReverse> backupPtr =
73         std::make_shared<ServiceReverse>(callbacks);
74     backupPtr->OnRemoteRequest(code % MAX_CALL_TRANSACTION, datas, reply, option);
75     return true;
76 }
77 
RestoreFuzzTest(const uint8_t * data,size_t size)78 bool RestoreFuzzTest(const uint8_t *data, size_t size)
79 {
80     uint32_t code = ConvertToUint32(data);
81     if (code < static_cast<uint32_t>(IServiceReverseInterfaceCode::SERVICER_RESTORE_ON_SUB_TASK_STARTED) ||
82         code > static_cast<uint32_t>(IServiceReverseInterfaceCode::SERVICER_RESTORE_ON_FILE_READY)) {
83         return true;
84     }
85 
86     MessageParcel datas;
87     datas.WriteInterfaceToken(ServiceReverseStub::GetDescriptor());
88     datas.WriteBuffer(data, size);
89     datas.RewindRead(0);
90     MessageParcel reply;
91     MessageOption option;
92 
93     BSessionRestore::Callbacks callbacks;
94     std::shared_ptr<ServiceReverse> restorePtr =
95         std::make_shared<ServiceReverse>(callbacks);
96     restorePtr->OnRemoteRequest(code % MAX_CALL_TRANSACTION, datas, reply, option);
97     return true;
98 }
99 
IncrementalBackupFuzzTest(const uint8_t * data,size_t size)100 bool IncrementalBackupFuzzTest(const uint8_t *data, size_t size)
101 {
102     uint32_t code = ConvertToUint32(data);
103     if (code < static_cast<uint32_t>(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_BACKUP_ON_FILE_READY) ||
104         code > static_cast<uint32_t>(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_BACKUP_ON_TASK_FINISHED)) {
105         return true;
106     }
107 
108     MessageParcel datas;
109     datas.WriteInterfaceToken(ServiceReverseStub::GetDescriptor());
110     datas.WriteBuffer(data, size);
111     datas.RewindRead(0);
112     MessageParcel reply;
113     MessageOption option;
114 
115     BIncrementalBackupSession::Callbacks callbacks;
116     std::shared_ptr<ServiceReverse> backupPtr =
117         std::make_shared<ServiceReverse>(callbacks);
118     backupPtr->OnRemoteRequest(code % MAX_CALL_TRANSACTION, datas, reply, option);
119     return true;
120 }
121 
IncrementalRestoreFuzzTest(const uint8_t * data,size_t size)122 bool IncrementalRestoreFuzzTest(const uint8_t *data, size_t size)
123 {
124     uint32_t code = ConvertToUint32(data);
125     if (code < static_cast<uint32_t>(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_RESTORE_ON_SUB_TASK_STARTED) ||
126         code > static_cast<uint32_t>(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_RESTORE_ON_FILE_READY)) {
127         return true;
128     }
129 
130     MessageParcel datas;
131     datas.WriteInterfaceToken(ServiceReverseStub::GetDescriptor());
132     datas.WriteBuffer(data, size);
133     datas.RewindRead(0);
134     MessageParcel reply;
135     MessageOption option;
136 
137     BIncrementalRestoreSession::Callbacks callbacks;
138     std::shared_ptr<ServiceReverse> restorePtr =
139         std::make_shared<ServiceReverse>(callbacks);
140     restorePtr->OnRemoteRequest(code % MAX_CALL_TRANSACTION, datas, reply, option);
141     return true;
142 }
143 } // namespace OHOS
144 
145 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)146 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
147 {
148     /* Run your code on data */
149     if (data == nullptr) {
150         return 0;
151     }
152 
153     /* Validate the length of size */
154     if (size < OHOS::U32_AT_SIZE || size > OHOS::FOO_MAX_LEN) {
155         return 0;
156     }
157 
158     OHOS::BackupFuzzTest(data, size);
159     OHOS::RestoreFuzzTest(data, size);
160     OHOS::IncrementalBackupFuzzTest(data, size);
161     OHOS::IncrementalRestoreFuzzTest(data, size);
162     return 0;
163 }