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