1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "los_process_pri.h"
33 #include "los_task_pri.h"
34 #include "los_sched_pri.h"
35 #include "los_hw_pri.h"
36 #include "los_sys_pri.h"
37 #include "los_futex_pri.h"
38 #include "los_mp.h"
39 #include "sys/wait.h"
40 #include "user_copy.h"
41 #include "time.h"
42 #ifdef LOSCFG_SECURITY_CAPABILITY
43 #include "capability_api.h"
44 #endif
45
OsPermissionToCheck(unsigned int pid,unsigned int who)46 static int OsPermissionToCheck(unsigned int pid, unsigned int who)
47 {
48 int ret = LOS_GetProcessGroupID(pid);
49 if (ret < 0) {
50 return ret;
51 } else if (ret == OS_KERNEL_PROCESS_GROUP) {
52 return -EPERM;
53 } else if ((ret == OS_USER_PRIVILEGE_PROCESS_GROUP) && (pid != who)) {
54 return -EPERM;
55 } else if (pid == OsGetUserInitProcessID()) {
56 return -EPERM;
57 }
58
59 return 0;
60 }
61
OsUserTaskSchedulerSet(unsigned int tid,unsigned short policy,unsigned short priority,bool policyFlag)62 static int OsUserTaskSchedulerSet(unsigned int tid, unsigned short policy, unsigned short priority, bool policyFlag)
63 {
64 int ret;
65 unsigned int intSave;
66 bool needSched = false;
67
68 if (OS_TID_CHECK_INVALID(tid)) {
69 return EINVAL;
70 }
71
72 if (priority > OS_TASK_PRIORITY_LOWEST) {
73 return EINVAL;
74 }
75
76 if ((policy != LOS_SCHED_FIFO) && (policy != LOS_SCHED_RR)) {
77 return EINVAL;
78 }
79
80 LosTaskCB *taskCB = OS_TCB_FROM_TID(tid);
81 SCHEDULER_LOCK(intSave);
82 ret = OsUserTaskOperatePermissionsCheck(taskCB);
83 if (ret != LOS_OK) {
84 SCHEDULER_UNLOCK(intSave);
85 return ret;
86 }
87
88 policy = (policyFlag == true) ? policy : taskCB->policy;
89 needSched = OsSchedModifyTaskSchedParam(taskCB, policy, priority);
90 SCHEDULER_UNLOCK(intSave);
91
92 LOS_MpSchedule(OS_MP_CPU_ALL);
93 if (needSched && OS_SCHEDULER_ACTIVE) {
94 LOS_Schedule();
95 }
96
97 return LOS_OK;
98 }
99
SysSchedYield(int type)100 void SysSchedYield(int type)
101 {
102 (void)type;
103
104 (void)LOS_TaskYield();
105 return;
106 }
107
SysSchedGetScheduler(int id,int flag)108 int SysSchedGetScheduler(int id, int flag)
109 {
110 unsigned int intSave;
111 int policy;
112 int ret;
113
114 if (flag < 0) {
115 if (OS_TID_CHECK_INVALID(id)) {
116 return -EINVAL;
117 }
118
119 LosTaskCB *taskCB = OS_TCB_FROM_TID(id);
120 SCHEDULER_LOCK(intSave);
121 ret = OsUserTaskOperatePermissionsCheck(taskCB);
122 if (ret != LOS_OK) {
123 SCHEDULER_UNLOCK(intSave);
124 return -ret;
125 }
126
127 policy = (int)taskCB->policy;
128 SCHEDULER_UNLOCK(intSave);
129 return policy;
130 }
131
132 return LOS_GetProcessScheduler(id);
133 }
134
SysSchedSetScheduler(int id,int policy,int prio,int flag)135 int SysSchedSetScheduler(int id, int policy, int prio, int flag)
136 {
137 int ret;
138
139 if (flag < 0) {
140 return -OsUserTaskSchedulerSet(id, policy, prio, true);
141 }
142
143 if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) {
144 return -EINVAL;
145 }
146
147 if (id == 0) {
148 id = (int)LOS_GetCurrProcessID();
149 }
150
151 ret = OsPermissionToCheck(id, LOS_GetCurrProcessID());
152 if (ret < 0) {
153 return ret;
154 }
155
156 return OsSetProcessScheduler(LOS_PRIO_PROCESS, id, prio, policy);
157 }
158
SysSchedGetParam(int id,int flag)159 int SysSchedGetParam(int id, int flag)
160 {
161 int prio;
162 unsigned int intSave;
163
164 if (flag < 0) {
165 if (OS_TID_CHECK_INVALID(id)) {
166 return -EINVAL;
167 }
168
169 LosTaskCB *taskCB = OS_TCB_FROM_TID(id);
170 SCHEDULER_LOCK(intSave);
171 prio = OsUserTaskOperatePermissionsCheck(taskCB);
172 if (prio != LOS_OK) {
173 SCHEDULER_UNLOCK(intSave);
174 return -prio;
175 }
176
177 prio = (int)taskCB->priority;
178 SCHEDULER_UNLOCK(intSave);
179 return prio;
180 }
181
182 if (id == 0) {
183 id = (int)LOS_GetCurrProcessID();
184 }
185
186 if (OS_PID_CHECK_INVALID(id)) {
187 return -EINVAL;
188 }
189
190 return OsGetProcessPriority(LOS_PRIO_PROCESS, id);
191 }
192
SysSetProcessPriority(int which,int who,unsigned int prio)193 int SysSetProcessPriority(int which, int who, unsigned int prio)
194 {
195 int ret;
196
197 if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) {
198 return -EINVAL;
199 }
200
201 if (who == 0) {
202 who = (int)LOS_GetCurrProcessID();
203 }
204
205 ret = OsPermissionToCheck(who, LOS_GetCurrProcessID());
206 if (ret < 0) {
207 return ret;
208 }
209
210 return OsSetProcessScheduler(which, who, prio, LOS_GetProcessScheduler(who));
211 }
212
SysSchedSetParam(int id,unsigned int prio,int flag)213 int SysSchedSetParam(int id, unsigned int prio, int flag)
214 {
215 if (flag < 0) {
216 return -OsUserTaskSchedulerSet(id, LOS_SCHED_RR, prio, false);
217 }
218
219 return SysSetProcessPriority(LOS_PRIO_PROCESS, id, prio);
220 }
221
SysGetProcessPriority(int which,int who)222 int SysGetProcessPriority(int which, int who)
223 {
224 if (who == 0) {
225 who = (int)LOS_GetCurrProcessID();
226 }
227
228 return OsGetProcessPriority(which, who);
229 }
230
SysSchedGetPriorityMin(int policy)231 int SysSchedGetPriorityMin(int policy)
232 {
233 if (policy != LOS_SCHED_RR) {
234 return -EINVAL;
235 }
236
237 return OS_USER_PROCESS_PRIORITY_HIGHEST;
238 }
239
SysSchedGetPriorityMax(int policy)240 int SysSchedGetPriorityMax(int policy)
241 {
242 if (policy != LOS_SCHED_RR) {
243 return -EINVAL;
244 }
245
246 return OS_USER_PROCESS_PRIORITY_LOWEST;
247 }
248
SysSchedRRGetInterval(int pid,struct timespec * tp)249 int SysSchedRRGetInterval(int pid, struct timespec *tp)
250 {
251 unsigned int intSave;
252 int ret;
253 time_t timeSlice = 0;
254 struct timespec tv;
255 LosTaskCB *taskCB = NULL;
256 LosProcessCB *processCB = NULL;
257
258 if (tp == NULL) {
259 return -EINVAL;
260 }
261
262 if (OS_PID_CHECK_INVALID(pid)) {
263 return -EINVAL;
264 }
265
266 if (pid == 0) {
267 processCB = OsCurrProcessGet();
268 } else {
269 processCB = OS_PCB_FROM_PID(pid);
270 }
271
272 SCHEDULER_LOCK(intSave);
273 /* if can not find process by pid return ESRCH */
274 if (OsProcessIsInactive(processCB)) {
275 SCHEDULER_UNLOCK(intSave);
276 return -ESRCH;
277 }
278
279 LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) {
280 if (!OsTaskIsInactive(taskCB) && (taskCB->policy == LOS_SCHED_RR)) {
281 timeSlice += taskCB->initTimeSlice;
282 }
283 }
284
285 SCHEDULER_UNLOCK(intSave);
286
287 timeSlice = timeSlice * OS_NS_PER_CYCLE;
288 tv.tv_sec = timeSlice / OS_SYS_NS_PER_SECOND;
289 tv.tv_nsec = timeSlice % OS_SYS_NS_PER_SECOND;
290 ret = LOS_ArchCopyToUser(tp, &tv, sizeof(struct timespec));
291 if (ret != 0) {
292 return -EFAULT;
293 }
294
295 return 0;
296 }
297
SysWait(int pid,USER int * status,int options,void * rusage)298 int SysWait(int pid, USER int *status, int options, void *rusage)
299 {
300 (void)rusage;
301
302 return LOS_Wait(pid, status, (unsigned int)options, NULL);
303 }
304
SysWaitid(idtype_t type,int pid,USER siginfo_t * info,int options,void * rusage)305 int SysWaitid(idtype_t type, int pid, USER siginfo_t *info, int options, void *rusage)
306 {
307 (void)rusage;
308 int ret;
309 int truepid = 0;
310
311 switch (type) {
312 case P_ALL:
313 /* Wait for any child; id is ignored. */
314 truepid = -1;
315 break;
316 case P_PID:
317 /* Wait for the child whose process ID matches id */
318 if (pid <= 0) {
319 return -EINVAL;
320 }
321 truepid = pid;
322 break;
323 case P_PGID:
324 /* Wait for any child whose process group ID matches id */
325 if (pid <= 1) {
326 return -EINVAL;
327 }
328 truepid = -pid;
329 break;
330 default:
331 return -EINVAL;
332 }
333
334 ret = LOS_Waitid(truepid, info, (unsigned int)options, NULL);
335 if (ret > 0) {
336 ret = 0;
337 }
338 return ret;
339 }
340
SysFork(void)341 int SysFork(void)
342 {
343 return OsClone(0, 0, 0);
344 }
345
SysVfork(void)346 int SysVfork(void)
347 {
348 return OsClone(CLONE_VFORK, 0, 0);
349 }
350
SysGetPPID(void)351 unsigned int SysGetPPID(void)
352 {
353 return OsCurrProcessGet()->parentProcessID;
354 }
355
SysGetPID(void)356 unsigned int SysGetPID(void)
357 {
358 return LOS_GetCurrProcessID();
359 }
360
SysSetProcessGroupID(unsigned int pid,unsigned int gid)361 int SysSetProcessGroupID(unsigned int pid, unsigned int gid)
362 {
363 int ret;
364
365 if (pid == 0) {
366 pid = LOS_GetCurrProcessID();
367 }
368
369 if (gid == 0) {
370 gid = pid;
371 } else if (gid <= OS_USER_PRIVILEGE_PROCESS_GROUP) {
372 return -EPERM;
373 }
374
375 ret = OsPermissionToCheck(pid, gid);
376 if (ret < 0) {
377 return ret;
378 }
379
380 return OsSetProcessGroupID(pid, gid);
381 }
382
SysGetProcessGroupID(unsigned int pid)383 int SysGetProcessGroupID(unsigned int pid)
384 {
385 if (pid == 0) {
386 pid = LOS_GetCurrProcessID();
387 }
388
389 return LOS_GetProcessGroupID(pid);
390 }
391
SysGetCurrProcessGroupID(void)392 int SysGetCurrProcessGroupID(void)
393 {
394 return LOS_GetCurrProcessGroupID();
395 }
396
SysGetUserID(void)397 int SysGetUserID(void)
398 {
399 return LOS_GetUserID();
400 }
401
SysGetEffUserID(void)402 int SysGetEffUserID(void)
403 {
404 #ifdef LOSCFG_SECURITY_CAPABILITY
405 UINT32 intSave;
406 int euid;
407
408 SCHEDULER_LOCK(intSave);
409 euid = (int)OsCurrUserGet()->effUserID;
410 SCHEDULER_UNLOCK(intSave);
411 return euid;
412 #else
413 return 0;
414 #endif
415 }
416
SysGetEffGID(void)417 int SysGetEffGID(void)
418 {
419 #ifdef LOSCFG_SECURITY_CAPABILITY
420 UINT32 intSave;
421 int egid;
422
423 SCHEDULER_LOCK(intSave);
424 egid = (int)OsCurrUserGet()->effGid;
425 SCHEDULER_UNLOCK(intSave);
426 return egid;
427 #else
428 return 0;
429 #endif
430 }
431
SysGetRealEffSaveUserID(int * ruid,int * euid,int * suid)432 int SysGetRealEffSaveUserID(int *ruid, int *euid, int *suid)
433 {
434 int ret;
435 int realUserID, effUserID, saveUserID;
436 #ifdef LOSCFG_SECURITY_CAPABILITY
437 unsigned int intSave;
438
439 SCHEDULER_LOCK(intSave);
440 realUserID = OsCurrUserGet()->userID;
441 effUserID = OsCurrUserGet()->effUserID;
442 saveUserID = OsCurrUserGet()->effUserID;
443 SCHEDULER_UNLOCK(intSave);
444 #else
445 realUserID = 0;
446 effUserID = 0;
447 saveUserID = 0;
448 #endif
449
450 ret = LOS_ArchCopyToUser(ruid, &realUserID, sizeof(int));
451 if (ret != 0) {
452 return -EFAULT;
453 }
454
455 ret = LOS_ArchCopyToUser(euid, &effUserID, sizeof(int));
456 if (ret != 0) {
457 return -EFAULT;
458 }
459
460 ret = LOS_ArchCopyToUser(suid, &saveUserID, sizeof(int));
461 if (ret != 0) {
462 return -EFAULT;
463 }
464
465 return 0;
466 }
467
SysSetUserID(int uid)468 int SysSetUserID(int uid)
469 {
470 #ifdef LOSCFG_SECURITY_CAPABILITY
471 int ret = -EPERM;
472 unsigned int intSave;
473
474 if (uid < 0) {
475 return -EINVAL;
476 }
477
478 SCHEDULER_LOCK(intSave);
479 User *user = OsCurrUserGet();
480 if (IsCapPermit(CAP_SETUID)) {
481 user->userID = uid;
482 user->effUserID = uid;
483 /* add process to a user */
484 } else if (user->userID != uid) {
485 goto EXIT;
486 }
487
488 ret = LOS_OK;
489 /* add process to a user */
490 EXIT:
491 SCHEDULER_UNLOCK(intSave);
492 return ret;
493 #else
494 if (uid != 0) {
495 return -EPERM;
496 }
497
498 return 0;
499 #endif
500 }
501
502 #ifdef LOSCFG_SECURITY_CAPABILITY
SetRealEffSaveUserIDCheck(int ruid,int euid,int suid)503 static int SetRealEffSaveUserIDCheck(int ruid, int euid, int suid)
504 {
505 if ((ruid < 0) && (ruid != -1)) {
506 return -EINVAL;
507 }
508
509 if ((euid < 0) && (euid != -1)) {
510 return -EINVAL;
511 }
512
513 if ((suid < 0) && (suid != -1)) {
514 return -EINVAL;
515 }
516
517 return 0;
518 }
519 #endif
520
SysSetRealEffSaveUserID(int ruid,int euid,int suid)521 int SysSetRealEffSaveUserID(int ruid, int euid, int suid)
522 {
523 #ifdef LOSCFG_SECURITY_CAPABILITY
524 int ret;
525
526 if ((ruid == -1) && (euid == -1) && (suid == -1)) {
527 return 0;
528 }
529
530 ret = SetRealEffSaveUserIDCheck(ruid, euid, suid);
531 if (ret != 0) {
532 return ret;
533 }
534
535 if (ruid >= 0) {
536 if (((euid != -1) && (euid != ruid)) || ((suid != -1) && (suid != ruid))) {
537 return -EPERM;
538 }
539 return SysSetUserID(ruid);
540 } else if (euid >= 0) {
541 if ((suid != -1) && (suid != euid)) {
542 return -EPERM;
543 }
544 return SysSetUserID(euid);
545 } else {
546 return SysSetUserID(suid);
547 }
548 #else
549 if ((ruid != 0) || (euid != 0) || (suid != 0)) {
550 return -EPERM;
551 }
552 return 0;
553 #endif
554 }
555
SysSetRealEffUserID(int ruid,int euid)556 int SysSetRealEffUserID(int ruid, int euid)
557 {
558 #ifdef LOSCFG_SECURITY_CAPABILITY
559 return SysSetRealEffSaveUserID(ruid, euid, -1);
560 #else
561 if ((ruid != 0) || (euid != 0)) {
562 return -EPERM;
563 }
564 return 0;
565 #endif
566 }
567
SysSetGroupID(int gid)568 int SysSetGroupID(int gid)
569 {
570 #ifdef LOSCFG_SECURITY_CAPABILITY
571 int ret = -EPERM;
572 unsigned int intSave;
573 unsigned int count;
574 unsigned int oldGid;
575 User *user = NULL;
576
577 if (gid < 0) {
578 return -EINVAL;
579 }
580
581 SCHEDULER_LOCK(intSave);
582 user = OsCurrUserGet();
583 if (IsCapPermit(CAP_SETGID)) {
584 oldGid = user->gid;
585 user->gid = gid;
586 user->effGid = gid;
587 for (count = 0; count < user->groupNumber; count++) {
588 if (user->groups[count] == oldGid) {
589 user->groups[count] = gid;
590 ret = LOS_OK;
591 goto EXIT;
592 }
593 }
594 } else if (user->gid != gid) {
595 goto EXIT;
596 }
597
598 ret = LOS_OK;
599 /* add process to a user */
600 EXIT:
601 SCHEDULER_UNLOCK(intSave);
602 return ret;
603
604 #else
605 if (gid != 0) {
606 return -EPERM;
607 }
608
609 return 0;
610 #endif
611 }
612
SysGetRealEffSaveGroupID(int * rgid,int * egid,int * sgid)613 int SysGetRealEffSaveGroupID(int *rgid, int *egid, int *sgid)
614 {
615 int ret;
616 int realGroupID, effGroupID, saveGroupID;
617 #ifdef LOSCFG_SECURITY_CAPABILITY
618 unsigned int intSave;
619
620 SCHEDULER_LOCK(intSave);
621 realGroupID = OsCurrUserGet()->gid;
622 effGroupID = OsCurrUserGet()->effGid;
623 saveGroupID = OsCurrUserGet()->effGid;
624 SCHEDULER_UNLOCK(intSave);
625 #else
626 realGroupID = 0;
627 effGroupID = 0;
628 saveGroupID = 0;
629 #endif
630
631 ret = LOS_ArchCopyToUser(rgid, &realGroupID, sizeof(int));
632 if (ret != 0) {
633 return -EFAULT;
634 }
635
636 ret = LOS_ArchCopyToUser(egid, &effGroupID, sizeof(int));
637 if (ret != 0) {
638 return -EFAULT;
639 }
640
641 ret = LOS_ArchCopyToUser(sgid, &saveGroupID, sizeof(int));
642 if (ret != 0) {
643 return -EFAULT;
644 }
645
646 return 0;
647 }
648
649 #ifdef LOSCFG_SECURITY_CAPABILITY
SetRealEffSaveGroupIDCheck(int rgid,int egid,int sgid)650 static int SetRealEffSaveGroupIDCheck(int rgid, int egid, int sgid)
651 {
652 if ((rgid < 0) && (rgid != -1)) {
653 return -EINVAL;
654 }
655
656 if ((egid < 0) && (egid != -1)) {
657 return -EINVAL;
658 }
659
660 if ((sgid < 0) && (sgid != -1)) {
661 return -EINVAL;
662 }
663
664 return 0;
665 }
666 #endif
667
SysSetRealEffSaveGroupID(int rgid,int egid,int sgid)668 int SysSetRealEffSaveGroupID(int rgid, int egid, int sgid)
669 {
670 #ifdef LOSCFG_SECURITY_CAPABILITY
671 int ret;
672
673 if ((rgid == -1) && (egid == -1) && (sgid == -1)) {
674 return 0;
675 }
676
677 ret = SetRealEffSaveGroupIDCheck(rgid, egid, sgid);
678 if (ret != 0) {
679 return ret;
680 }
681
682 if (rgid >= 0) {
683 if (((egid != -1) && (egid != rgid)) || ((sgid != -1) && (sgid != rgid))) {
684 return -EPERM;
685 }
686 return SysSetGroupID(rgid);
687 } else if (egid >= 0) {
688 if ((sgid != -1) && (sgid != egid)) {
689 return -EPERM;
690 }
691 return SysSetGroupID(egid);
692 } else {
693 return SysSetGroupID(sgid);
694 }
695
696 #else
697 if ((rgid != 0) || (egid != 0) || (sgid != 0)) {
698 return -EPERM;
699 }
700 return 0;
701 #endif
702 }
703
SysSetRealEffGroupID(int rgid,int egid)704 int SysSetRealEffGroupID(int rgid, int egid)
705 {
706 #ifdef LOSCFG_SECURITY_CAPABILITY
707 return SysSetRealEffSaveGroupID(rgid, egid, -1);
708 #else
709 if ((rgid != 0) || (egid != 0)) {
710 return -EPERM;
711 }
712 return 0;
713 #endif
714 }
715
SysGetGroupID(void)716 int SysGetGroupID(void)
717 {
718 return LOS_GetGroupID();
719 }
720
721 #ifdef LOSCFG_SECURITY_CAPABILITY
SetGroups(int listSize,const int * safeList,int size)722 static int SetGroups(int listSize, const int *safeList, int size)
723 {
724 User *oldUser = NULL;
725 unsigned int intSave;
726
727 User *newUser = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + listSize * sizeof(int));
728 if (newUser == NULL) {
729 return -ENOMEM;
730 }
731
732 SCHEDULER_LOCK(intSave);
733 oldUser = OsCurrUserGet();
734 (VOID)memcpy_s(newUser, sizeof(User), oldUser, sizeof(User));
735 if (safeList != NULL) {
736 (VOID)memcpy_s(newUser->groups, size * sizeof(int), safeList, size * sizeof(int));
737 }
738 if (listSize == size) {
739 newUser->groups[listSize] = oldUser->gid;
740 }
741
742 newUser->groupNumber = listSize + 1;
743 OsCurrProcessGet()->user = newUser;
744 SCHEDULER_UNLOCK(intSave);
745
746 (void)LOS_MemFree(m_aucSysMem1, oldUser);
747 return 0;
748 }
749
GetGroups(int size,int list[])750 static int GetGroups(int size, int list[])
751 {
752 unsigned int intSave;
753 int groupCount;
754 int ret;
755 int *safeList = NULL;
756 unsigned int listSize;
757
758 SCHEDULER_LOCK(intSave);
759 groupCount = OsCurrUserGet()->groupNumber;
760 SCHEDULER_UNLOCK(intSave);
761
762 listSize = groupCount * sizeof(int);
763 if (size == 0) {
764 return groupCount;
765 } else if (list == NULL) {
766 return -EFAULT;
767 } else if (size < groupCount) {
768 return -EINVAL;
769 }
770
771 safeList = LOS_MemAlloc(m_aucSysMem1, listSize);
772 if (safeList == NULL) {
773 return -ENOMEM;
774 }
775
776 SCHEDULER_LOCK(intSave);
777 (void)memcpy_s(safeList, listSize, &OsCurrProcessGet()->user->groups[0], listSize);
778 SCHEDULER_UNLOCK(intSave);
779
780 ret = LOS_ArchCopyToUser(list, safeList, listSize);
781 if (ret != 0) {
782 groupCount = -EFAULT;
783 }
784
785 (void)LOS_MemFree(m_aucSysMem1, safeList);
786 return groupCount;
787 }
788 #endif
789
SysGetGroups(int size,int list[])790 int SysGetGroups(int size, int list[])
791 {
792 #ifdef LOSCFG_SECURITY_CAPABILITY
793 return GetGroups(size, list);
794 #else
795 int group = 0;
796 int groupCount = 1;
797 int ret;
798
799 if (size == 0) {
800 return groupCount;
801 } else if (list == NULL) {
802 return -EFAULT;
803 } else if (size < groupCount) {
804 return -EINVAL;
805 }
806
807 ret = LOS_ArchCopyToUser(list, &group, sizeof(int));
808 if (ret != 0) {
809 return -EFAULT;
810 }
811
812 return groupCount;
813 #endif
814 }
815
SysSetGroups(int size,const int list[])816 int SysSetGroups(int size, const int list[])
817 {
818 #ifdef LOSCFG_SECURITY_CAPABILITY
819 int ret;
820 int gid;
821 int listSize = size;
822 unsigned int count;
823 int *safeList = NULL;
824 #endif
825
826 if ((size != 0) && (list == NULL)) {
827 return -EFAULT;
828 }
829
830 if ((size < 0) || (size > OS_GROUPS_NUMBER_MAX)) {
831 return -EINVAL;
832 }
833
834 #ifdef LOSCFG_SECURITY_CAPABILITY
835 if (!IsCapPermit(CAP_SETGID)) {
836 return -EPERM;
837 }
838
839 if (size != 0) {
840 safeList = LOS_MemAlloc(m_aucSysMem1, size * sizeof(int));
841 if (safeList == NULL) {
842 return -ENOMEM;
843 }
844
845 ret = LOS_ArchCopyFromUser(safeList, list, size * sizeof(int));
846 if (ret != 0) {
847 ret = -EFAULT;
848 goto EXIT;
849 }
850 gid = OsCurrUserGet()->gid;
851 for (count = 0; count < size; count++) {
852 if (safeList[count] == gid) {
853 listSize = size - 1;
854 } else if (safeList[count] < 0) {
855 ret = -EINVAL;
856 goto EXIT;
857 }
858 }
859 }
860
861 ret = SetGroups(listSize, safeList, size);
862 EXIT:
863 if (safeList != NULL) {
864 (void)LOS_MemFree(m_aucSysMem1, safeList);
865 }
866
867 return ret;
868 #else
869 return 0;
870 #endif
871 }
872
SysCreateUserThread(const TSK_ENTRY_FUNC func,const UserTaskParam * userParam,bool joinable)873 unsigned int SysCreateUserThread(const TSK_ENTRY_FUNC func, const UserTaskParam *userParam, bool joinable)
874 {
875 TSK_INIT_PARAM_S param = { 0 };
876 int ret;
877
878 ret = LOS_ArchCopyFromUser(&(param.userParam), userParam, sizeof(UserTaskParam));
879 if (ret != 0) {
880 return OS_INVALID_VALUE;
881 }
882
883 param.pfnTaskEntry = func;
884 if (joinable == TRUE) {
885 param.uwResved = LOS_TASK_ATTR_JOINABLE;
886 } else {
887 param.uwResved = LOS_TASK_STATUS_DETACHED;
888 }
889
890 return OsCreateUserTask(OS_INVALID_VALUE, ¶m);
891 }
892
SysSetThreadArea(const char * area)893 int SysSetThreadArea(const char *area)
894 {
895 unsigned int intSave;
896 int ret = LOS_OK;
897
898 if (!LOS_IsUserAddress((unsigned long)(uintptr_t)area)) {
899 return EINVAL;
900 }
901
902 LosTaskCB *taskCB = OsCurrTaskGet();
903 SCHEDULER_LOCK(intSave);
904 LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);
905 if (processCB->processMode != OS_USER_MODE) {
906 ret = EPERM;
907 goto OUT;
908 }
909
910 taskCB->userArea = (unsigned long)(uintptr_t)area;
911 OUT:
912 SCHEDULER_UNLOCK(intSave);
913 return ret;
914 }
915
SysGetThreadArea(void)916 char *SysGetThreadArea(void)
917 {
918 return (char *)(OsCurrTaskGet()->userArea);
919 }
920
SysUserThreadSetDetach(unsigned int taskID)921 int SysUserThreadSetDetach(unsigned int taskID)
922 {
923 unsigned int intSave;
924 int ret;
925
926 if (OS_TID_CHECK_INVALID(taskID)) {
927 return EINVAL;
928 }
929
930 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
931 SCHEDULER_LOCK(intSave);
932 ret = OsUserTaskOperatePermissionsCheck(taskCB);
933 if (ret != LOS_OK) {
934 goto EXIT;
935 }
936
937 ret = (int)OsTaskSetDetachUnsafe(taskCB);
938
939 EXIT:
940 SCHEDULER_UNLOCK(intSave);
941 return ret;
942 }
943
SysUserThreadDetach(unsigned int taskID)944 int SysUserThreadDetach(unsigned int taskID)
945 {
946 unsigned int intSave;
947 int ret;
948
949 if (OS_TID_CHECK_INVALID(taskID)) {
950 return EINVAL;
951 }
952
953 SCHEDULER_LOCK(intSave);
954 ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
955 SCHEDULER_UNLOCK(intSave);
956 if (ret != LOS_OK) {
957 return ret;
958 }
959
960 if (LOS_TaskDelete(taskID) != LOS_OK) {
961 return ESRCH;
962 }
963
964 return LOS_OK;
965 }
966
SysThreadJoin(unsigned int taskID)967 int SysThreadJoin(unsigned int taskID)
968 {
969 unsigned int intSave;
970 int ret;
971
972 if (OS_TID_CHECK_INVALID(taskID)) {
973 return EINVAL;
974 }
975
976 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
977 SCHEDULER_LOCK(intSave);
978 ret = OsUserTaskOperatePermissionsCheck(taskCB);
979 if (ret != LOS_OK) {
980 goto EXIT;
981 }
982
983 ret = (int)OsTaskJoinPendUnsafe(OS_TCB_FROM_TID(taskID));
984
985 EXIT:
986 SCHEDULER_UNLOCK(intSave);
987 return ret;
988 }
989
SysUserExitGroup(int status)990 void SysUserExitGroup(int status)
991 {
992 (void)status;
993 OsProcessThreadGroupDestroy();
994 }
995
SysThreadExit(int status)996 void SysThreadExit(int status)
997 {
998 OsRunningTaskToExit(OsCurrTaskGet(), (unsigned int)status);
999 }
1000
SysFutex(const unsigned int * uAddr,unsigned int flags,int val,unsigned int absTime,const unsigned int * newUserAddr)1001 int SysFutex(const unsigned int *uAddr, unsigned int flags, int val,
1002 unsigned int absTime, const unsigned int *newUserAddr)
1003 {
1004 if ((flags & FUTEX_MASK) == FUTEX_REQUEUE) {
1005 return -OsFutexRequeue(uAddr, flags, val, absTime, newUserAddr);
1006 }
1007
1008 if ((flags & FUTEX_MASK) == FUTEX_WAKE) {
1009 return -OsFutexWake(uAddr, flags, val);
1010 }
1011
1012 return -OsFutexWait(uAddr, flags, val, absTime);
1013 }
1014
SysGetTid(void)1015 unsigned int SysGetTid(void)
1016 {
1017 return OsCurrTaskGet()->taskID;
1018 }
1019
1020 /* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */
SchedAffinityParameterPreprocess(int id,int flag,unsigned int * taskID,unsigned int * processID)1021 static int SchedAffinityParameterPreprocess(int id, int flag, unsigned int *taskID, unsigned int *processID)
1022 {
1023 if (flag >= 0) {
1024 if (OS_PID_CHECK_INVALID(id)) {
1025 return -ESRCH;
1026 }
1027 *taskID = (id == 0) ? (OsCurrTaskGet()->taskID) : (OS_PCB_FROM_PID((UINT32)id)->threadGroupID);
1028 *processID = (id == 0) ? (OS_TCB_FROM_TID(*taskID)->processID) : id;
1029 } else {
1030 if (OS_TID_CHECK_INVALID(id)) {
1031 return -ESRCH;
1032 }
1033 *taskID = id;
1034 *processID = OS_INVALID_VALUE;
1035 }
1036 return LOS_OK;
1037 }
1038
1039 /* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */
SysSchedGetAffinity(int id,unsigned int * cpuset,int flag)1040 int SysSchedGetAffinity(int id, unsigned int *cpuset, int flag)
1041 {
1042 int ret;
1043 unsigned int processID;
1044 unsigned int taskID;
1045 unsigned int intSave;
1046 unsigned int cpuAffiMask;
1047
1048 ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID);
1049 if (ret != LOS_OK) {
1050 return ret;
1051 }
1052
1053 SCHEDULER_LOCK(intSave);
1054 if (flag >= 0) {
1055 if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) {
1056 SCHEDULER_UNLOCK(intSave);
1057 return -ESRCH;
1058 }
1059 } else {
1060 ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
1061 if (ret != LOS_OK) {
1062 SCHEDULER_UNLOCK(intSave);
1063 if (ret == EINVAL) {
1064 return -ESRCH;
1065 }
1066 return -ret;
1067 }
1068 }
1069
1070 #ifdef LOSCFG_KERNEL_SMP
1071 cpuAffiMask = (unsigned int)OS_TCB_FROM_TID(taskID)->cpuAffiMask;
1072 #else
1073 cpuAffiMask = 1;
1074 #endif /* LOSCFG_KERNEL_SMP */
1075
1076 SCHEDULER_UNLOCK(intSave);
1077 ret = LOS_ArchCopyToUser(cpuset, &cpuAffiMask, sizeof(unsigned int));
1078 if (ret != LOS_OK) {
1079 return -EFAULT;
1080 }
1081
1082 return LOS_OK;
1083 }
1084
1085 /* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */
SysSchedSetAffinity(int id,const unsigned short cpuset,int flag)1086 int SysSchedSetAffinity(int id, const unsigned short cpuset, int flag)
1087 {
1088 int ret;
1089 unsigned int processID;
1090 unsigned int taskID;
1091 unsigned int intSave;
1092 unsigned short currCpuMask;
1093 bool needSched = FALSE;
1094
1095 if (cpuset > LOSCFG_KERNEL_CPU_MASK) {
1096 return -EINVAL;
1097 }
1098
1099 ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID);
1100 if (ret != LOS_OK) {
1101 return ret;
1102 }
1103
1104 if (flag >= 0) {
1105 ret = OsPermissionToCheck(processID, LOS_GetCurrProcessID());
1106 if (ret != LOS_OK) {
1107 return ret;
1108 }
1109 SCHEDULER_LOCK(intSave);
1110 if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) {
1111 SCHEDULER_UNLOCK(intSave);
1112 return -ESRCH;
1113 }
1114 } else {
1115 SCHEDULER_LOCK(intSave);
1116 ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
1117 if (ret != LOS_OK) {
1118 SCHEDULER_UNLOCK(intSave);
1119 if (ret == EINVAL) {
1120 return -ESRCH;
1121 }
1122 return -ret;
1123 }
1124 }
1125
1126 needSched = OsTaskCpuAffiSetUnsafe(taskID, cpuset, &currCpuMask);
1127 SCHEDULER_UNLOCK(intSave);
1128 if (needSched && OS_SCHEDULER_ACTIVE) {
1129 LOS_MpSchedule(currCpuMask);
1130 LOS_Schedule();
1131 }
1132
1133 return LOS_OK;
1134 }
1135
1136