• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param);
90     param.policy = (policyFlag == true) ? policy : param.policy;
91     param.priority = priority;
92     needSched = taskCB->ops->schedParamModify(taskCB, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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