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 "remotefileshare_fuzzer.h"
17 
18 #include <cstdint>
19 #include <fcntl.h>
20 #include <sys/ioctl.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 
25 #include <climits>
26 
27 #include "securec.h"
28 
29 namespace OHOS {
30 namespace AppFileService {
31 namespace ModuleRemoteFileShare {
32 namespace {
33     constexpr int HMDFS_CID_SIZE = 64;
34     constexpr unsigned HMDFS_IOC = 0xf2;
35     const char* g_sharePATH = "/data/storage/el2/distributedfiles/.share";
36 }
37 
38 #define HMDFS_IOC_SET_SHARE_PATH    _IOW(HMDFS_IOC, 1, struct HmdfsShareControl)
39 
40 struct HmdfsShareControl {
41     int srcFd;
42     char cid[HMDFS_CID_SIZE];
43 };
44 
ShareFilePathIoctlFdAndCidFuzzTest(const uint8_t * data,size_t size)45 bool ShareFilePathIoctlFdAndCidFuzzTest(const uint8_t* data, size_t size)
46 {
47     struct HmdfsShareControl sc;
48     int32_t dirFd;
49     int32_t ret = 0;
50 
51     if (size == 0) {
52         return false;
53     }
54 
55     if (access(g_sharePATH, F_OK) != 0) {
56         ret = mkdir(g_sharePATH, S_IRWXU | S_IRWXG | S_IXOTH);
57         if (ret < 0) {
58             return false;
59         }
60     }
61 
62     char path[PATH_MAX] = {0};
63     if (!realpath(g_sharePATH, path)) {
64         return false;
65     }
66     dirFd = open(path, O_RDONLY);
67     if (dirFd < 0) {
68         return false;
69     }
70 
71     const char* cid = reinterpret_cast<const char*>(data);
72     sc.srcFd = size;
73     if (memcpy_s(sc.cid, HMDFS_CID_SIZE, cid, size) != 0) {
74         close(dirFd);
75         return false;
76     }
77 
78     ret = ioctl(dirFd, HMDFS_IOC_SET_SHARE_PATH, &sc);
79     if (ret < 0) {
80         close(dirFd);
81         return false;
82     }
83 
84     return true;
85 }
86 
ShareFilePathIoctlCidFuzzTest(const uint8_t * data,size_t size)87 bool ShareFilePathIoctlCidFuzzTest(const uint8_t* data, size_t size)
88 {
89     struct HmdfsShareControl sc;
90     int32_t ret = 0;
91     int32_t dirFd;
92     int32_t srcFd;
93 
94     if (size == 0) {
95         return false;
96     }
97 
98     if (access(g_sharePATH, F_OK) != 0) {
99         ret = mkdir(g_sharePATH, S_IRWXU | S_IRWXG | S_IXOTH);
100         if (ret < 0) {
101             return false;
102         }
103     }
104 
105     char realLocation[PATH_MAX] = {0};
106     if (!realpath(g_sharePATH, realLocation)) {
107         return false;
108     }
109     dirFd = open(realLocation, O_RDONLY);
110     if (dirFd < 0) {
111         return false;
112     }
113 
114     const char* srcPath = "/data/service/el2/100/hmdfs/non_account/data/com.ohos.camera";
115     srcFd = open(srcPath, O_RDONLY);
116     if (srcFd < 0) {
117         close(dirFd);
118         return false;
119     }
120     sc.srcFd = size;
121     const char* cid = reinterpret_cast<const char*>(data);
122     if (memcpy_s(sc.cid, HMDFS_CID_SIZE, cid, size) != 0) {
123         close(dirFd);
124         close(srcFd);
125         return false;
126     }
127 
128     ret = ioctl(dirFd, HMDFS_IOC_SET_SHARE_PATH, &sc);
129     if (ret < 0) {
130         close(dirFd);
131         close(srcFd);
132         return false;
133     }
134 
135     close(srcFd);
136     return true;
137 }
138 
ShareFilePathIoctlFdFuzzTest(const uint8_t * data,size_t size)139 bool ShareFilePathIoctlFdFuzzTest(const uint8_t* data, size_t size)
140 {
141     struct HmdfsShareControl sc;
142     int32_t ret = 0;
143     int32_t dirFd;
144 
145     if (size == 0) {
146         return false;
147     }
148 
149     if (access(g_sharePATH, F_OK) != 0) {
150         ret = mkdir(g_sharePATH, S_IRWXU | S_IRWXG | S_IXOTH);
151         if (ret < 0) {
152             return false;
153         }
154     }
155 
156     char realPath[PATH_MAX] = {0};
157     if (!realpath(g_sharePATH, realPath)) {
158         return false;
159     }
160 
161     dirFd = open(realPath, O_RDONLY);
162     if (dirFd < 0) {
163         return false;
164     }
165 
166     const char* cid = "remoteShareFileFuzzTestCidxxx";
167     if (memcpy_s(sc.cid, HMDFS_CID_SIZE, cid, strlen(cid)) != 0) {
168         close(dirFd);
169         return false;
170     }
171     sc.srcFd = size;
172 
173     ret = ioctl(dirFd, HMDFS_IOC_SET_SHARE_PATH, &sc);
174     if (ret < 0) {
175         close(dirFd);
176         return false;
177     }
178 
179     return true;
180 }
181 } // namespace ModuleRemoteFileShare
182 } // namespace AppFileService
183 } // namespace OHOS
184 
185 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)186 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
187 {
188     /* Run your code on data */
189     OHOS::AppFileService::ModuleRemoteFileShare::ShareFilePathIoctlFdFuzzTest(data, size);
190     OHOS::AppFileService::ModuleRemoteFileShare::ShareFilePathIoctlCidFuzzTest(data, size);
191     OHOS::AppFileService::ModuleRemoteFileShare::ShareFilePathIoctlFdAndCidFuzzTest(data, size);
192     return 0;
193 }
194