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, ¶m);
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, ¶m);
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, ¶m);
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(¶m, userParam, sizeof(LosSchedParam)) != 0) {
190 return -EFAULT;
191 }
192
193 if (flag < 0) {
194 return -OsUserTaskSchedulerSet(id, policy, ¶m, 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, ¶m);
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, ¶m);
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(¶m, userParam, sizeof(LosSchedParam)) != 0) {
308 return -EFAULT;
309 }
310 return -OsUserTaskSchedulerSet(id, LOS_SCHED_RR, ¶m, 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, ¶m);
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
1036 listSize = groupCount * sizeof(int);
1037 if (size == 0) {
1038 SCHEDULER_UNLOCK(intSave);
1039 return groupCount;
1040 } else if (list == NULL) {
1041 SCHEDULER_UNLOCK(intSave);
1042 return -EFAULT;
1043 } else if (size < groupCount) {
1044 SCHEDULER_UNLOCK(intSave);
1045 return -EINVAL;
1046 }
1047
1048 safeList = LOS_MemAlloc(m_aucSysMem1, listSize);
1049 if (safeList == NULL) {
1050 SCHEDULER_UNLOCK(intSave);
1051 return -ENOMEM;
1052 }
1053
1054 (void)memcpy_s(safeList, listSize, &OsCurrProcessGet()->user->groups[0], listSize);
1055 SCHEDULER_UNLOCK(intSave);
1056
1057 ret = LOS_ArchCopyToUser(list, safeList, listSize);
1058 if (ret != 0) {
1059 groupCount = -EFAULT;
1060 }
1061
1062 (void)LOS_MemFree(m_aucSysMem1, safeList);
1063 return groupCount;
1064 }
1065 #endif
1066
SysGetGroups(int size,int list[])1067 int SysGetGroups(int size, int list[])
1068 {
1069 #ifdef LOSCFG_SECURITY_CAPABILITY
1070 return GetGroups(size, list);
1071 #else
1072 int group = 0;
1073 int groupCount = 1;
1074 int ret;
1075
1076 if (size == 0) {
1077 return groupCount;
1078 } else if (list == NULL) {
1079 return -EFAULT;
1080 } else if (size < groupCount) {
1081 return -EINVAL;
1082 }
1083
1084 ret = LOS_ArchCopyToUser(list, &group, sizeof(int));
1085 if (ret != 0) {
1086 return -EFAULT;
1087 }
1088
1089 return groupCount;
1090 #endif
1091 }
1092
SysSetGroups(int size,const int list[])1093 int SysSetGroups(int size, const int list[])
1094 {
1095 #ifdef LOSCFG_SECURITY_CAPABILITY
1096 int ret;
1097 int gid;
1098 int listSize = size;
1099 unsigned int count;
1100 int *safeList = NULL;
1101 #endif
1102
1103 if ((size != 0) && (list == NULL)) {
1104 return -EFAULT;
1105 }
1106
1107 if ((size < 0) || (size > OS_GROUPS_NUMBER_MAX)) {
1108 return -EINVAL;
1109 }
1110
1111 #ifdef LOSCFG_SECURITY_CAPABILITY
1112 if (!IsCapPermit(CAP_SETGID)) {
1113 return -EPERM;
1114 }
1115
1116 if (size != 0) {
1117 safeList = LOS_MemAlloc(m_aucSysMem1, size * sizeof(int));
1118 if (safeList == NULL) {
1119 return -ENOMEM;
1120 }
1121
1122 ret = LOS_ArchCopyFromUser(safeList, list, size * sizeof(int));
1123 if (ret != 0) {
1124 ret = -EFAULT;
1125 goto EXIT;
1126 }
1127 gid = OsCurrUserGet()->gid;
1128 for (count = 0; count < size; count++) {
1129 if (safeList[count] == gid) {
1130 listSize = size - 1;
1131 } else if (safeList[count] < 0) {
1132 ret = -EINVAL;
1133 goto EXIT;
1134 }
1135 }
1136 }
1137
1138 ret = SetGroups(listSize, safeList, size);
1139 EXIT:
1140 if (safeList != NULL) {
1141 (void)LOS_MemFree(m_aucSysMem1, safeList);
1142 }
1143
1144 return ret;
1145 #else
1146 return 0;
1147 #endif
1148 }
1149
SysCreateUserThread(const TSK_ENTRY_FUNC func,const UserTaskParam * userParam,bool joinable)1150 unsigned int SysCreateUserThread(const TSK_ENTRY_FUNC func, const UserTaskParam *userParam, bool joinable)
1151 {
1152 TSK_INIT_PARAM_S param = { 0 };
1153 int ret;
1154
1155 ret = LOS_ArchCopyFromUser(&(param.userParam), userParam, sizeof(UserTaskParam));
1156 if (ret != 0) {
1157 return OS_INVALID_VALUE;
1158 }
1159
1160 param.pfnTaskEntry = func;
1161 if (joinable == TRUE) {
1162 param.uwResved = LOS_TASK_ATTR_JOINABLE;
1163 } else {
1164 param.uwResved = LOS_TASK_STATUS_DETACHED;
1165 }
1166
1167 return OsCreateUserTask(OS_INVALID_VALUE, ¶m);
1168 }
1169
SysSetThreadArea(const char * area)1170 int SysSetThreadArea(const char *area)
1171 {
1172 unsigned int intSave;
1173 int ret = LOS_OK;
1174
1175 if (!LOS_IsUserAddress((unsigned long)(uintptr_t)area)) {
1176 return EINVAL;
1177 }
1178
1179 LosTaskCB *taskCB = OsCurrTaskGet();
1180 SCHEDULER_LOCK(intSave);
1181 LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB);
1182 if (processCB->processMode != OS_USER_MODE) {
1183 ret = EPERM;
1184 goto OUT;
1185 }
1186
1187 taskCB->userArea = (unsigned long)(uintptr_t)area;
1188 OUT:
1189 SCHEDULER_UNLOCK(intSave);
1190 return ret;
1191 }
1192
SysGetThreadArea(void)1193 char *SysGetThreadArea(void)
1194 {
1195 return (char *)(OsCurrTaskGet()->userArea);
1196 }
1197
SysUserThreadSetDetach(unsigned int taskID)1198 int SysUserThreadSetDetach(unsigned int taskID)
1199 {
1200 unsigned int intSave;
1201 int ret;
1202
1203 if (OS_TID_CHECK_INVALID(taskID)) {
1204 return EINVAL;
1205 }
1206
1207 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1208 SCHEDULER_LOCK(intSave);
1209 ret = OsUserTaskOperatePermissionsCheck(taskCB);
1210 if (ret != LOS_OK) {
1211 goto EXIT;
1212 }
1213
1214 ret = (int)OsTaskSetDetachUnsafe(taskCB);
1215
1216 EXIT:
1217 SCHEDULER_UNLOCK(intSave);
1218 return ret;
1219 }
1220
SysUserThreadDetach(unsigned int taskID)1221 int SysUserThreadDetach(unsigned int taskID)
1222 {
1223 unsigned int intSave;
1224 int ret;
1225
1226 if (OS_TID_CHECK_INVALID(taskID)) {
1227 return EINVAL;
1228 }
1229
1230 SCHEDULER_LOCK(intSave);
1231 ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
1232 SCHEDULER_UNLOCK(intSave);
1233 if (ret != LOS_OK) {
1234 return ret;
1235 }
1236
1237 if (LOS_TaskDelete(taskID) != LOS_OK) {
1238 return ESRCH;
1239 }
1240
1241 return LOS_OK;
1242 }
1243
SysThreadJoin(unsigned int taskID)1244 int SysThreadJoin(unsigned int taskID)
1245 {
1246 unsigned int intSave;
1247 int ret;
1248
1249 if (OS_TID_CHECK_INVALID(taskID)) {
1250 return EINVAL;
1251 }
1252
1253 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1254 SCHEDULER_LOCK(intSave);
1255 ret = OsUserTaskOperatePermissionsCheck(taskCB);
1256 if (ret != LOS_OK) {
1257 goto EXIT;
1258 }
1259
1260 ret = (int)OsTaskJoinPendUnsafe(OS_TCB_FROM_TID(taskID));
1261
1262 EXIT:
1263 SCHEDULER_UNLOCK(intSave);
1264 return ret;
1265 }
1266
SysUserExitGroup(int status)1267 void SysUserExitGroup(int status)
1268 {
1269 (void)status;
1270 OsProcessThreadGroupDestroy();
1271 }
1272
SysThreadExit(int status)1273 void SysThreadExit(int status)
1274 {
1275 OsRunningTaskToExit(OsCurrTaskGet(), (unsigned int)status);
1276 }
1277
SysFutex(const unsigned int * uAddr,unsigned int flags,int val,unsigned int absTime,const unsigned int * newUserAddr)1278 int SysFutex(const unsigned int *uAddr, unsigned int flags, int val,
1279 unsigned int absTime, const unsigned int *newUserAddr)
1280 {
1281 if ((flags & FUTEX_MASK) == FUTEX_REQUEUE) {
1282 return -OsFutexRequeue(uAddr, flags, val, absTime, newUserAddr);
1283 }
1284
1285 if ((flags & FUTEX_MASK) == FUTEX_WAKE) {
1286 return -OsFutexWake(uAddr, flags, val);
1287 }
1288
1289 return -OsFutexWait(uAddr, flags, val, absTime);
1290 }
1291
SysGetTid(void)1292 unsigned int SysGetTid(void)
1293 {
1294 return OsCurrTaskGet()->taskID;
1295 }
1296
1297 /* 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)1298 static int SchedAffinityParameterPreprocess(int id, int flag, unsigned int *taskID, unsigned int *processID)
1299 {
1300 if (flag >= 0) {
1301 if (OS_PID_CHECK_INVALID(id)) {
1302 return -ESRCH;
1303 }
1304 LosProcessCB *ProcessCB = OS_PCB_FROM_PID((UINT32)id);
1305 if (ProcessCB->threadGroup == NULL) {
1306 return -ESRCH;
1307 }
1308 *taskID = (id == 0) ? (OsCurrTaskGet()->taskID) : (ProcessCB->threadGroup->taskID);
1309 *processID = (id == 0) ? (OS_PCB_FROM_TID(*taskID)->processID) : id;
1310 } else {
1311 if (OS_TID_CHECK_INVALID(id)) {
1312 return -ESRCH;
1313 }
1314 *taskID = id;
1315 *processID = OS_INVALID_VALUE;
1316 }
1317 return LOS_OK;
1318 }
1319
1320 /* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */
SysSchedGetAffinity(int id,unsigned int * cpuset,int flag)1321 int SysSchedGetAffinity(int id, unsigned int *cpuset, int flag)
1322 {
1323 int ret;
1324 unsigned int processID;
1325 unsigned int taskID;
1326 unsigned int intSave;
1327 unsigned int cpuAffiMask;
1328
1329 ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID);
1330 if (ret != LOS_OK) {
1331 return ret;
1332 }
1333
1334 SCHEDULER_LOCK(intSave);
1335 if (flag >= 0) {
1336 if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) {
1337 SCHEDULER_UNLOCK(intSave);
1338 return -ESRCH;
1339 }
1340 } else {
1341 ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
1342 if (ret != LOS_OK) {
1343 SCHEDULER_UNLOCK(intSave);
1344 if (ret == EINVAL) {
1345 return -ESRCH;
1346 }
1347 return -ret;
1348 }
1349 }
1350
1351 #ifdef LOSCFG_KERNEL_SMP
1352 cpuAffiMask = (unsigned int)OS_TCB_FROM_TID(taskID)->cpuAffiMask;
1353 #else
1354 cpuAffiMask = 1;
1355 #endif /* LOSCFG_KERNEL_SMP */
1356
1357 SCHEDULER_UNLOCK(intSave);
1358 ret = LOS_ArchCopyToUser(cpuset, &cpuAffiMask, sizeof(unsigned int));
1359 if (ret != LOS_OK) {
1360 return -EFAULT;
1361 }
1362
1363 return LOS_OK;
1364 }
1365
1366 /* 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)1367 int SysSchedSetAffinity(int id, const unsigned short cpuset, int flag)
1368 {
1369 int ret;
1370 unsigned int processID;
1371 unsigned int taskID;
1372 unsigned int intSave;
1373 unsigned short currCpuMask;
1374 bool needSched = FALSE;
1375
1376 if (cpuset > LOSCFG_KERNEL_CPU_MASK) {
1377 return -EINVAL;
1378 }
1379
1380 ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID);
1381 if (ret != LOS_OK) {
1382 return ret;
1383 }
1384
1385 if (flag >= 0) {
1386 ret = OsPermissionToCheck(processID, LOS_GetCurrProcessID());
1387 if (ret != LOS_OK) {
1388 return ret;
1389 }
1390 SCHEDULER_LOCK(intSave);
1391 if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) {
1392 SCHEDULER_UNLOCK(intSave);
1393 return -ESRCH;
1394 }
1395 } else {
1396 SCHEDULER_LOCK(intSave);
1397 ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
1398 if (ret != LOS_OK) {
1399 SCHEDULER_UNLOCK(intSave);
1400 if (ret == EINVAL) {
1401 return -ESRCH;
1402 }
1403 return -ret;
1404 }
1405 }
1406
1407 needSched = OsTaskCpuAffiSetUnsafe(taskID, cpuset, &currCpuMask);
1408 SCHEDULER_UNLOCK(intSave);
1409 if (needSched && OS_SCHEDULER_ACTIVE) {
1410 LOS_MpSchedule(currCpuMask);
1411 LOS_Schedule();
1412 }
1413
1414 return LOS_OK;
1415 }
1416
1417