• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2023 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     uintptr_t pgroupID = 0;
49     unsigned int ret = OsGetProcessGroupCB(pid, &pgroupID);
50     if (ret != 0) {
51         return -ret;
52     } else if (pgroupID == OS_KERNEL_PROCESS_GROUP) {
53         return -EPERM;
54     } else if ((pgroupID == OS_USER_PRIVILEGE_PROCESS_GROUP) && (pid != who)) {
55         return -EPERM;
56     } else if ((UINTPTR)OS_PCB_FROM_PID(pid) == OS_USER_PRIVILEGE_PROCESS_GROUP) {
57         return -EPERM;
58     }
59 
60     return 0;
61 }
62 
UserTaskSchedulerCheck(unsigned int tid,int policy,const LosSchedParam * schedParam,bool policyFlag)63 static int UserTaskSchedulerCheck(unsigned int tid, int policy, const LosSchedParam *schedParam, bool policyFlag)
64 {
65     int ret;
66     int processPolicy;
67 
68     if (OS_TID_CHECK_INVALID(tid)) {
69         return EINVAL;
70     }
71 
72     ret = OsSchedulerParamCheck(policy, TRUE, schedParam);
73     if (ret != 0) {
74         return ret;
75     }
76 
77     if (policyFlag) {
78         ret = LOS_GetProcessScheduler(LOS_GetCurrProcessID(), &processPolicy, NULL);
79         if (ret < 0) {
80             return -ret;
81         }
82         if ((processPolicy != LOS_SCHED_DEADLINE) && (policy == LOS_SCHED_DEADLINE)) {
83             return EPERM;
84         } else if ((processPolicy == LOS_SCHED_DEADLINE) && (policy != LOS_SCHED_DEADLINE)) {
85             return EPERM;
86         }
87     }
88     return 0;
89 }
90 
OsUserTaskSchedulerSet(unsigned int tid,int policy,const LosSchedParam * schedParam,bool policyFlag)91 static int OsUserTaskSchedulerSet(unsigned int tid, int policy, const LosSchedParam *schedParam, bool policyFlag)
92 {
93     int ret;
94     unsigned int intSave;
95     bool needSched = false;
96     SchedParam param = { 0 };
97 
98     ret = UserTaskSchedulerCheck(tid, policy, schedParam, policyFlag);
99     if (ret != 0) {
100         return ret;
101     }
102 
103     LosTaskCB *taskCB = OS_TCB_FROM_TID(tid);
104     SCHEDULER_LOCK(intSave);
105     ret = OsUserTaskOperatePermissionsCheck(taskCB);
106     if (ret != LOS_OK) {
107         SCHEDULER_UNLOCK(intSave);
108         return ret;
109     }
110 
111     taskCB->ops->schedParamGet(taskCB, &param);
112     param.policy = (policyFlag == true) ? (UINT16)policy : param.policy;
113     if ((param.policy == LOS_SCHED_RR) || (param.policy == LOS_SCHED_FIFO)) {
114         param.priority = schedParam->priority;
115     } else if (param.policy == LOS_SCHED_DEADLINE) {
116 #ifdef LOSCFG_SECURITY_CAPABILITY
117         /* user mode process with privilege of CAP_SCHED_SETPRIORITY can change the priority */
118         if (!IsCapPermit(CAP_SCHED_SETPRIORITY)) {
119             SCHEDULER_UNLOCK(intSave);
120             return EPERM;
121         }
122 #endif
123         param.runTimeUs = schedParam->runTimeUs;
124         param.deadlineUs = schedParam->deadlineUs;
125         param.periodUs = schedParam->periodUs;
126     }
127 
128     needSched = taskCB->ops->schedParamModify(taskCB, &param);
129     SCHEDULER_UNLOCK(intSave);
130 
131     LOS_MpSchedule(OS_MP_CPU_ALL);
132     if (needSched && OS_SCHEDULER_ACTIVE) {
133         LOS_Schedule();
134     }
135 
136     return LOS_OK;
137 }
138 
SysSchedYield(int type)139 void SysSchedYield(int type)
140 {
141     (void)type;
142 
143     (void)LOS_TaskYield();
144     return;
145 }
146 
SysSchedGetScheduler(int id,int flag)147 int SysSchedGetScheduler(int id, int flag)
148 {
149     unsigned int intSave;
150     SchedParam param = { 0 };
151     int policy;
152     int ret;
153 
154     if (flag < 0) {
155         if (OS_TID_CHECK_INVALID(id)) {
156             return -EINVAL;
157         }
158 
159         LosTaskCB *taskCB = OS_TCB_FROM_TID(id);
160         SCHEDULER_LOCK(intSave);
161         ret = OsUserTaskOperatePermissionsCheck(taskCB);
162         if (ret != LOS_OK) {
163             SCHEDULER_UNLOCK(intSave);
164             return -ret;
165         }
166 
167         taskCB->ops->schedParamGet(taskCB, &param);
168         SCHEDULER_UNLOCK(intSave);
169         return (int)param.policy;
170     }
171 
172     if (id == 0) {
173         id = (int)LOS_GetCurrProcessID();
174     }
175 
176     ret = LOS_GetProcessScheduler(id, &policy, NULL);
177     if (ret < 0) {
178         return ret;
179     }
180 
181     return policy;
182 }
183 
SysSchedSetScheduler(int id,int policy,const LosSchedParam * userParam,int flag)184 int SysSchedSetScheduler(int id, int policy, const LosSchedParam *userParam, int flag)
185 {
186     int ret;
187     LosSchedParam param;
188 
189     if (LOS_ArchCopyFromUser(&param, userParam, sizeof(LosSchedParam)) != 0) {
190         return -EFAULT;
191     }
192 
193     if (flag < 0) {
194         return -OsUserTaskSchedulerSet(id, policy, &param, true);
195     }
196 
197     if (policy == LOS_SCHED_RR) {
198 #ifdef LOSCFG_KERNEL_PLIMITS
199         if (param.priority < OsPidLimitGetPriorityLimit()) {
200             return -EINVAL;
201         }
202 #else
203         if (param.priority < OS_USER_PROCESS_PRIORITY_HIGHEST) {
204             return -EINVAL;
205         }
206 #endif
207     }
208 
209     if (id == 0) {
210         id = (int)LOS_GetCurrProcessID();
211     }
212 
213     ret = OsPermissionToCheck(id, LOS_GetCurrProcessID());
214     if (ret < 0) {
215         return ret;
216     }
217 
218     return OsSetProcessScheduler(LOS_PRIO_PROCESS, id, policy, &param);
219 }
220 
SysSchedGetParam(int id,LosSchedParam * userParam,int flag)221 int SysSchedGetParam(int id, LosSchedParam *userParam, int flag)
222 {
223     LosSchedParam schedParam = {0};
224     SchedParam param = { 0 };
225     unsigned int intSave;
226     int ret;
227 
228     if (flag < 0) {
229         if (OS_TID_CHECK_INVALID(id)) {
230             return -EINVAL;
231         }
232 
233         LosTaskCB *taskCB = OS_TCB_FROM_TID(id);
234         SCHEDULER_LOCK(intSave);
235         ret = OsUserTaskOperatePermissionsCheck(taskCB);
236         if (ret != LOS_OK) {
237             SCHEDULER_UNLOCK(intSave);
238             return -ret;
239         }
240 
241         taskCB->ops->schedParamGet(taskCB, &param);
242         SCHEDULER_UNLOCK(intSave);
243         if (param.policy == LOS_SCHED_DEADLINE) {
244             schedParam.runTimeUs = param.runTimeUs;
245             schedParam.deadlineUs = param.deadlineUs;
246             schedParam.periodUs = param.periodUs;
247         } else {
248             schedParam.priority = param.priority;
249         }
250     } else {
251         if (id == 0) {
252             id = (int)LOS_GetCurrProcessID();
253         }
254 
255         if (OS_PID_CHECK_INVALID(id)) {
256             return -EINVAL;
257         }
258 
259         ret = LOS_GetProcessScheduler(id, NULL, &schedParam);
260         if (ret < 0) {
261             return ret;
262         }
263     }
264 
265     if (LOS_ArchCopyToUser(userParam, &schedParam, sizeof(LosSchedParam))) {
266         return -EFAULT;
267     }
268     return 0;
269 }
270 
SysSetProcessPriority(int which,int who,int prio)271 int SysSetProcessPriority(int which, int who, int prio)
272 {
273     int ret;
274 
275     if (which != LOS_PRIO_PROCESS) {
276         return -EINVAL;
277     }
278 
279     if (who == 0) {
280         who = (int)LOS_GetCurrProcessID();
281     }
282 
283 #ifdef LOSCFG_KERNEL_PLIMITS
284     if (prio < OsPidLimitGetPriorityLimit()) {
285         return -EINVAL;
286     }
287 #else
288     if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) {
289         return -EINVAL;
290     }
291 #endif
292 
293     ret = OsPermissionToCheck(who, LOS_GetCurrProcessID());
294     if (ret < 0) {
295         return ret;
296     }
297 
298     return LOS_SetProcessPriority(who, prio);
299 }
300 
SysSchedSetParam(int id,const LosSchedParam * userParam,int flag)301 int SysSchedSetParam(int id, const LosSchedParam *userParam, int flag)
302 {
303     int ret, policy;
304     LosSchedParam param;
305 
306     if (flag < 0) {
307         if (LOS_ArchCopyFromUser(&param, userParam, sizeof(LosSchedParam)) != 0) {
308             return -EFAULT;
309         }
310         return -OsUserTaskSchedulerSet(id, LOS_SCHED_RR, &param, false);
311     }
312 
313     if (id == 0) {
314         id = (int)LOS_GetCurrProcessID();
315     }
316 
317     ret = LOS_GetProcessScheduler(id, &policy, NULL);
318     if (ret < 0) {
319         return ret;
320     }
321 
322     return SysSchedSetScheduler(id, policy, userParam, flag);
323 }
324 
SysGetProcessPriority(int which,int who)325 int SysGetProcessPriority(int which, int who)
326 {
327     if (who == 0) {
328         who = (int)LOS_GetCurrProcessID();
329     }
330 
331     return OsGetProcessPriority(which, who);
332 }
333 
SysSchedGetPriorityMin(int policy)334 int SysSchedGetPriorityMin(int policy)
335 {
336     if (policy != LOS_SCHED_RR) {
337         return -EINVAL;
338     }
339 
340     return OS_USER_PROCESS_PRIORITY_HIGHEST;
341 }
342 
SysSchedGetPriorityMax(int policy)343 int SysSchedGetPriorityMax(int policy)
344 {
345     if (policy != LOS_SCHED_RR) {
346         return -EINVAL;
347     }
348 
349     return OS_USER_PROCESS_PRIORITY_LOWEST;
350 }
351 
SysSchedRRGetInterval(int pid,struct timespec * tp)352 int SysSchedRRGetInterval(int pid, struct timespec *tp)
353 {
354     unsigned int intSave;
355     int ret;
356     SchedParam param = { 0 };
357     time_t timeSlice = 0;
358     struct timespec tv = { 0 };
359     LosTaskCB *taskCB = NULL;
360     LosProcessCB *processCB = NULL;
361 
362     if (tp == NULL) {
363         return -EINVAL;
364     }
365 
366     if (OS_PID_CHECK_INVALID(pid)) {
367         return -EINVAL;
368     }
369 
370     if (pid == 0) {
371         processCB = OsCurrProcessGet();
372     } else {
373         processCB = OS_PCB_FROM_PID(pid);
374     }
375 
376     SCHEDULER_LOCK(intSave);
377     /* if can not find process by pid return ESRCH */
378     if (OsProcessIsInactive(processCB)) {
379         SCHEDULER_UNLOCK(intSave);
380         return -ESRCH;
381     }
382 
383     LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) {
384         if (!OsTaskIsInactive(taskCB)) {
385             taskCB->ops->schedParamGet(taskCB, &param);
386             if (param.policy == LOS_SCHED_RR) {
387                 timeSlice += param.timeSlice;
388             }
389         }
390     }
391 
392     SCHEDULER_UNLOCK(intSave);
393 
394     timeSlice = timeSlice * OS_NS_PER_CYCLE;
395     tv.tv_sec = timeSlice / OS_SYS_NS_PER_SECOND;
396     tv.tv_nsec = timeSlice % OS_SYS_NS_PER_SECOND;
397     ret = LOS_ArchCopyToUser(tp, &tv, sizeof(struct timespec));
398     if (ret != 0) {
399         return -EFAULT;
400     }
401 
402     return 0;
403 }
404 
SysWait(int pid,USER int * status,int options,void * rusage)405 int SysWait(int pid, USER int *status, int options, void *rusage)
406 {
407     (void)rusage;
408 
409     return LOS_Wait(pid, status, (unsigned int)options, NULL);
410 }
411 
SysWaitid(idtype_t type,int pid,USER siginfo_t * info,int options,void * rusage)412 int SysWaitid(idtype_t type, int pid, USER siginfo_t *info, int options, void *rusage)
413 {
414     (void)rusage;
415     int ret;
416     int truepid = 0;
417 
418     switch (type) {
419         case P_ALL:
420             /* Wait for any child; id is ignored. */
421             truepid = -1;
422             break;
423         case P_PID:
424             /* Wait for the child whose process ID matches id */
425             if (pid <= 0) {
426                 return -EINVAL;
427             }
428             truepid = pid;
429             break;
430         case P_PGID:
431             /* Wait for any child whose process group ID matches id */
432             if (pid <= 1) {
433                 return -EINVAL;
434             }
435             truepid = -pid;
436             break;
437         default:
438             return -EINVAL;
439     }
440 
441     ret = LOS_Waitid(truepid, info, (unsigned int)options, NULL);
442     if (ret > 0) {
443         ret = 0;
444     }
445     return ret;
446 }
447 
SysFork(void)448 int SysFork(void)
449 {
450     return OsClone(0, 0, 0);
451 }
452 
SysVfork(void)453 int SysVfork(void)
454 {
455     return OsClone(CLONE_VFORK, 0, 0);
456 }
457 
SysClone(int flags,void * stack,int * parentTid,unsigned long tls,int * childTid)458 int SysClone(int flags, void *stack, int *parentTid, unsigned long tls, int *childTid)
459 {
460     (void)parentTid;
461     (void)tls;
462     (void)childTid;
463 
464     return OsClone((UINT32)flags, (UINTPTR)stack, 0);
465 }
466 
SysUnshare(int flags)467 int SysUnshare(int flags)
468 {
469 #ifdef LOSCFG_KERNEL_CONTAINER
470     return OsUnshare(flags);
471 #else
472     return -ENOSYS;
473 #endif
474 }
475 
SysSetns(int fd,int type)476 int SysSetns(int fd, int type)
477 {
478 #ifdef LOSCFG_KERNEL_CONTAINER
479     return OsSetNs(fd, type);
480 #else
481     return -ENOSYS;
482 #endif
483 }
484 
SysGetPPID(void)485 unsigned int SysGetPPID(void)
486 {
487 #ifdef LOSCFG_PID_CONTAINER
488     if (OsCurrProcessGet()->processID == OS_USER_ROOT_PROCESS_ID) {
489         return 0;
490     }
491 #endif
492     return OsCurrProcessGet()->parentProcess->processID;
493 }
494 
SysGetPID(void)495 unsigned int SysGetPID(void)
496 {
497     return LOS_GetCurrProcessID();
498 }
499 
SysSetProcessGroupID(unsigned int pid,unsigned int gid)500 int SysSetProcessGroupID(unsigned int pid, unsigned int gid)
501 {
502     int ret;
503 
504     if (pid == 0) {
505         pid = LOS_GetCurrProcessID();
506     }
507 
508     if (gid == 0) {
509         gid = pid;
510     }
511 
512     ret = OsPermissionToCheck(pid, gid);
513     if (ret < 0) {
514         return ret;
515     }
516 
517     return OsSetProcessGroupID(pid, gid);
518 }
519 
SysGetProcessGroupID(unsigned int pid)520 int SysGetProcessGroupID(unsigned int pid)
521 {
522     if (pid == 0) {
523         pid = LOS_GetCurrProcessID();
524     }
525 
526     return LOS_GetProcessGroupID(pid);
527 }
528 
SysGetCurrProcessGroupID(void)529 int SysGetCurrProcessGroupID(void)
530 {
531     return LOS_GetCurrProcessGroupID();
532 }
533 
SysGetUserID(void)534 int SysGetUserID(void)
535 {
536     return LOS_GetUserID();
537 }
538 
SysGetEffUserID(void)539 int SysGetEffUserID(void)
540 {
541 #ifdef LOSCFG_SECURITY_CAPABILITY
542     UINT32 intSave;
543     int euid;
544 
545     SCHEDULER_LOCK(intSave);
546 #ifdef LOSCFG_USER_CONTAINER
547     euid = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid);
548 #else
549     euid = (int)OsCurrUserGet()->effUserID;
550 #endif
551     SCHEDULER_UNLOCK(intSave);
552     return euid;
553 #else
554     return 0;
555 #endif
556 }
557 
SysGetEffGID(void)558 int SysGetEffGID(void)
559 {
560 #ifdef LOSCFG_SECURITY_CAPABILITY
561     UINT32 intSave;
562     int egid;
563 
564     SCHEDULER_LOCK(intSave);
565 #ifdef LOSCFG_USER_CONTAINER
566     egid = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid);
567 #else
568     egid = (int)OsCurrUserGet()->effGid;
569 #endif
570     SCHEDULER_UNLOCK(intSave);
571     return egid;
572 #else
573     return 0;
574 #endif
575 }
576 
SysGetRealEffSaveUserID(int * ruid,int * euid,int * suid)577 int SysGetRealEffSaveUserID(int *ruid, int *euid, int *suid)
578 {
579     int ret;
580     int realUserID, effUserID, saveUserID;
581 #ifdef LOSCFG_SECURITY_CAPABILITY
582     unsigned int intSave;
583 
584     SCHEDULER_LOCK(intSave);
585 #ifdef LOSCFG_USER_CONTAINER
586     realUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->uid);
587     effUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid);
588     saveUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid);
589 #else
590     realUserID = OsCurrUserGet()->userID;
591     effUserID = OsCurrUserGet()->effUserID;
592     saveUserID = OsCurrUserGet()->effUserID;
593 #endif
594     SCHEDULER_UNLOCK(intSave);
595 #else
596     realUserID = 0;
597     effUserID = 0;
598     saveUserID = 0;
599 #endif
600 
601     ret = LOS_ArchCopyToUser(ruid, &realUserID, sizeof(int));
602     if (ret != 0) {
603         return -EFAULT;
604     }
605 
606     ret = LOS_ArchCopyToUser(euid, &effUserID, sizeof(int));
607     if (ret != 0) {
608         return -EFAULT;
609     }
610 
611     ret = LOS_ArchCopyToUser(suid, &saveUserID, sizeof(int));
612     if (ret != 0) {
613         return -EFAULT;
614     }
615 
616     return 0;
617 }
618 
619 #ifdef LOSCFG_USER_CONTAINER
SysSetUserID(int uid)620 long SysSetUserID(int uid)
621 {
622 #ifdef LOSCFG_SECURITY_CAPABILITY
623     UserContainer *userContainer = CurrentCredentials()->userContainer;
624     int retval = -EPERM;
625     unsigned int intSave;
626 
627     if (uid < 0) {
628         return -EINVAL;
629     }
630 
631     UINT32 kuid = OsMakeKuid(userContainer, uid);
632     if (kuid == (UINT32)-1) {
633         return -EINVAL;
634     }
635 
636     Credentials *newCredentials = PrepareCredential(OsCurrProcessGet());
637     if (newCredentials == NULL) {
638         return -ENOMEM;
639     }
640 
641     Credentials *oldCredentials = CurrentCredentials();
642 
643     SCHEDULER_LOCK(intSave);
644     User *user = OsCurrUserGet();
645     if (IsCapPermit(CAP_SETUID)) {
646         newCredentials->uid = kuid;
647         if (kuid != oldCredentials->uid) {
648             user->userID = kuid;
649             user->effUserID = kuid;
650         }
651         retval = LOS_OK;
652     } else if (kuid != oldCredentials->uid) {
653         goto ERROR;
654     }
655     newCredentials->euid = kuid;
656 
657     retval = CommitCredentials(newCredentials);
658     SCHEDULER_UNLOCK(intSave);
659     return retval;
660 
661 ERROR:
662     FreeCredential(newCredentials);
663     SCHEDULER_UNLOCK(intSave);
664     return retval;
665 #else
666     if (uid != 0) {
667         return -EPERM;
668     }
669     return 0;
670 #endif
671 }
672 
673 #else
674 
SysSetUserID(int uid)675 int SysSetUserID(int uid)
676 {
677 #ifdef LOSCFG_SECURITY_CAPABILITY
678     int ret = -EPERM;
679     unsigned int intSave;
680 
681     if (uid < 0) {
682         return -EINVAL;
683     }
684 
685     SCHEDULER_LOCK(intSave);
686     User *user = OsCurrUserGet();
687     if (IsCapPermit(CAP_SETUID)) {
688         user->userID = uid;
689         user->effUserID = uid;
690         /* add process to a user */
691     } else if (user->userID != uid) {
692         goto EXIT;
693     }
694 
695     ret = LOS_OK;
696     /* add process to a user */
697 EXIT:
698     SCHEDULER_UNLOCK(intSave);
699     return ret;
700 #else
701     if (uid != 0) {
702         return -EPERM;
703     }
704 
705     return 0;
706 #endif
707 }
708 #endif
709 
710 #ifdef LOSCFG_SECURITY_CAPABILITY
SetRealEffSaveUserIDCheck(int ruid,int euid,int suid)711 static int SetRealEffSaveUserIDCheck(int ruid, int euid, int suid)
712 {
713     if ((ruid < 0) && (ruid != -1)) {
714         return -EINVAL;
715     }
716 
717     if ((euid < 0) && (euid != -1)) {
718         return -EINVAL;
719     }
720 
721     if ((suid < 0) && (suid != -1)) {
722         return -EINVAL;
723     }
724 
725     return 0;
726 }
727 #endif
728 
SysSetRealEffSaveUserID(int ruid,int euid,int suid)729 int SysSetRealEffSaveUserID(int ruid, int euid, int suid)
730 {
731 #ifdef LOSCFG_SECURITY_CAPABILITY
732     int ret;
733 
734     if ((ruid == -1) && (euid == -1) && (suid == -1)) {
735         return 0;
736     }
737 
738     ret = SetRealEffSaveUserIDCheck(ruid, euid, suid);
739     if (ret != 0) {
740         return ret;
741     }
742 
743     if (ruid >= 0) {
744         if (((euid != -1) && (euid != ruid)) || ((suid != -1) && (suid != ruid))) {
745             return -EPERM;
746         }
747         return SysSetUserID(ruid);
748     } else if (euid >= 0) {
749         if ((suid != -1) && (suid != euid)) {
750             return -EPERM;
751         }
752         return SysSetUserID(euid);
753     } else {
754         return SysSetUserID(suid);
755     }
756 #else
757     if ((ruid != 0) || (euid != 0) || (suid != 0)) {
758         return -EPERM;
759     }
760     return 0;
761 #endif
762 }
763 
SysSetRealEffUserID(int ruid,int euid)764 int SysSetRealEffUserID(int ruid, int euid)
765 {
766 #ifdef LOSCFG_SECURITY_CAPABILITY
767     return SysSetRealEffSaveUserID(ruid, euid, -1);
768 #else
769     if ((ruid != 0) || (euid != 0)) {
770         return -EPERM;
771     }
772     return 0;
773 #endif
774 }
775 
776 #ifdef LOSCFG_USER_CONTAINER
SysSetGroupID(int gid)777 int SysSetGroupID(int gid)
778 {
779 #ifdef LOSCFG_SECURITY_CAPABILITY
780     UserContainer *userContainer = CurrentCredentials()->userContainer;
781     int retval = -EPERM;
782     unsigned int oldGid;
783     unsigned int intSave;
784     int count;
785 
786     if (gid < 0) {
787         return -EINVAL;
788     }
789 
790     unsigned int kgid = OsMakeKgid(userContainer, gid);
791     if (kgid == (UINT32)-1) {
792         return -EINVAL;
793     }
794 
795     Credentials *newCredentials = PrepareCredential(OsCurrProcessGet());
796     if (newCredentials == NULL) {
797         return -ENOMEM;
798     }
799 
800     SCHEDULER_LOCK(intSave);
801     User *user = OsCurrUserGet();
802     if (IsCapPermit(CAP_SETGID)) {
803         newCredentials->gid = kgid;
804         newCredentials->egid = kgid;
805         oldGid = user->gid;
806         user->gid = kgid;
807         user->effGid = kgid;
808         for (count = 0; count < user->groupNumber; count++) {
809             if (user->groups[count] == oldGid) {
810                 user->groups[count] = kgid;
811                 retval = LOS_OK;
812                 break;
813             }
814         }
815     } else if (user->gid != kgid) {
816         goto ERROR;
817     }
818 
819     retval = CommitCredentials(newCredentials);
820     SCHEDULER_UNLOCK(intSave);
821     return retval;
822 
823 ERROR:
824     FreeCredential(newCredentials);
825     SCHEDULER_UNLOCK(intSave);
826     return retval;
827 
828 #else
829     if (gid != 0) {
830         return -EPERM;
831     }
832     return 0;
833 #endif
834 }
835 #else
SysSetGroupID(int gid)836 int SysSetGroupID(int gid)
837 {
838 #ifdef LOSCFG_SECURITY_CAPABILITY
839     int ret = -EPERM;
840     unsigned int intSave;
841     unsigned int count;
842     unsigned int oldGid;
843     User *user = NULL;
844 
845     if (gid < 0) {
846         return -EINVAL;
847     }
848 
849     SCHEDULER_LOCK(intSave);
850     user = OsCurrUserGet();
851     if (IsCapPermit(CAP_SETGID)) {
852         oldGid = user->gid;
853         user->gid = gid;
854         user->effGid = gid;
855         for (count = 0; count < user->groupNumber; count++) {
856             if (user->groups[count] == oldGid) {
857                 user->groups[count] = gid;
858                 ret = LOS_OK;
859                 goto EXIT;
860             }
861         }
862     } else if (user->gid != gid) {
863         goto EXIT;
864     }
865 
866     ret = LOS_OK;
867     /* add process to a user */
868 EXIT:
869     SCHEDULER_UNLOCK(intSave);
870     return ret;
871 
872 #else
873     if (gid != 0) {
874         return -EPERM;
875     }
876 
877     return 0;
878 #endif
879 }
880 #endif
881 
SysGetRealEffSaveGroupID(int * rgid,int * egid,int * sgid)882 int SysGetRealEffSaveGroupID(int *rgid, int *egid, int *sgid)
883 {
884     int ret;
885     int realGroupID, effGroupID, saveGroupID;
886 #ifdef LOSCFG_SECURITY_CAPABILITY
887     unsigned int intSave;
888 
889     SCHEDULER_LOCK(intSave);
890 #ifdef LOSCFG_USER_CONTAINER
891     realGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->gid);
892     effGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid);
893     saveGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid);
894 #else
895     realGroupID = OsCurrUserGet()->gid;
896     effGroupID = OsCurrUserGet()->effGid;
897     saveGroupID = OsCurrUserGet()->effGid;
898 #endif
899     SCHEDULER_UNLOCK(intSave);
900 #else
901     realGroupID = 0;
902     effGroupID = 0;
903     saveGroupID = 0;
904 #endif
905 
906     ret = LOS_ArchCopyToUser(rgid, &realGroupID, sizeof(int));
907     if (ret != 0) {
908         return -EFAULT;
909     }
910 
911     ret = LOS_ArchCopyToUser(egid, &effGroupID, sizeof(int));
912     if (ret != 0) {
913         return -EFAULT;
914     }
915 
916     ret = LOS_ArchCopyToUser(sgid, &saveGroupID, sizeof(int));
917     if (ret != 0) {
918         return -EFAULT;
919     }
920 
921     return 0;
922 }
923 
924 #ifdef LOSCFG_SECURITY_CAPABILITY
SetRealEffSaveGroupIDCheck(int rgid,int egid,int sgid)925 static int SetRealEffSaveGroupIDCheck(int rgid, int egid, int sgid)
926 {
927     if ((rgid < 0) && (rgid != -1)) {
928         return -EINVAL;
929     }
930 
931     if ((egid < 0) && (egid != -1)) {
932         return -EINVAL;
933     }
934 
935     if ((sgid < 0) && (sgid != -1)) {
936         return -EINVAL;
937     }
938 
939     return 0;
940 }
941 #endif
942 
SysSetRealEffSaveGroupID(int rgid,int egid,int sgid)943 int SysSetRealEffSaveGroupID(int rgid, int egid, int sgid)
944 {
945 #ifdef LOSCFG_SECURITY_CAPABILITY
946     int ret;
947 
948     if ((rgid == -1) && (egid == -1) && (sgid == -1)) {
949         return 0;
950     }
951 
952     ret = SetRealEffSaveGroupIDCheck(rgid, egid, sgid);
953     if (ret != 0) {
954         return ret;
955     }
956 
957     if (rgid >= 0) {
958         if (((egid != -1) && (egid != rgid)) || ((sgid != -1) && (sgid != rgid))) {
959             return -EPERM;
960         }
961         return SysSetGroupID(rgid);
962     } else if (egid >= 0) {
963         if ((sgid != -1) && (sgid != egid)) {
964             return -EPERM;
965         }
966         return SysSetGroupID(egid);
967     } else {
968         return SysSetGroupID(sgid);
969     }
970 
971 #else
972     if ((rgid != 0) || (egid != 0) || (sgid != 0)) {
973         return -EPERM;
974     }
975     return 0;
976 #endif
977 }
978 
SysSetRealEffGroupID(int rgid,int egid)979 int SysSetRealEffGroupID(int rgid, int egid)
980 {
981 #ifdef LOSCFG_SECURITY_CAPABILITY
982     return SysSetRealEffSaveGroupID(rgid, egid, -1);
983 #else
984     if ((rgid != 0) || (egid != 0)) {
985         return -EPERM;
986     }
987     return 0;
988 #endif
989 }
990 
SysGetGroupID(void)991 int SysGetGroupID(void)
992 {
993     return LOS_GetGroupID();
994 }
995 
996 #ifdef LOSCFG_SECURITY_CAPABILITY
SetGroups(int listSize,const int * safeList,int size)997 static int SetGroups(int listSize, const int *safeList, int size)
998 {
999     User *oldUser = NULL;
1000     unsigned int intSave;
1001 
1002     User *newUser = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + listSize * sizeof(int));
1003     if (newUser == NULL) {
1004         return -ENOMEM;
1005     }
1006 
1007     SCHEDULER_LOCK(intSave);
1008     oldUser = OsCurrUserGet();
1009     (VOID)memcpy_s(newUser, sizeof(User), oldUser, sizeof(User));
1010     if (safeList != NULL) {
1011         (VOID)memcpy_s(newUser->groups, size * sizeof(int), safeList, size * sizeof(int));
1012     }
1013     if (listSize == size) {
1014         newUser->groups[listSize] = oldUser->gid;
1015     }
1016 
1017     newUser->groupNumber = listSize + 1;
1018     OsCurrProcessGet()->user = newUser;
1019     SCHEDULER_UNLOCK(intSave);
1020 
1021     (void)LOS_MemFree(m_aucSysMem1, oldUser);
1022     return 0;
1023 }
1024 
GetGroups(int size,int list[])1025 static int GetGroups(int size, int list[])
1026 {
1027     unsigned int intSave;
1028     int groupCount;
1029     int ret;
1030     int *safeList = NULL;
1031     unsigned int listSize;
1032 
1033     SCHEDULER_LOCK(intSave);
1034     groupCount = OsCurrUserGet()->groupNumber;
1035     SCHEDULER_UNLOCK(intSave);
1036 
1037     listSize = groupCount * sizeof(int);
1038     if (size == 0) {
1039         return groupCount;
1040     } else if (list == NULL) {
1041         return -EFAULT;
1042     } else if (size < groupCount) {
1043         return -EINVAL;
1044     }
1045 
1046     safeList = LOS_MemAlloc(m_aucSysMem1, listSize);
1047     if (safeList == NULL) {
1048         return -ENOMEM;
1049     }
1050 
1051     SCHEDULER_LOCK(intSave);
1052     (void)memcpy_s(safeList, listSize, &OsCurrProcessGet()->user->groups[0], listSize);
1053     SCHEDULER_UNLOCK(intSave);
1054 
1055     ret = LOS_ArchCopyToUser(list, safeList, listSize);
1056     if (ret != 0) {
1057         groupCount = -EFAULT;
1058     }
1059 
1060     (void)LOS_MemFree(m_aucSysMem1, safeList);
1061     return groupCount;
1062 }
1063 #endif
1064 
SysGetGroups(int size,int list[])1065 int SysGetGroups(int size, int list[])
1066 {
1067 #ifdef LOSCFG_SECURITY_CAPABILITY
1068     return GetGroups(size, list);
1069 #else
1070     int group = 0;
1071     int groupCount = 1;
1072     int ret;
1073 
1074     if (size == 0) {
1075         return groupCount;
1076     } else if (list == NULL) {
1077         return -EFAULT;
1078     } else if (size < groupCount) {
1079         return -EINVAL;
1080     }
1081 
1082     ret = LOS_ArchCopyToUser(list, &group, sizeof(int));
1083     if (ret != 0) {
1084         return -EFAULT;
1085     }
1086 
1087     return groupCount;
1088 #endif
1089 }
1090 
SysSetGroups(int size,const int list[])1091 int SysSetGroups(int size, const int list[])
1092 {
1093 #ifdef LOSCFG_SECURITY_CAPABILITY
1094     int ret;
1095     int gid;
1096     int listSize = size;
1097     unsigned int count;
1098     int *safeList = NULL;
1099 #endif
1100 
1101     if ((size != 0) && (list == NULL)) {
1102         return -EFAULT;
1103     }
1104 
1105     if ((size < 0) || (size > OS_GROUPS_NUMBER_MAX)) {
1106         return -EINVAL;
1107     }
1108 
1109 #ifdef LOSCFG_SECURITY_CAPABILITY
1110     if (!IsCapPermit(CAP_SETGID)) {
1111         return -EPERM;
1112     }
1113 
1114     if (size != 0) {
1115         safeList = LOS_MemAlloc(m_aucSysMem1, size * sizeof(int));
1116         if (safeList == NULL) {
1117             return -ENOMEM;
1118         }
1119 
1120         ret = LOS_ArchCopyFromUser(safeList, list, size * sizeof(int));
1121         if (ret != 0) {
1122             ret = -EFAULT;
1123             goto EXIT;
1124         }
1125         gid = OsCurrUserGet()->gid;
1126         for (count = 0; count < size; count++) {
1127             if (safeList[count] == gid) {
1128                 listSize = size - 1;
1129             } else if (safeList[count] < 0) {
1130                 ret = -EINVAL;
1131                 goto EXIT;
1132             }
1133         }
1134     }
1135 
1136     ret = SetGroups(listSize, safeList, size);
1137 EXIT:
1138     if (safeList != NULL) {
1139         (void)LOS_MemFree(m_aucSysMem1, safeList);
1140     }
1141 
1142     return ret;
1143 #else
1144     return 0;
1145 #endif
1146 }
1147 
SysCreateUserThread(const TSK_ENTRY_FUNC func,const UserTaskParam * userParam,bool joinable)1148 unsigned int SysCreateUserThread(const TSK_ENTRY_FUNC func, const UserTaskParam *userParam, bool joinable)
1149 {
1150     TSK_INIT_PARAM_S param = { 0 };
1151     int ret;
1152 
1153     ret = LOS_ArchCopyFromUser(&(param.userParam), userParam, sizeof(UserTaskParam));
1154     if (ret != 0) {
1155         return OS_INVALID_VALUE;
1156     }
1157 
1158     param.pfnTaskEntry = func;
1159     if (joinable == TRUE) {
1160         param.uwResved = LOS_TASK_ATTR_JOINABLE;
1161     } else {
1162         param.uwResved = LOS_TASK_STATUS_DETACHED;
1163     }
1164 
1165     return OsCreateUserTask(OS_INVALID_VALUE, &param);
1166 }
1167 
SysSetThreadArea(const char * area)1168 int SysSetThreadArea(const char *area)
1169 {
1170     unsigned int intSave;
1171     int ret = LOS_OK;
1172 
1173     if (!LOS_IsUserAddress((unsigned long)(uintptr_t)area)) {
1174         return EINVAL;
1175     }
1176 
1177     LosTaskCB *taskCB = OsCurrTaskGet();
1178     SCHEDULER_LOCK(intSave);
1179     LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB);
1180     if (processCB->processMode != OS_USER_MODE) {
1181         ret = EPERM;
1182         goto OUT;
1183     }
1184 
1185     taskCB->userArea = (unsigned long)(uintptr_t)area;
1186 OUT:
1187     SCHEDULER_UNLOCK(intSave);
1188     return ret;
1189 }
1190 
SysGetThreadArea(void)1191 char *SysGetThreadArea(void)
1192 {
1193     return (char *)(OsCurrTaskGet()->userArea);
1194 }
1195 
SysUserThreadSetDetach(unsigned int taskID)1196 int SysUserThreadSetDetach(unsigned int taskID)
1197 {
1198     unsigned int intSave;
1199     int ret;
1200 
1201     if (OS_TID_CHECK_INVALID(taskID)) {
1202         return EINVAL;
1203     }
1204 
1205     LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1206     SCHEDULER_LOCK(intSave);
1207     ret = OsUserTaskOperatePermissionsCheck(taskCB);
1208     if (ret != LOS_OK) {
1209         goto EXIT;
1210     }
1211 
1212     ret = (int)OsTaskSetDetachUnsafe(taskCB);
1213 
1214 EXIT:
1215     SCHEDULER_UNLOCK(intSave);
1216     return ret;
1217 }
1218 
SysUserThreadDetach(unsigned int taskID)1219 int SysUserThreadDetach(unsigned int taskID)
1220 {
1221     unsigned int intSave;
1222     int ret;
1223 
1224     if (OS_TID_CHECK_INVALID(taskID)) {
1225         return EINVAL;
1226     }
1227 
1228     SCHEDULER_LOCK(intSave);
1229     ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
1230     SCHEDULER_UNLOCK(intSave);
1231     if (ret != LOS_OK) {
1232         return ret;
1233     }
1234 
1235     if (LOS_TaskDelete(taskID) != LOS_OK) {
1236         return ESRCH;
1237     }
1238 
1239     return LOS_OK;
1240 }
1241 
SysThreadJoin(unsigned int taskID)1242 int SysThreadJoin(unsigned int taskID)
1243 {
1244     unsigned int intSave;
1245     int ret;
1246 
1247     if (OS_TID_CHECK_INVALID(taskID)) {
1248         return EINVAL;
1249     }
1250 
1251     LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1252     SCHEDULER_LOCK(intSave);
1253     ret = OsUserTaskOperatePermissionsCheck(taskCB);
1254     if (ret != LOS_OK) {
1255         goto EXIT;
1256     }
1257 
1258     ret = (int)OsTaskJoinPendUnsafe(OS_TCB_FROM_TID(taskID));
1259 
1260 EXIT:
1261     SCHEDULER_UNLOCK(intSave);
1262     return ret;
1263 }
1264 
SysUserExitGroup(int status)1265 void SysUserExitGroup(int status)
1266 {
1267     (void)status;
1268     OsProcessThreadGroupDestroy();
1269 }
1270 
SysThreadExit(int status)1271 void SysThreadExit(int status)
1272 {
1273     OsRunningTaskToExit(OsCurrTaskGet(), (unsigned int)status);
1274 }
1275 
SysFutex(const unsigned int * uAddr,unsigned int flags,int val,unsigned int absTime,const unsigned int * newUserAddr)1276 int SysFutex(const unsigned int *uAddr, unsigned int flags, int val,
1277              unsigned int absTime, const unsigned int *newUserAddr)
1278 {
1279     if ((flags & FUTEX_MASK) == FUTEX_REQUEUE) {
1280         return -OsFutexRequeue(uAddr, flags, val, absTime, newUserAddr);
1281     }
1282 
1283     if ((flags & FUTEX_MASK) == FUTEX_WAKE) {
1284         return -OsFutexWake(uAddr, flags, val);
1285     }
1286 
1287     return -OsFutexWait(uAddr, flags, val, absTime);
1288 }
1289 
SysGetTid(void)1290 unsigned int SysGetTid(void)
1291 {
1292     return OsCurrTaskGet()->taskID;
1293 }
1294 
1295 /* 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)1296 static int SchedAffinityParameterPreprocess(int id, int flag, unsigned int *taskID, unsigned int *processID)
1297 {
1298     if (flag >= 0) {
1299         if (OS_PID_CHECK_INVALID(id)) {
1300             return -ESRCH;
1301         }
1302         LosProcessCB *ProcessCB = OS_PCB_FROM_PID((UINT32)id);
1303         if (ProcessCB->threadGroup == NULL) {
1304             return -ESRCH;
1305         }
1306         *taskID = (id == 0) ? (OsCurrTaskGet()->taskID) : (ProcessCB->threadGroup->taskID);
1307         *processID = (id == 0) ? (OS_PCB_FROM_TID(*taskID)->processID) : id;
1308     } else {
1309         if (OS_TID_CHECK_INVALID(id)) {
1310             return -ESRCH;
1311         }
1312         *taskID = id;
1313         *processID = OS_INVALID_VALUE;
1314     }
1315     return LOS_OK;
1316 }
1317 
1318 /* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */
SysSchedGetAffinity(int id,unsigned int * cpuset,int flag)1319 int SysSchedGetAffinity(int id, unsigned int *cpuset, int flag)
1320 {
1321     int ret;
1322     unsigned int processID;
1323     unsigned int taskID;
1324     unsigned int intSave;
1325     unsigned int cpuAffiMask;
1326 
1327     ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID);
1328     if (ret != LOS_OK) {
1329         return ret;
1330     }
1331 
1332     SCHEDULER_LOCK(intSave);
1333     if (flag >= 0) {
1334         if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) {
1335             SCHEDULER_UNLOCK(intSave);
1336             return -ESRCH;
1337         }
1338     } else {
1339         ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
1340         if (ret != LOS_OK) {
1341             SCHEDULER_UNLOCK(intSave);
1342             if (ret == EINVAL) {
1343                 return -ESRCH;
1344             }
1345             return -ret;
1346         }
1347     }
1348 
1349 #ifdef LOSCFG_KERNEL_SMP
1350     cpuAffiMask = (unsigned int)OS_TCB_FROM_TID(taskID)->cpuAffiMask;
1351 #else
1352     cpuAffiMask = 1;
1353 #endif /* LOSCFG_KERNEL_SMP */
1354 
1355     SCHEDULER_UNLOCK(intSave);
1356     ret = LOS_ArchCopyToUser(cpuset, &cpuAffiMask, sizeof(unsigned int));
1357     if (ret != LOS_OK) {
1358         return -EFAULT;
1359     }
1360 
1361     return LOS_OK;
1362 }
1363 
1364 /* 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)1365 int SysSchedSetAffinity(int id, const unsigned short cpuset, int flag)
1366 {
1367     int ret;
1368     unsigned int processID;
1369     unsigned int taskID;
1370     unsigned int intSave;
1371     unsigned short currCpuMask;
1372     bool needSched = FALSE;
1373 
1374     if (cpuset > LOSCFG_KERNEL_CPU_MASK) {
1375         return -EINVAL;
1376     }
1377 
1378     ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID);
1379     if (ret != LOS_OK) {
1380         return ret;
1381     }
1382 
1383     if (flag >= 0) {
1384         ret = OsPermissionToCheck(processID, LOS_GetCurrProcessID());
1385         if (ret != LOS_OK) {
1386             return ret;
1387         }
1388         SCHEDULER_LOCK(intSave);
1389         if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) {
1390             SCHEDULER_UNLOCK(intSave);
1391             return -ESRCH;
1392         }
1393     } else {
1394         SCHEDULER_LOCK(intSave);
1395         ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
1396         if (ret != LOS_OK) {
1397             SCHEDULER_UNLOCK(intSave);
1398             if (ret == EINVAL) {
1399                 return -ESRCH;
1400             }
1401             return -ret;
1402         }
1403     }
1404 
1405     needSched = OsTaskCpuAffiSetUnsafe(taskID, cpuset, &currCpuMask);
1406     SCHEDULER_UNLOCK(intSave);
1407     if (needSched && OS_SCHEDULER_ACTIVE) {
1408         LOS_MpSchedule(currCpuMask);
1409         LOS_Schedule();
1410     }
1411 
1412     return LOS_OK;
1413 }
1414 
1415