• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifdef LOSCFG_KERNEL_DEV_PLIMIT
32 #include "los_seq_buf.h"
33 #include "los_bitmap.h"
34 #include "los_process_pri.h"
35 #include "los_devicelimit.h"
36 
37 #define TYPE_CHAR_LEN            (1)
38 #define DEVICE_NAME_PREFIX_SPACE (1)
39 #define DEVICE_ACCESS_MAXLEN     (3)
40 #define BUF_SEPARATOR            (5)
41 
42 STATIC ProcDevLimit *g_procDevLimit = NULL;
43 
OsDevLimitInit(UINTPTR limit)44 VOID OsDevLimitInit(UINTPTR limit)
45 {
46     ProcDevLimit *deviceLimit = (ProcDevLimit *)limit;
47     deviceLimit->behavior = DEVLIMIT_DEFAULT_ALLOW;
48     LOS_ListInit(&(deviceLimit->accessList));
49     g_procDevLimit = deviceLimit;
50 }
51 
OsDevLimitAlloc(VOID)52 VOID *OsDevLimitAlloc(VOID)
53 {
54     ProcDevLimit *plimit = (ProcDevLimit *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcDevLimit));
55     if (plimit == NULL) {
56         return NULL;
57     }
58     (VOID)memset_s(plimit, sizeof(ProcDevLimit), 0, sizeof(ProcDevLimit));
59     LOS_ListInit(&(plimit->accessList));
60     plimit->behavior = DEVLIMIT_DEFAULT_NONE;
61     return (VOID *)plimit;
62 }
63 
DevAccessListDelete(ProcDevLimit * devLimit)64 STATIC VOID DevAccessListDelete(ProcDevLimit *devLimit)
65 {
66     DevAccessItem *delItem = NULL;
67     DevAccessItem *tmpItem = NULL;
68     LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(delItem, tmpItem, &devLimit->accessList, DevAccessItem, list) {
69         LOS_ListDelete(&delItem->list);
70         (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)delItem);
71     }
72 }
73 
OsDevLimitFree(UINTPTR limit)74 VOID OsDevLimitFree(UINTPTR limit)
75 {
76     ProcDevLimit *devLimit = (ProcDevLimit *)limit;
77     if (devLimit == NULL) {
78         return;
79     }
80 
81     DevAccessListDelete(devLimit);
82     (VOID)LOS_MemFree(m_aucSysMem1, devLimit);
83 }
84 
DevLimitCopyAccess(ProcDevLimit * devLimitDest,ProcDevLimit * devLimitSrc)85 STATIC UINT32 DevLimitCopyAccess(ProcDevLimit *devLimitDest, ProcDevLimit *devLimitSrc)
86 {
87     DevAccessItem *tmpItem = NULL;
88     INT32 itemSize = sizeof(DevAccessItem);
89     devLimitDest->behavior = devLimitSrc->behavior;
90     LOS_DL_LIST_FOR_EACH_ENTRY(tmpItem, &devLimitSrc->accessList, DevAccessItem, list) {
91         DevAccessItem *newItem = (DevAccessItem *)LOS_MemAlloc(m_aucSysMem1, itemSize);
92         if (newItem == NULL) {
93             return ENOMEM;
94         }
95         (VOID)memcpy_s(newItem, sizeof(DevAccessItem), tmpItem, sizeof(DevAccessItem));
96         LOS_ListTailInsert(&devLimitDest->accessList, &newItem->list);
97     }
98     return LOS_OK;
99 }
100 
OsDevLimitCopy(UINTPTR dest,UINTPTR src)101 VOID OsDevLimitCopy(UINTPTR dest, UINTPTR src)
102 {
103     ProcDevLimit *devLimitDest = (ProcDevLimit *)dest;
104     ProcDevLimit *devLimitSrc = (ProcDevLimit *)src;
105     (VOID)DevLimitCopyAccess(devLimitDest, devLimitSrc);
106     devLimitDest->parent = (ProcDevLimit *)src;
107 }
108 
IsSpace(INT32 c)109 STATIC INLINE INT32 IsSpace(INT32 c)
110 {
111     return (c == ' ' || (unsigned)c - '\t' < BUF_SEPARATOR);
112 }
113 
ParseItemAccess(const CHAR * buf,DevAccessItem * item)114 STATIC UINT32 ParseItemAccess(const CHAR *buf, DevAccessItem *item)
115 {
116     switch (*buf) {
117         case 'a':
118             item->type = DEVLIMIT_DEV_ALL;
119             return LOS_OK;
120         case 'b':
121             item->type = DEVLIMIT_DEV_BLOCK;
122             break;
123         case 'c':
124             item->type = DEVLIMIT_DEV_CHAR;
125             break;
126         default:
127             return EINVAL;
128     }
129     buf += DEVICE_NAME_PREFIX_SPACE;
130     if (!IsSpace(*buf)) {
131         return EINVAL;
132     }
133     buf += DEVICE_NAME_PREFIX_SPACE;
134 
135     for (INT32 count = 0; count < sizeof(item->name) - 1; count++) {
136         if (IsSpace(*buf)) {
137             break;
138         }
139         item->name[count] = *buf;
140         buf += TYPE_CHAR_LEN;
141     }
142     if (!IsSpace(*buf)) {
143         return EINVAL;
144     }
145 
146     buf += DEVICE_NAME_PREFIX_SPACE;
147     for (INT32 i = 0; i < DEVICE_ACCESS_MAXLEN; i++) {
148         switch (*buf) {
149             case 'r':
150                 item->access |= DEVLIMIT_ACC_READ;
151                 break;
152             case 'w':
153                 item->access |= DEVLIMIT_ACC_WRITE;
154                 break;
155             case 'm':
156                 item->access |= DEVLIMIT_ACC_MKNOD;
157                 break;
158             case '\n':
159             case '\0':
160                 i = DEVICE_ACCESS_MAXLEN;
161                 break;
162             default:
163                 return EINVAL;
164         }
165         buf += TYPE_CHAR_LEN;
166     }
167     return LOS_OK;
168 }
169 
DevLimitMayAllowAll(ProcDevLimit * parent)170 STATIC BOOL DevLimitMayAllowAll(ProcDevLimit *parent)
171 {
172     if (parent == NULL) {
173         return TRUE;
174     }
175     return (parent->behavior == DEVLIMIT_DEFAULT_ALLOW);
176 }
177 
DevLimitHasChildren(ProcLimitSet * procLimitSet,ProcDevLimit * devLimit)178 STATIC BOOL DevLimitHasChildren(ProcLimitSet *procLimitSet, ProcDevLimit *devLimit)
179 {
180     ProcLimitSet *parent = procLimitSet;
181     ProcLimitSet *childProcLimitSet = NULL;
182     if (devLimit == NULL) {
183         return FALSE;
184     }
185 
186     LOS_DL_LIST_FOR_EACH_ENTRY(childProcLimitSet, &(procLimitSet->childList), ProcLimitSet, childList) {
187         if (childProcLimitSet == NULL) {
188             continue;
189         }
190         if (childProcLimitSet->parent != parent) {
191             continue;
192         }
193         if (!((childProcLimitSet->mask) & BIT(PROCESS_LIMITER_ID_DEV))) {
194             continue;
195         }
196         return TRUE;
197     }
198     return FALSE;
199 }
200 
DealItemAllAccess(ProcLimitSet * procLimitSet,ProcDevLimit * devLimit,ProcDevLimit * devParentLimit,INT32 filetype)201 STATIC UINT32 DealItemAllAccess(ProcLimitSet *procLimitSet, ProcDevLimit *devLimit,
202                                 ProcDevLimit *devParentLimit, INT32 filetype)
203 {
204     switch (filetype) {
205         case DEVLIMIT_ALLOW: {
206             if (DevLimitHasChildren(procLimitSet, devLimit)) {
207                 return EINVAL;
208             }
209             if (!DevLimitMayAllowAll(devParentLimit)) {
210                 return EPERM;
211             }
212             DevAccessListDelete(devLimit);
213             devLimit->behavior = DEVLIMIT_DEFAULT_ALLOW;
214             if (devParentLimit == NULL) {
215                 break;
216             }
217             DevLimitCopyAccess(devLimit, devParentLimit);
218             break;
219         }
220         case DEVLIMIT_DENY: {
221             if (DevLimitHasChildren(procLimitSet, devLimit)) {
222                 return EINVAL;
223             }
224             DevAccessListDelete(devLimit);
225             devLimit->behavior = DEVLIMIT_DEFAULT_DENY;
226             break;
227         }
228         default:
229             return EINVAL;
230     }
231     return LOS_OK;
232 }
233 
DevLimitMatchItemPartial(LOS_DL_LIST * list,DevAccessItem * item)234 STATIC BOOL DevLimitMatchItemPartial(LOS_DL_LIST *list, DevAccessItem *item)
235 {
236     if ((list == NULL) || (item == NULL)) {
237         return FALSE;
238     }
239     if (LOS_ListEmpty(list)) {
240         return FALSE;
241     }
242     DevAccessItem *walk = NULL;
243     LOS_DL_LIST_FOR_EACH_ENTRY(walk, list, DevAccessItem, list) {
244         if (item->type != walk->type) {
245             continue;
246         }
247         if ((strcmp(walk->name, "*") != 0) && (strcmp(item->name, "*") != 0)
248         && (strcmp(walk->name, item->name) != 0)) {
249             continue;
250         }
251         if (!(item->access & ~(walk->access))) {
252             return TRUE;
253         }
254     }
255     return FALSE;
256 }
257 
DevLimitParentAllowsRmItem(ProcDevLimit * devParentLimit,DevAccessItem * item)258 STATIC BOOL DevLimitParentAllowsRmItem(ProcDevLimit *devParentLimit, DevAccessItem *item)
259 {
260     if (devParentLimit == NULL) {
261         return TRUE;
262     }
263      /* Make sure you're not removing part or a whole item existing in the parent plimits */
264     return !DevLimitMatchItemPartial(&devParentLimit->accessList, item);
265 }
266 
DevLimitMatchItem(LOS_DL_LIST * list,DevAccessItem * item)267 STATIC BOOL DevLimitMatchItem(LOS_DL_LIST *list, DevAccessItem *item)
268 {
269     if ((list == NULL) || (item == NULL)) {
270         return FALSE;
271     }
272     if (LOS_ListEmpty(list)) {
273         return FALSE;
274     }
275     DevAccessItem *walk = NULL;
276     LOS_DL_LIST_FOR_EACH_ENTRY(walk, list, DevAccessItem, list) {
277         if (item->type != walk->type) {
278             continue;
279         }
280         if ((strcmp(walk->name, "*") != 0) && (strcmp(walk->name, item->name) != 0)) {
281             continue;
282         }
283         if (!(item->access & ~(walk->access))) {
284             return TRUE;
285         }
286     }
287     return FALSE;
288 }
289 
290 /**
291  * This is used to make sure a child plimits won't have more privileges than its parent
292  */
DevLimitVerifyNewItem(ProcDevLimit * parent,DevAccessItem * item,INT32 currBehavior)293 STATIC BOOL DevLimitVerifyNewItem(ProcDevLimit *parent, DevAccessItem *item, INT32 currBehavior)
294 {
295     if (parent == NULL) {
296         return TRUE;
297     }
298 
299     if (parent->behavior == DEVLIMIT_DEFAULT_ALLOW) {
300         if (currBehavior == DEVLIMIT_DEFAULT_ALLOW) {
301             return TRUE;
302         }
303         return !DevLimitMatchItemPartial(&parent->accessList, item);
304     }
305     return DevLimitMatchItem(&parent->accessList, item);
306 }
307 
DevLimitParentAllowsAddItem(ProcDevLimit * devParentLimit,DevAccessItem * item,INT32 currBehavior)308 STATIC BOOL DevLimitParentAllowsAddItem(ProcDevLimit *devParentLimit, DevAccessItem *item, INT32 currBehavior)
309 {
310     return DevLimitVerifyNewItem(devParentLimit, item, currBehavior);
311 }
312 
DevLimitAccessListRm(ProcDevLimit * devLimit,DevAccessItem * item)313 STATIC VOID DevLimitAccessListRm(ProcDevLimit *devLimit, DevAccessItem *item)
314 {
315     if ((item == NULL) || (devLimit == NULL)) {
316         return;
317     }
318     DevAccessItem *walk, *tmp = NULL;
319     LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(walk, tmp, &devLimit->accessList, DevAccessItem, list) {
320         if (walk->type != item->type) {
321             continue;
322         }
323         if (strcmp(walk->name, item->name) != 0) {
324             continue;
325         }
326         walk->access &= ~item->access;
327         if (!walk->access) {
328             LOS_ListDelete(&walk->list);
329             (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)walk);
330         }
331     }
332 }
333 
DevLimitAccessListAdd(ProcDevLimit * devLimit,DevAccessItem * item)334 STATIC UINT32 DevLimitAccessListAdd(ProcDevLimit *devLimit, DevAccessItem *item)
335 {
336     if ((item == NULL) || (devLimit == NULL)) {
337         return ENOMEM;
338     }
339 
340     DevAccessItem *walk = NULL;
341     DevAccessItem *newItem = (DevAccessItem *)LOS_MemAlloc(m_aucSysMem1, sizeof(DevAccessItem));
342     if (newItem == NULL) {
343         return ENOMEM;
344     }
345     (VOID)memcpy_s(newItem, sizeof(DevAccessItem), item, sizeof(DevAccessItem));
346     LOS_DL_LIST_FOR_EACH_ENTRY(walk, &devLimit->accessList, DevAccessItem, list) {
347         if (walk->type != item->type) {
348             continue;
349         }
350         if (strcmp(walk->name, item->name) != 0) {
351             continue;
352         }
353         walk->access |= item->access;
354         (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)newItem);
355         newItem = NULL;
356     }
357 
358     if (newItem != NULL) {
359         LOS_ListTailInsert(&devLimit->accessList, &newItem->list);
360     }
361     return LOS_OK;
362 }
363 
364 /**
365  * Revalidate permissions
366  */
DevLimitRevalidateActiveItems(ProcDevLimit * devLimit,ProcDevLimit * devParentLimit)367 STATIC VOID DevLimitRevalidateActiveItems(ProcDevLimit *devLimit, ProcDevLimit *devParentLimit)
368 {
369     if ((devLimit == NULL) || (devParentLimit == NULL)) {
370         return;
371     }
372     DevAccessItem *walK = NULL;
373     DevAccessItem *tmp = NULL;
374     LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(walK, tmp, &devLimit->accessList, DevAccessItem, list) {
375         if (!DevLimitParentAllowsAddItem(devParentLimit, walK, devLimit->behavior)) {
376             DevLimitAccessListRm(devLimit, walK);
377         }
378     }
379 }
380 
381 /**
382  * propagates a new item to the children
383  */
DevLimitPropagateItem(ProcLimitSet * procLimitSet,ProcDevLimit * devLimit,DevAccessItem * item)384 STATIC UINT32 DevLimitPropagateItem(ProcLimitSet *procLimitSet, ProcDevLimit *devLimit, DevAccessItem *item)
385 {
386     UINT32 ret = LOS_OK;
387     ProcLimitSet *parent = procLimitSet;
388     ProcLimitSet *childProcLimitSet = NULL;
389 
390     if ((procLimitSet == NULL) || (item == NULL)) {
391         return ENOMEM;
392     }
393 
394     if (devLimit == NULL) {
395         return LOS_OK;
396     }
397 
398     LOS_DL_LIST_FOR_EACH_ENTRY(childProcLimitSet, &procLimitSet->childList, ProcLimitSet, childList) {
399         if (childProcLimitSet == NULL) {
400             continue;
401         }
402         if (childProcLimitSet->parent != parent) {
403             continue;
404         }
405         if (!((childProcLimitSet->mask) & BIT(PROCESS_LIMITER_ID_DEV))) {
406             continue;
407         }
408         ProcDevLimit *devLimitChild = (ProcDevLimit *)childProcLimitSet->limitsList[PROCESS_LIMITER_ID_DEV];
409         if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW &&
410             devLimitChild->behavior == DEVLIMIT_DEFAULT_ALLOW) {
411             ret = DevLimitAccessListAdd(devLimitChild, item);
412         } else {
413             DevLimitAccessListRm(devLimitChild, item);
414         }
415         DevLimitRevalidateActiveItems(devLimitChild, (ProcDevLimit *)parent->limitsList[PROCESS_LIMITER_ID_DEV]);
416     }
417     return ret;
418 }
419 
DevLimitUpdateAccess(ProcLimitSet * procLimitSet,const CHAR * buf,INT32 filetype)420 STATIC UINT32 DevLimitUpdateAccess(ProcLimitSet *procLimitSet, const CHAR *buf, INT32 filetype)
421 {
422     UINT32 ret;
423     UINT32 intSave;
424     DevAccessItem item = {0};
425 
426     SCHEDULER_LOCK(intSave);
427     ProcDevLimit *devLimit = (ProcDevLimit *)(procLimitSet->limitsList[PROCESS_LIMITER_ID_DEV]);
428     ProcDevLimit *devParentLimit = devLimit->parent;
429 
430     ret = ParseItemAccess(buf, &item);
431     if (ret != LOS_OK) {
432         SCHEDULER_UNLOCK(intSave);
433         return ret;
434     }
435     if (item.type == DEVLIMIT_DEV_ALL) {
436         ret = DealItemAllAccess(procLimitSet, devLimit, devParentLimit, filetype);
437         SCHEDULER_UNLOCK(intSave);
438         return ret;
439     }
440     switch (filetype) {
441         case DEVLIMIT_ALLOW: {
442             if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW) {
443                 if (!DevLimitParentAllowsRmItem(devParentLimit, &item)) {
444                     SCHEDULER_UNLOCK(intSave);
445                     return EPERM;
446                 }
447                 DevLimitAccessListRm(devLimit, &item);
448                 break;
449             }
450             if (!DevLimitParentAllowsAddItem(devParentLimit, &item, devLimit->behavior)) {
451                 SCHEDULER_UNLOCK(intSave);
452                 return EPERM;
453             }
454             ret = DevLimitAccessListAdd(devLimit, &item);
455             break;
456         }
457         case DEVLIMIT_DENY: {
458             if (devLimit->behavior == DEVLIMIT_DEFAULT_DENY) {
459                 DevLimitAccessListRm(devLimit, &item);
460             } else {
461                 ret = DevLimitAccessListAdd(devLimit, &item);
462             }
463             // update child access list
464             ret = DevLimitPropagateItem(procLimitSet, devLimit, &item);
465             break;
466         }
467         default:
468             ret = EINVAL;
469             break;
470     }
471     SCHEDULER_UNLOCK(intSave);
472     return ret;
473 }
474 
475 
OsDevLimitWriteAllow(ProcLimitSet * plimit,const CHAR * buf,UINT32 size)476 UINT32 OsDevLimitWriteAllow(ProcLimitSet *plimit, const CHAR *buf, UINT32 size)
477 {
478     (VOID)size;
479     return DevLimitUpdateAccess(plimit, buf, DEVLIMIT_ALLOW);
480 }
481 
OsDevLimitWriteDeny(ProcLimitSet * plimit,const CHAR * buf,UINT32 size)482 UINT32 OsDevLimitWriteDeny(ProcLimitSet *plimit, const CHAR *buf, UINT32 size)
483 {
484     (VOID)size;
485     return DevLimitUpdateAccess(plimit, buf, DEVLIMIT_DENY);
486 }
487 
DevLimitItemSetAccess(CHAR * acc,INT16 access)488 STATIC VOID DevLimitItemSetAccess(CHAR *acc, INT16 access)
489 {
490     INT32 index = 0;
491     (VOID)memset_s(acc, ACCLEN, 0, ACCLEN);
492     if (access & DEVLIMIT_ACC_READ) {
493         acc[index++] = 'r';
494     }
495     if (access & DEVLIMIT_ACC_WRITE) {
496         acc[index++] = 'w';
497     }
498     if (access & DEVLIMIT_ACC_MKNOD) {
499         acc[index++] = 'm';
500     }
501 }
502 
DevLimitItemTypeToChar(INT16 type)503 STATIC CHAR DevLimitItemTypeToChar(INT16 type)
504 {
505     if (type == DEVLIMIT_DEV_ALL) {
506         return 'a';
507     } else if (type == DEVLIMIT_DEV_CHAR) {
508         return 'c';
509     } else if (type == DEVLIMIT_DEV_BLOCK) {
510         return 'b';
511     }
512     return 'X';
513 }
514 
OsDevLimitShow(ProcDevLimit * devLimit,struct SeqBuf * seqBuf)515 UINT32 OsDevLimitShow(ProcDevLimit *devLimit, struct SeqBuf *seqBuf)
516 {
517     DevAccessItem *item = NULL;
518     CHAR acc[ACCLEN];
519     UINT32 intSave;
520 
521     if ((devLimit == NULL) || (seqBuf == NULL)) {
522         return EINVAL;
523     }
524 
525     SCHEDULER_LOCK(intSave);
526     if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW) {
527         DevLimitItemSetAccess(acc, DEVLIMIT_ACC_MASK);
528         SCHEDULER_UNLOCK(intSave);
529         LosBufPrintf(seqBuf, "%c %s %s\n", DevLimitItemTypeToChar(DEVLIMIT_DEV_ALL), "*", acc);
530         return LOS_OK;
531     }
532     LOS_DL_LIST_FOR_EACH_ENTRY(item, &devLimit->accessList, DevAccessItem, list) {
533         DevLimitItemSetAccess(acc, item->access);
534         LosBufPrintf(seqBuf, "%c %s %s\n", DevLimitItemTypeToChar(item->type), item->name, acc);
535     }
536     SCHEDULER_UNLOCK(intSave);
537     return LOS_OK;
538 }
539 
ConversionDevType(INT32 vnodeType)540 STATIC INLINE INT16 ConversionDevType(INT32 vnodeType)
541 {
542     INT16 type = 0;
543     if (vnodeType == VNODE_TYPE_BLK) {
544         type = DEVLIMIT_DEV_BLOCK;
545     } else if (vnodeType == VNODE_TYPE_CHR) {
546         type = DEVLIMIT_DEV_CHAR;
547     }
548     return type;
549 }
550 
ConversionDevAccess(INT32 flags)551 STATIC INLINE INT16 ConversionDevAccess(INT32 flags)
552 {
553     INT16 access = 0;
554     if ((flags & O_ACCMODE) == O_RDONLY) {
555         access |= DEVLIMIT_ACC_READ;
556     }
557     if (flags & O_WRONLY) {
558         access |= DEVLIMIT_ACC_WRITE;
559     }
560     if (flags & O_RDWR) {
561         access |= DEVLIMIT_ACC_WRITE | DEVLIMIT_ACC_READ;
562     }
563     if (flags & O_CREAT) {
564         access |= DEVLIMIT_ACC_MKNOD;
565     }
566     return access;
567 }
568 
OsDevLimitCheckPermission(INT32 vnodeType,const CHAR * pathName,INT32 flags)569 UINT32 OsDevLimitCheckPermission(INT32 vnodeType, const CHAR *pathName, INT32 flags)
570 {
571     BOOL matched = FALSE;
572     DevAccessItem item = {0};
573     LosProcessCB *run = OsCurrProcessGet();
574     if ((run == NULL) || (run->plimits == NULL)) {
575         return LOS_OK;
576     }
577 
578     if (pathName == NULL) {
579         return EINVAL;
580     }
581 
582     ProcDevLimit *devLimit = (ProcDevLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_DEV];
583 
584     item.type = ConversionDevType(vnodeType);
585     item.access = ConversionDevAccess(flags);
586     LOS_ListInit(&(item.list));
587     (VOID)strncpy_s(item.name, PATH_MAX, pathName, PATH_MAX);
588 
589     if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW) {
590         matched = !DevLimitMatchItemPartial(&devLimit->accessList, &item);
591     } else {
592         matched = DevLimitMatchItem(&devLimit->accessList, &item);
593     }
594     if (!matched) {
595         return EPERM;
596     }
597     return LOS_OK;
598 }
599 #endif
600