1 /*
2 * Copyright (c) 2025 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 "alg_utils.h"
17
18 #include <unistd.h>
19 #include "securec.h"
20
21 #include "dlp_permission_log.h"
22
23 #define MAX_FOLDER_NAME_SIZE 128
24
25 namespace OHOS {
26 namespace Security {
27 namespace DlpPermission {
28 namespace {
29 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "AlgUtils" };
30 const int PARCEL_DEFAULT_INCREASE_STEP = 16;
31 const uint32_t PARCEL_UINT_MAX = 0xffffffffU;
32 }
33
HcMalloc(uint32_t size,char val)34 void* HcMalloc(uint32_t size, char val)
35 {
36 if (size == 0 || size > MAX_MALLOC_SIZE) {
37 DLP_LOG_ERROR(LABEL, "Malloc size is invalid.");
38 return nullptr;
39 }
40 void* addr = malloc(size);
41 if (addr != nullptr) {
42 (void)memset_s(addr, size, val, size);
43 }
44 return addr;
45 }
46
HcFree(void * addr)47 void HcFree(void* addr)
48 {
49 if (addr != nullptr) {
50 free(addr);
51 }
52 }
53
HcStrlen(const char * str)54 uint32_t HcStrlen(const char *str)
55 {
56 if (str == nullptr) {
57 return 0;
58 }
59 return strlen(str);
60 }
61
ClibMalloc(uint32_t size,char val)62 void* ClibMalloc(uint32_t size, char val)
63 {
64 if (size == 0 || size > CLIB_MAX_MALLOC_SIZE) {
65 return nullptr;
66 }
67 void* addr = malloc(size);
68 if (addr != nullptr) {
69 (void)memset_s(addr, size, val, size);
70 }
71 return addr;
72 }
73
IsBlobDataValid(const BlobData * blob)74 bool IsBlobDataValid(const BlobData *blob)
75 {
76 if (blob == nullptr) {
77 DLP_LOG_ERROR(LABEL, "Blob is null!");
78 return false;
79 }
80 if (blob->value == nullptr) {
81 DLP_LOG_ERROR(LABEL, "The value of blob is null!");
82 return false;
83 }
84 if (blob->dataSize == 0) {
85 DLP_LOG_ERROR(LABEL, "The data size of blob is zero!");
86 return false;
87 }
88 return true;
89 }
90
FreeBlobData(BlobData * data)91 void FreeBlobData(BlobData *data)
92 {
93 if (data == nullptr) {
94 return;
95 }
96 HcFree(data->value);
97 data->value = nullptr;
98 data->dataSize = 0;
99 }
100
CreateParcel(uint32_t size,uint32_t allocUnit)101 HcParcel CreateParcel(uint32_t size, uint32_t allocUnit)
102 {
103 HcParcel parcel;
104 (void)memset_s(&parcel, sizeof(parcel), 0, sizeof(parcel));
105 parcel.allocUnit = allocUnit;
106 if (parcel.allocUnit == 0) {
107 parcel.allocUnit = PARCEL_DEFAULT_INCREASE_STEP;
108 }
109 if (size > 0) {
110 parcel.data = (char *)ClibMalloc(size, 0);
111 if (parcel.data != nullptr) {
112 parcel.length = size;
113 }
114 }
115 return parcel;
116 }
117
DeleteParcel(HcParcel * parcel)118 void DeleteParcel(HcParcel *parcel)
119 {
120 if (parcel == nullptr) {
121 return;
122 }
123
124 if (parcel->data != nullptr) {
125 HcFree(parcel->data);
126 parcel->data = 0;
127 }
128 parcel->length = 0;
129 parcel->beginPos = 0;
130 parcel->endPos = 0;
131 }
132
GetParcelDataSize(const HcParcel * parcel)133 uint32_t GetParcelDataSize(const HcParcel *parcel)
134 {
135 if (parcel == nullptr) {
136 return 0;
137 }
138 if (parcel->endPos >= parcel->beginPos) {
139 return parcel->endPos - parcel->beginPos;
140 }
141 return 0;
142 }
143
GetParcelData(const HcParcel * parcel)144 const char *GetParcelData(const HcParcel *parcel)
145 {
146 if (parcel == nullptr) {
147 return nullptr;
148 }
149 return parcel->data + parcel->beginPos;
150 }
151
ParcelRead(HcParcel * parcel,void * dst,uint32_t dataSize)152 HcBool ParcelRead(HcParcel *parcel, void *dst, uint32_t dataSize)
153 {
154 errno_t rc;
155 if (parcel == nullptr || dst == nullptr || dataSize == 0) {
156 return HC_FALSE;
157 }
158 if (parcel->beginPos > PARCEL_UINT_MAX - dataSize) {
159 return HC_FALSE;
160 }
161 if (parcel->beginPos + dataSize > parcel->endPos) {
162 return HC_FALSE;
163 }
164 rc = memmove_s(dst, dataSize, parcel->data + parcel->beginPos, dataSize);
165 if (rc != EOK) {
166 return HC_FALSE;
167 }
168 parcel->beginPos += dataSize;
169 return HC_TRUE;
170 }
171
ParcelRealloc(HcParcel * parcel,uint32_t size)172 static HcBool ParcelRealloc(HcParcel *parcel, uint32_t size)
173 {
174 if (parcel->length >= size) {
175 return HC_FALSE;
176 }
177 char *newData = (char *)ClibMalloc(size, 0);
178 if (newData == nullptr) {
179 return HC_FALSE;
180 }
181 if (memcpy_s(newData, size, parcel->data, parcel->length) != EOK) {
182 HcFree(newData);
183 return HC_FALSE;
184 }
185 HcFree(parcel->data);
186 parcel->data = newData;
187 parcel->length = size;
188 return HC_TRUE;
189 }
190
ParcelIncrease(HcParcel * parcel,uint32_t size)191 static HcBool ParcelIncrease(HcParcel *parcel, uint32_t size)
192 {
193 if (parcel == nullptr || size == 0) {
194 return HC_FALSE;
195 }
196 if (parcel->data == nullptr) {
197 if (parcel->length != 0) {
198 return HC_FALSE;
199 }
200 *parcel = CreateParcel(size, parcel->allocUnit);
201 if (parcel->data == nullptr) {
202 return HC_FALSE;
203 } else {
204 return HC_TRUE;
205 }
206 } else {
207 return ParcelRealloc(parcel, size);
208 }
209 }
210
ParcelRecycle(HcParcel * parcel)211 static void ParcelRecycle(HcParcel *parcel)
212 {
213 if (parcel == nullptr) {
214 return;
215 }
216 if (parcel->data == nullptr || parcel->beginPos < parcel->allocUnit) {
217 return;
218 }
219
220 uint32_t contentSize = parcel->endPos - parcel->beginPos;
221 if (contentSize > 0) {
222 if (memmove_s(parcel->data, contentSize, parcel->data + parcel->beginPos, contentSize) != EOK) {
223 return;
224 }
225 }
226 parcel->beginPos = 0;
227 parcel->endPos = contentSize;
228 }
229
GetParcelIncreaseSize(HcParcel * parcel,uint32_t newSize)230 static uint32_t GetParcelIncreaseSize(HcParcel *parcel, uint32_t newSize)
231 {
232 if (parcel == nullptr || parcel->allocUnit == 0) {
233 return 0;
234 }
235 if (newSize % parcel->allocUnit) {
236 return (newSize / parcel->allocUnit + 1) * parcel->allocUnit;
237 } else {
238 return (newSize / parcel->allocUnit) * parcel->allocUnit;
239 }
240 }
241
ParcelWrite(HcParcel * parcel,const void * src,uint32_t dataSize)242 HcBool ParcelWrite(HcParcel *parcel, const void *src, uint32_t dataSize)
243 {
244 errno_t rc;
245 if (parcel == nullptr || src == nullptr || dataSize == 0) {
246 return HC_FALSE;
247 }
248 if (parcel->endPos > PARCEL_UINT_MAX - dataSize) {
249 return HC_FALSE;
250 }
251 if (parcel->endPos + dataSize > parcel->length) {
252 ParcelRecycle(parcel);
253 if (parcel->endPos + dataSize > parcel->length) {
254 uint32_t newSize = GetParcelIncreaseSize(parcel, parcel->endPos + dataSize);
255 if (!ParcelIncrease(parcel, newSize)) {
256 return HC_FALSE;
257 }
258 }
259 }
260 rc = memmove_s(parcel->data + parcel->endPos, dataSize, src, dataSize);
261 if (rc != EOK) {
262 return HC_FALSE;
263 }
264 parcel->endPos += dataSize;
265 return HC_TRUE;
266 }
267
CreateDirectory(const char * filePath)268 static int32_t CreateDirectory(const char *filePath)
269 {
270 int32_t ret;
271 errno_t eno;
272 const char *chPtr = nullptr;
273 char dirCache[MAX_FOLDER_NAME_SIZE];
274
275 chPtr = filePath;
276 while ((chPtr = strchr(chPtr, '/')) != nullptr) {
277 unsigned long len = (unsigned long)((uintptr_t)chPtr - (uintptr_t)filePath);
278 if (len == 0uL) {
279 chPtr++;
280 continue;
281 }
282 if (len >= MAX_FOLDER_NAME_SIZE) {
283 DLP_LOG_ERROR(LABEL, "the length of folder in filePath is too long.");
284 return -1;
285 }
286 eno = memcpy_s(dirCache, sizeof(dirCache), filePath, len);
287 if (eno != EOK) {
288 DLP_LOG_ERROR(LABEL, "memory copy failed");
289 return -1;
290 }
291 dirCache[len] = 0;
292 if (access(dirCache, F_OK) != 0) {
293 ret = mkdir(dirCache, S_IRWXU);
294 if (ret != 0) {
295 DLP_LOG_ERROR(LABEL, "make dir failed, err code %{public}d", ret);
296 return -1;
297 }
298 }
299 chPtr++;
300 }
301 return 0;
302 }
303
HcFileOpenRead(const char * path)304 static FILE *HcFileOpenRead(const char *path)
305 {
306 return fopen(path, "rb");
307 }
308
HcFileOpenWrite(const char * path,mode_t permissionMode)309 static FILE *HcFileOpenWrite(const char *path, mode_t permissionMode)
310 {
311 if (access(path, F_OK) != 0) {
312 int32_t ret = CreateDirectory(path);
313 if (ret != 0) {
314 return nullptr;
315 }
316 }
317
318 mode_t oldMask = umask(permissionMode);
319 FILE *fp = fopen(path, "w+");
320 (void)umask(oldMask);
321 return fp;
322 }
323
HcFileOpen(const char * path,int mode,FileHandle * file,mode_t permissionMode)324 int HcFileOpen(const char *path, int mode, FileHandle *file, mode_t permissionMode)
325 {
326 if (path == nullptr || file == nullptr) {
327 return -1;
328 }
329 if (mode == MODE_FILE_READ) {
330 file->pfd = HcFileOpenRead(path);
331 } else {
332 file->pfd = HcFileOpenWrite(path, permissionMode);
333 }
334
335 if (file->pfd == nullptr) {
336 return -1;
337 }
338 return 0;
339 }
340
HcFileSize(FileHandle file)341 int HcFileSize(FileHandle file)
342 {
343 FILE *fp = (FILE *)file.pfd;
344 if (fp != nullptr) {
345 if (fseek(fp, 0L, SEEK_END) != 0) {
346 return -1;
347 }
348 int size = ftell(fp);
349 if (fseek(fp, 0L, SEEK_SET) != 0) {
350 return -1;
351 }
352 return size;
353 } else {
354 return -1;
355 }
356 }
357
HcFileRead(FileHandle file,void * dst,int dstSize)358 int HcFileRead(FileHandle file, void *dst, int dstSize)
359 {
360 FILE *fp = (FILE *)file.pfd;
361 if (fp == nullptr || dstSize < 0 || dst == nullptr) {
362 return -1;
363 }
364
365 char *dstBuffer = (char *)dst;
366 int total = 0;
367 while (total < dstSize) {
368 int readCount = (int)fread(dstBuffer + total, 1, dstSize - total, fp);
369 if (ferror(fp) != 0) {
370 DLP_LOG_ERROR(LABEL, "read file error!");
371 }
372 if (readCount == 0) {
373 return total;
374 }
375 total += readCount;
376 }
377
378 return total;
379 }
380
HcFileWrite(FileHandle file,const void * src,int srcSize)381 int HcFileWrite(FileHandle file, const void *src, int srcSize)
382 {
383 FILE *fp = (FILE *)file.pfd;
384 if (fp == nullptr || srcSize < 0 || src == nullptr) {
385 return -1;
386 }
387
388 const char *srcBuffer = static_cast<const char *>(src);
389 int total = 0;
390 while (total < srcSize) {
391 int writeCount = (int)fwrite(srcBuffer + total, 1, srcSize - total, fp);
392 if (ferror(fp) != 0) {
393 DLP_LOG_ERROR(LABEL, "write file error!");
394 }
395 total += writeCount;
396 }
397 return total;
398 }
399
HcFileClose(FileHandle file)400 void HcFileClose(FileHandle file)
401 {
402 FILE *fp = (FILE *)file.pfd;
403 if (fp == nullptr) {
404 return;
405 }
406
407 (void)fclose(fp);
408 }
409
HcIsFileExist(const char * path)410 bool HcIsFileExist(const char *path)
411 {
412 if (path == nullptr) {
413 DLP_LOG_ERROR(LABEL, "Input params is invalid");
414 return false;
415 }
416 if (access(path, 0) != 0) {
417 return false;
418 }
419 return true;
420 }
421 } // namespace DlpPermission
422 } // namespace Security
423 } // namespace OHOS