• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param);
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