• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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