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