更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
process_syscall.c
浏览该文件的文档.
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
46//进程相关系统回调
47//检查进程权限
48static int OsPermissionToCheck(unsigned int pid, unsigned int who)
49{
50 int ret = LOS_GetProcessGroupID(pid);//获取进程组ID
51 if (ret < 0) {
52 return ret;
53 } else if (ret == OS_KERNEL_PROCESS_GROUP) {//为内核进程组
54 return -EPERM;
55 } else if ((ret == OS_USER_PRIVILEGE_PROCESS_GROUP) && (pid != who)) {//为用户进程组,但两个参数进程不一致
56 return -EPERM;
57 } else if (pid == OsGetUserInitProcessID()) {//为用户进程的祖宗
58 return -EPERM;
59 }
60
61 return 0;
62}
63///设置用户级任务调度信息
64static int OsUserTaskSchedulerSet(unsigned int tid, unsigned short policy, unsigned short priority, bool policyFlag)
65{
66 int ret;
67 unsigned int intSave;
68 bool needSched = false;
69 SchedParam param = { 0 };
70
71 if (OS_TID_CHECK_INVALID(tid)) {
72 return EINVAL;
73 }
74
75 if (priority > OS_TASK_PRIORITY_LOWEST) {
76 return EINVAL;
77 }
78
79 if ((policy != LOS_SCHED_FIFO) && (policy != LOS_SCHED_RR)) {
80 return EINVAL;
81 }
82
83 LosTaskCB *taskCB = OS_TCB_FROM_TID(tid);
84 SCHEDULER_LOCK(intSave);
86 if (ret != LOS_OK) {
87 SCHEDULER_UNLOCK(intSave);
88 return ret;
89 }
90
91 taskCB->ops->schedParamGet(taskCB, &param);
92 param.policy = (policyFlag == true) ? policy : param.policy;
93 param.priority = priority;
94 needSched = taskCB->ops->schedParamModify(taskCB, &param);
95 SCHEDULER_UNLOCK(intSave);
96
97 LOS_MpSchedule(OS_MP_CPU_ALL);
98 if (needSched && OS_SCHEDULER_ACTIVE) {
100 }
101
102 return LOS_OK;
103}
104
105void SysSchedYield(int type)
106{
107 (void)type;
108
110 return;
111}
112
113int SysSchedGetScheduler(int id, int flag)
114{
115 unsigned int intSave;
116 SchedParam param = { 0 };
117 int ret;
118
119 if (flag < 0) {
120 if (OS_TID_CHECK_INVALID(id)) {
121 return -EINVAL;
122 }
123
124 LosTaskCB *taskCB = OS_TCB_FROM_TID(id);
125 SCHEDULER_LOCK(intSave);
127 if (ret != LOS_OK) {
128 SCHEDULER_UNLOCK(intSave);
129 return -ret;
130 }
131
132 taskCB->ops->schedParamGet(taskCB, &param);
133 SCHEDULER_UNLOCK(intSave);
134 return (int)param.policy;
135 }
136
137 return LOS_GetProcessScheduler(id);
138}
139
140int SysSchedSetScheduler(int id, int policy, int prio, int flag)
141{
142 int ret;
143
144 if (flag < 0) {
145 return -OsUserTaskSchedulerSet(id, policy, prio, true);
146 }
147
148 if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) {
149 return -EINVAL;
150 }
151
152 if (id == 0) {
154 }
155
157 if (ret < 0) {
158 return ret;
159 }
160
161 return OsSetProcessScheduler(LOS_PRIO_PROCESS, id, prio, policy);
162}
163
164int SysSchedGetParam(int id, int flag)
165{
166 SchedParam param = { 0 };
167 unsigned int intSave;
168
169 if (flag < 0) {
170 if (OS_TID_CHECK_INVALID(id)) {
171 return -EINVAL;
172 }
173
174 LosTaskCB *taskCB = OS_TCB_FROM_TID(id);
175 SCHEDULER_LOCK(intSave);
176 int ret = OsUserTaskOperatePermissionsCheck(taskCB);
177 if (ret != LOS_OK) {
178 SCHEDULER_UNLOCK(intSave);
179 return -ret;
180 }
181
182 taskCB->ops->schedParamGet(taskCB, &param);
183 SCHEDULER_UNLOCK(intSave);
184 return (int)param.priority;
185 }
186
187 if (id == 0) {
189 }
190
191 if (OS_PID_CHECK_INVALID(id)) {
192 return -EINVAL;
193 }
194
195 return OsGetProcessPriority(LOS_PRIO_PROCESS, id);
196}
197
198int SysSetProcessPriority(int which, int who, unsigned int prio)
199{
200 int ret;
201
202 if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) {
203 return -EINVAL;
204 }
205
206 if (who == 0) {
207 who = (int)LOS_GetCurrProcessID();
208 }
209
211 if (ret < 0) {
212 return ret;
213 }
214
215 return OsSetProcessScheduler(which, who, prio, LOS_GetProcessScheduler(who));
216}
217
218int SysSchedSetParam(int id, unsigned int prio, int flag)
219{
220 if (flag < 0) {
221 return -OsUserTaskSchedulerSet(id, LOS_SCHED_RR, prio, false);
222 }
223
224 return SysSetProcessPriority(LOS_PRIO_PROCESS, id, prio);
225}
226
227int SysGetProcessPriority(int which, int who)
228{
229 if (who == 0) {
230 who = (int)LOS_GetCurrProcessID();
231 }
232
233 return OsGetProcessPriority(which, who);
234}
235
237{
238 if (policy != LOS_SCHED_RR) {
239 return -EINVAL;
240 }
241
242 return OS_USER_PROCESS_PRIORITY_HIGHEST;
243}
244
246{
247 if (policy != LOS_SCHED_RR) {
248 return -EINVAL;
249 }
250
251 return OS_USER_PROCESS_PRIORITY_LOWEST;
252}
253
254int SysSchedRRGetInterval(int pid, struct timespec *tp)
255{
256 unsigned int intSave;
257 int ret;
258 SchedParam param = { 0 };
259 time_t timeSlice = 0;
260 struct timespec tv;
261 LosTaskCB *taskCB = NULL;
262 LosProcessCB *processCB = NULL;
263
264 if (tp == NULL) {
265 return -EINVAL;
266 }
267
268 if (OS_PID_CHECK_INVALID(pid)) {
269 return -EINVAL;
270 }
271
272 if (pid == 0) {
273 processCB = OsCurrProcessGet();
274 } else {
275 processCB = OS_PCB_FROM_PID(pid);
276 }
277
278 SCHEDULER_LOCK(intSave);
279 /* if can not find process by pid return ESRCH */
280 if (OsProcessIsInactive(processCB)) {
281 SCHEDULER_UNLOCK(intSave);
282 return -ESRCH;
283 }
284
285 LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) {
286 if (!OsTaskIsInactive(taskCB)) {
287 taskCB->ops->schedParamGet(taskCB, &param);
288 if (param.policy == LOS_SCHED_RR) {
289 timeSlice += param.timeSlice;
290 }
291 }
292 }
293
294 SCHEDULER_UNLOCK(intSave);
295
296 timeSlice = timeSlice * OS_NS_PER_CYCLE;
297 tv.tv_sec = timeSlice / OS_SYS_NS_PER_SECOND;
298 tv.tv_nsec = timeSlice % OS_SYS_NS_PER_SECOND;
299 ret = LOS_ArchCopyToUser(tp, &tv, sizeof(struct timespec));
300 if (ret != 0) {
301 return -EFAULT;
302 }
303
304 return 0;
305}
306
307int SysWait(int pid, USER int *status, int options, void *rusage)
308{
309 (void)rusage;
310
311 return LOS_Wait(pid, status, (unsigned int)options, NULL);
312}
313
314int SysWaitid(idtype_t type, int pid, USER siginfo_t *info, int options, void *rusage)
315{
316 (void)rusage;
317 int ret;
318 int truepid = 0;
319
320 switch (type) {
321 case P_ALL:
322 /* Wait for any child; id is ignored. */
323 truepid = -1;
324 break;
325 case P_PID:
326 /* Wait for the child whose process ID matches id */
327 if (pid <= 0) {
328 return -EINVAL;
329 }
330 truepid = pid;
331 break;
332 case P_PGID:
333 /* Wait for any child whose process group ID matches id */
334 if (pid <= 1) {
335 return -EINVAL;
336 }
337 truepid = -pid;
338 break;
339 default:
340 return -EINVAL;
341 }
342
343 ret = LOS_Waitid(truepid, info, (unsigned int)options, NULL);
344 if (ret > 0) {
345 ret = 0;
346 }
347 return ret;
348}
349
350int SysFork(void)
351{
352 return OsClone(0, 0, 0);
353}
354
355int SysVfork(void)
356{
357 return OsClone(CLONE_VFORK, 0, 0);
358}
359
360unsigned int SysGetPPID(void)
361{
363}
364
365unsigned int SysGetPID(void)
366{
367 return LOS_GetCurrProcessID();
368}
369/// 为指定进程设置进程组ID
370int SysSetProcessGroupID(unsigned int pid, unsigned int gid)
371{
372 int ret;
373
374 if (pid == 0) {//无指定进程ID时 @note_thinking 此处会不会有风险, 直接返回会不会好些 ?
375 pid = LOS_GetCurrProcessID();//获取当前进程ID,给当前进程设置组ID
376 }
377
378 if (gid == 0) {
379 gid = pid;
380 } else if (gid <= OS_USER_PRIVILEGE_PROCESS_GROUP) {
381 return -EPERM;
382 }
383
384 ret = OsPermissionToCheck(pid, gid);
385 if (ret < 0) {
386 return ret;
387 }
388
389 return OsSetProcessGroupID(pid, gid);
390}
391/// 获取指定进程的组ID,为0时返回当前进程ID
392int SysGetProcessGroupID(unsigned int pid)
393{
394 if (pid == 0) {
395 pid = LOS_GetCurrProcessID();
396 }
397
398 return LOS_GetProcessGroupID(pid);
399}
400/// 获取当前进程组ID
402{
404}
405/// 获取用户ID
407{
408 return LOS_GetUserID();
409}
410
412{
413#ifdef LOSCFG_SECURITY_CAPABILITY
414 UINT32 intSave;
415 int euid;
416
417 SCHEDULER_LOCK(intSave);
418 euid = (int)OsCurrUserGet()->effUserID;
419 SCHEDULER_UNLOCK(intSave);
420 return euid;
421#else
422 return 0;
423#endif
424}
425
427{
428#ifdef LOSCFG_SECURITY_CAPABILITY
429 UINT32 intSave;
430 int egid;
431
432 SCHEDULER_LOCK(intSave);
433 egid = (int)OsCurrUserGet()->effGid;
434 SCHEDULER_UNLOCK(intSave);
435 return egid;
436#else
437 return 0;
438#endif
439}
440
441int SysGetRealEffSaveUserID(int *ruid, int *euid, int *suid)
442{
443 int ret;
444 int realUserID, effUserID, saveUserID;
445#ifdef LOSCFG_SECURITY_CAPABILITY
446 unsigned int intSave;
447
448 SCHEDULER_LOCK(intSave);
449 realUserID = OsCurrUserGet()->userID;
450 effUserID = OsCurrUserGet()->effUserID;
451 saveUserID = OsCurrUserGet()->effUserID;
452 SCHEDULER_UNLOCK(intSave);
453#else
454 realUserID = 0;
455 effUserID = 0;
456 saveUserID = 0;
457#endif
458
459 ret = LOS_ArchCopyToUser(ruid, &realUserID, sizeof(int));
460 if (ret != 0) {
461 return -EFAULT;
462 }
463
464 ret = LOS_ArchCopyToUser(euid, &effUserID, sizeof(int));
465 if (ret != 0) {
466 return -EFAULT;
467 }
468
469 ret = LOS_ArchCopyToUser(suid, &saveUserID, sizeof(int));
470 if (ret != 0) {
471 return -EFAULT;
472 }
473
474 return 0;
475}
476
477int SysSetUserID(int uid)
478{
479#ifdef LOSCFG_SECURITY_CAPABILITY
480 int ret = -EPERM;
481 unsigned int intSave;
482
483 if (uid < 0) {
484 return -EINVAL;
485 }
486
487 SCHEDULER_LOCK(intSave);
488 User *user = OsCurrUserGet();
489 if (IsCapPermit(CAP_SETUID)) {
490 user->userID = uid;
491 user->effUserID = uid;
492 /* add process to a user */
493 } else if (user->userID != uid) {
494 goto EXIT;
495 }
496
497 ret = LOS_OK;
498 /* add process to a user */
499EXIT:
500 SCHEDULER_UNLOCK(intSave);
501 return ret;
502#else
503 if (uid != 0) {
504 return -EPERM;
505 }
506
507 return 0;
508#endif
509}
510
511#ifdef LOSCFG_SECURITY_CAPABILITY
512static int SetRealEffSaveUserIDCheck(int ruid, int euid, int suid)
513{
514 if ((ruid < 0) && (ruid != -1)) {
515 return -EINVAL;
516 }
517
518 if ((euid < 0) && (euid != -1)) {
519 return -EINVAL;
520 }
521
522 if ((suid < 0) && (suid != -1)) {
523 return -EINVAL;
524 }
525
526 return 0;
527}
528#endif
529
530int SysSetRealEffSaveUserID(int ruid, int euid, int suid)
531{
532#ifdef LOSCFG_SECURITY_CAPABILITY
533 int ret;
534
535 if ((ruid == -1) && (euid == -1) && (suid == -1)) {
536 return 0;
537 }
538
539 ret = SetRealEffSaveUserIDCheck(ruid, euid, suid);
540 if (ret != 0) {
541 return ret;
542 }
543
544 if (ruid >= 0) {
545 if (((euid != -1) && (euid != ruid)) || ((suid != -1) && (suid != ruid))) {
546 return -EPERM;
547 }
548 return SysSetUserID(ruid);
549 } else if (euid >= 0) {
550 if ((suid != -1) && (suid != euid)) {
551 return -EPERM;
552 }
553 return SysSetUserID(euid);
554 } else {
555 return SysSetUserID(suid);
556 }
557#else
558 if ((ruid != 0) || (euid != 0) || (suid != 0)) {
559 return -EPERM;
560 }
561 return 0;
562#endif
563}
564
565int SysSetRealEffUserID(int ruid, int euid)
566{
567#ifdef LOSCFG_SECURITY_CAPABILITY
568 return SysSetRealEffSaveUserID(ruid, euid, -1);
569#else
570 if ((ruid != 0) || (euid != 0)) {
571 return -EPERM;
572 }
573 return 0;
574#endif
575}
576
577int SysSetGroupID(int gid)
578{
579#ifdef LOSCFG_SECURITY_CAPABILITY
580 int ret = -EPERM;
581 unsigned int intSave;
582 unsigned int count;
583 unsigned int oldGid;
584 User *user = NULL;
585
586 if (gid < 0) {
587 return -EINVAL;
588 }
589
590 SCHEDULER_LOCK(intSave);
591 user = OsCurrUserGet();
592 if (IsCapPermit(CAP_SETGID)) {
593 oldGid = user->gid;
594 user->gid = gid;
595 user->effGid = gid;
596 for (count = 0; count < user->groupNumber; count++) {
597 if (user->groups[count] == oldGid) {
598 user->groups[count] = gid;
599 ret = LOS_OK;
600 goto EXIT;
601 }
602 }
603 } else if (user->gid != gid) {
604 goto EXIT;
605 }
606
607 ret = LOS_OK;
608 /* add process to a user */
609EXIT:
610 SCHEDULER_UNLOCK(intSave);
611 return ret;
612
613#else
614 if (gid != 0) {
615 return -EPERM;
616 }
617
618 return 0;
619#endif
620}
621
622int SysGetRealEffSaveGroupID(int *rgid, int *egid, int *sgid)
623{
624 int ret;
625 int realGroupID, effGroupID, saveGroupID;
626#ifdef LOSCFG_SECURITY_CAPABILITY
627 unsigned int intSave;
628
629 SCHEDULER_LOCK(intSave);
630 realGroupID = OsCurrUserGet()->gid;
631 effGroupID = OsCurrUserGet()->effGid;
632 saveGroupID = OsCurrUserGet()->effGid;
633 SCHEDULER_UNLOCK(intSave);
634#else
635 realGroupID = 0;
636 effGroupID = 0;
637 saveGroupID = 0;
638#endif
639
640 ret = LOS_ArchCopyToUser(rgid, &realGroupID, sizeof(int));
641 if (ret != 0) {
642 return -EFAULT;
643 }
644
645 ret = LOS_ArchCopyToUser(egid, &effGroupID, sizeof(int));
646 if (ret != 0) {
647 return -EFAULT;
648 }
649
650 ret = LOS_ArchCopyToUser(sgid, &saveGroupID, sizeof(int));
651 if (ret != 0) {
652 return -EFAULT;
653 }
654
655 return 0;
656}
657
658#ifdef LOSCFG_SECURITY_CAPABILITY
659static int SetRealEffSaveGroupIDCheck(int rgid, int egid, int sgid)
660{
661 if ((rgid < 0) && (rgid != -1)) {
662 return -EINVAL;
663 }
664
665 if ((egid < 0) && (egid != -1)) {
666 return -EINVAL;
667 }
668
669 if ((sgid < 0) && (sgid != -1)) {
670 return -EINVAL;
671 }
672
673 return 0;
674}
675#endif
676
677int SysSetRealEffSaveGroupID(int rgid, int egid, int sgid)
678{
679#ifdef LOSCFG_SECURITY_CAPABILITY
680 int ret;
681
682 if ((rgid == -1) && (egid == -1) && (sgid == -1)) {
683 return 0;
684 }
685
686 ret = SetRealEffSaveGroupIDCheck(rgid, egid, sgid);
687 if (ret != 0) {
688 return ret;
689 }
690
691 if (rgid >= 0) {
692 if (((egid != -1) && (egid != rgid)) || ((sgid != -1) && (sgid != rgid))) {
693 return -EPERM;
694 }
695 return SysSetGroupID(rgid);
696 } else if (egid >= 0) {
697 if ((sgid != -1) && (sgid != egid)) {
698 return -EPERM;
699 }
700 return SysSetGroupID(egid);
701 } else {
702 return SysSetGroupID(sgid);
703 }
704
705#else
706 if ((rgid != 0) || (egid != 0) || (sgid != 0)) {
707 return -EPERM;
708 }
709 return 0;
710#endif
711}
712
713int SysSetRealEffGroupID(int rgid, int egid)
714{
715#ifdef LOSCFG_SECURITY_CAPABILITY
716 return SysSetRealEffSaveGroupID(rgid, egid, -1);
717#else
718 if ((rgid != 0) || (egid != 0)) {
719 return -EPERM;
720 }
721 return 0;
722#endif
723}
724
726{
727 return LOS_GetGroupID();
728}
729
730#ifdef LOSCFG_SECURITY_CAPABILITY
731static int SetGroups(int listSize, const int *safeList, int size)
732{
733 User *oldUser = NULL;
734 unsigned int intSave;
735
736 User *newUser = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + listSize * sizeof(int));
737 if (newUser == NULL) {
738 return -ENOMEM;
739 }
740
741 SCHEDULER_LOCK(intSave);
742 oldUser = OsCurrUserGet();
743 (VOID)memcpy_s(newUser, sizeof(User), oldUser, sizeof(User));
744 if (safeList != NULL) {
745 (VOID)memcpy_s(newUser->groups, size * sizeof(int), safeList, size * sizeof(int));
746 }
747 if (listSize == size) {
748 newUser->groups[listSize] = oldUser->gid;
749 }
750
751 newUser->groupNumber = listSize + 1;
752 OsCurrProcessGet()->user = newUser;
753 SCHEDULER_UNLOCK(intSave);
754
755 (void)LOS_MemFree(m_aucSysMem1, oldUser);
756 return 0;
757}
758
759static int GetGroups(int size, int list[])
760{
761 unsigned int intSave;
762 int groupCount;
763 int ret;
764 int *safeList = NULL;
765 unsigned int listSize;
766
767 SCHEDULER_LOCK(intSave);
768 groupCount = OsCurrUserGet()->groupNumber;
769 SCHEDULER_UNLOCK(intSave);
770
771 listSize = groupCount * sizeof(int);
772 if (size == 0) {
773 return groupCount;
774 } else if (list == NULL) {
775 return -EFAULT;
776 } else if (size < groupCount) {
777 return -EINVAL;
778 }
779
780 safeList = LOS_MemAlloc(m_aucSysMem1, listSize);
781 if (safeList == NULL) {
782 return -ENOMEM;
783 }
784
785 SCHEDULER_LOCK(intSave);
786 (void)memcpy_s(safeList, listSize, &OsCurrProcessGet()->user->groups[0], listSize);
787 SCHEDULER_UNLOCK(intSave);
788
789 ret = LOS_ArchCopyToUser(list, safeList, listSize);
790 if (ret != 0) {
791 groupCount = -EFAULT;
792 }
793
794 (void)LOS_MemFree(m_aucSysMem1, safeList);
795 return groupCount;
796}
797#endif
798
799int SysGetGroups(int size, int list[])
800{
801#ifdef LOSCFG_SECURITY_CAPABILITY
802 return GetGroups(size, list);
803#else
804 int group = 0;
805 int groupCount = 1;
806 int ret;
807
808 if (size == 0) {
809 return groupCount;
810 } else if (list == NULL) {
811 return -EFAULT;
812 } else if (size < groupCount) {
813 return -EINVAL;
814 }
815
816 ret = LOS_ArchCopyToUser(list, &group, sizeof(int));
817 if (ret != 0) {
818 return -EFAULT;
819 }
820
821 return groupCount;
822#endif
823}
824
825int SysSetGroups(int size, const int list[])
826{
827#ifdef LOSCFG_SECURITY_CAPABILITY
828 int ret;
829 int gid;
830 int listSize = size;
831 unsigned int count;
832 int *safeList = NULL;
833#endif
834
835 if ((size != 0) && (list == NULL)) {
836 return -EFAULT;
837 }
838
839 if ((size < 0) || (size > OS_GROUPS_NUMBER_MAX)) {
840 return -EINVAL;
841 }
842
843#ifdef LOSCFG_SECURITY_CAPABILITY
844 if (!IsCapPermit(CAP_SETGID)) {
845 return -EPERM;
846 }
847
848 if (size != 0) {
849 safeList = LOS_MemAlloc(m_aucSysMem1, size * sizeof(int));
850 if (safeList == NULL) {
851 return -ENOMEM;
852 }
853
854 ret = LOS_ArchCopyFromUser(safeList, list, size * sizeof(int));
855 if (ret != 0) {
856 ret = -EFAULT;
857 goto EXIT;
858 }
859 gid = OsCurrUserGet()->gid;
860 for (count = 0; count < size; count++) {
861 if (safeList[count] == gid) {
862 listSize = size - 1;
863 } else if (safeList[count] < 0) {
864 ret = -EINVAL;
865 goto EXIT;
866 }
867 }
868 }
869
870 ret = SetGroups(listSize, safeList, size);
871EXIT:
872 if (safeList != NULL) {
873 (void)LOS_MemFree(m_aucSysMem1, safeList);
874 }
875
876 return ret;
877#else
878 return 0;
879#endif
880}
881
882unsigned int SysCreateUserThread(const TSK_ENTRY_FUNC func, const UserTaskParam *userParam, bool joinable)
883{
884 TSK_INIT_PARAM_S param = { 0 };
885 int ret;
886
887 ret = LOS_ArchCopyFromUser(&(param.userParam), userParam, sizeof(UserTaskParam));
888 if (ret != 0) {
889 return OS_INVALID_VALUE;
890 }
891
892 param.pfnTaskEntry = func;
893 if (joinable == TRUE) {
894 param.uwResved = LOS_TASK_ATTR_JOINABLE;
895 } else {
896 param.uwResved = LOS_TASK_STATUS_DETACHED;
897 }
898
899 return OsCreateUserTask(OS_INVALID_VALUE, &param);
900}
901
902int SysSetThreadArea(const char *area)
903{
904 unsigned int intSave;
905 int ret = LOS_OK;
906
907 if (!LOS_IsUserAddress((unsigned long)(uintptr_t)area)) {
908 return EINVAL;
909 }
910
911 LosTaskCB *taskCB = OsCurrTaskGet();
912 SCHEDULER_LOCK(intSave);
913 LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);
914 if (processCB->processMode != OS_USER_MODE) {
915 ret = EPERM;
916 goto OUT;
917 }
918
919 taskCB->userArea = (unsigned long)(uintptr_t)area;
920OUT:
921 SCHEDULER_UNLOCK(intSave);
922 return ret;
923}
924
926{
927 return (char *)(OsCurrTaskGet()->userArea);
928}
929
930int SysUserThreadSetDetach(unsigned int taskID)
931{
932 unsigned int intSave;
933 int ret;
934
935 if (OS_TID_CHECK_INVALID(taskID)) {
936 return EINVAL;
937 }
938
939 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
940 SCHEDULER_LOCK(intSave);
942 if (ret != LOS_OK) {
943 goto EXIT;
944 }
945
946 ret = (int)OsTaskSetDetachUnsafe(taskCB);
947
948EXIT:
949 SCHEDULER_UNLOCK(intSave);
950 return ret;
951}
952
953int SysUserThreadDetach(unsigned int taskID)
954{
955 unsigned int intSave;
956 int ret;
957
958 if (OS_TID_CHECK_INVALID(taskID)) {
959 return EINVAL;
960 }
961
962 SCHEDULER_LOCK(intSave);
963 ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
964 SCHEDULER_UNLOCK(intSave);
965 if (ret != LOS_OK) {
966 return ret;
967 }
968
969 if (LOS_TaskDelete(taskID) != LOS_OK) {
970 return ESRCH;
971 }
972
973 return LOS_OK;
974}
975
976int SysThreadJoin(unsigned int taskID)
977{
978 unsigned int intSave;
979 int ret;
980
981 if (OS_TID_CHECK_INVALID(taskID)) {
982 return EINVAL;
983 }
984
985 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
986 SCHEDULER_LOCK(intSave);
988 if (ret != LOS_OK) {
989 goto EXIT;
990 }
991
992 ret = (int)OsTaskJoinPendUnsafe(OS_TCB_FROM_TID(taskID));
993
994EXIT:
995 SCHEDULER_UNLOCK(intSave);
996 return ret;
997}
998
999void SysUserExitGroup(int status)
1000{
1001 (void)status;
1003}
1004
1005void SysThreadExit(int status)
1006{
1007 OsRunningTaskToExit(OsCurrTaskGet(), (unsigned int)status);
1008}
1009
1010/*!
1011 * @brief SysFutex 操作用户态快速互斥锁
1012 * 系统调用
1013 * @param absTime 绝对时间
1014 * @param flags 操作标识(FUTEX_WAKE | FUTEX_WAIT)
1015 * @param newUserAddr FUTEX_REQUEUE下调整后带回新的用户空间地址
1016 * @param uAddr 用户态下共享内存的地址,里面存放的是一个对齐的整型计数器
1017 * @param val
1018 * @return
1019 *
1020 * @see
1021 */
1022int SysFutex(const unsigned int *uAddr, unsigned int flags, int val,
1023 unsigned int absTime, const unsigned int *newUserAddr)
1024{
1025 if ((flags & FUTEX_MASK) == FUTEX_REQUEUE) {//调整队列标识
1026 return -OsFutexRequeue(uAddr, flags, val, absTime, newUserAddr);
1027 }
1028
1029 if ((flags & FUTEX_MASK) == FUTEX_WAKE) {//唤醒标识
1030 return -OsFutexWake(uAddr, flags, val);//最多唤醒val个等待在uaddr上进程
1031 }
1032 //FUTEX_WAIT
1033 return -OsFutexWait(uAddr, flags, val, absTime);//设置线程等待 原子性的检查uaddr中计数器的值是否为val,
1034 //如果是则让进程休眠,直到FUTEX_WAKE或者超时(time-out)。也就是把进程挂到uaddr相对应的等待队列上去。
1035}
1036///获取当前任务ID
1037unsigned int SysGetTid(void)
1038{
1039 return OsCurrTaskGet()->taskID;
1040}
1041
1042/* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */
1043static int SchedAffinityParameterPreprocess(int id, int flag, unsigned int *taskID, unsigned int *processID)
1044{
1045 if (flag >= 0) {
1046 if (OS_PID_CHECK_INVALID(id)) {
1047 return -ESRCH;
1048 }
1049 *taskID = (id == 0) ? (OsCurrTaskGet()->taskID) : (OS_PCB_FROM_PID((UINT32)id)->threadGroupID);
1050 *processID = (id == 0) ? (OS_TCB_FROM_TID(*taskID)->processID) : id;
1051 } else {
1052 if (OS_TID_CHECK_INVALID(id)) {
1053 return -ESRCH;
1054 }
1055 *taskID = id;
1056 *processID = OS_INVALID_VALUE;
1057 }
1058 return LOS_OK;
1059}
1060
1061/* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */
1062int SysSchedGetAffinity(int id, unsigned int *cpuset, int flag)
1063{
1064 int ret;
1065 unsigned int processID;
1066 unsigned int taskID;
1067 unsigned int intSave;
1068 unsigned int cpuAffiMask;
1069
1070 ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID);
1071 if (ret != LOS_OK) {
1072 return ret;
1073 }
1074
1075 SCHEDULER_LOCK(intSave);
1076 if (flag >= 0) {
1077 if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) {
1078 SCHEDULER_UNLOCK(intSave);
1079 return -ESRCH;
1080 }
1081 } else {
1082 ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
1083 if (ret != LOS_OK) {
1084 SCHEDULER_UNLOCK(intSave);
1085 if (ret == EINVAL) {
1086 return -ESRCH;
1087 }
1088 return -ret;
1089 }
1090 }
1091
1092#ifdef LOSCFG_KERNEL_SMP
1093 cpuAffiMask = (unsigned int)OS_TCB_FROM_TID(taskID)->cpuAffiMask;
1094#else
1095 cpuAffiMask = 1;
1096#endif /* LOSCFG_KERNEL_SMP */
1097
1098 SCHEDULER_UNLOCK(intSave);
1099 ret = LOS_ArchCopyToUser(cpuset, &cpuAffiMask, sizeof(unsigned int));
1100 if (ret != LOS_OK) {
1101 return -EFAULT;
1102 }
1103
1104 return LOS_OK;
1105}
1106
1107/* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */
1108int SysSchedSetAffinity(int id, const unsigned short cpuset, int flag)
1109{
1110 int ret;
1111 unsigned int processID;
1112 unsigned int taskID;
1113 unsigned int intSave;
1114 unsigned short currCpuMask;
1115 bool needSched = FALSE;
1116
1117 if (cpuset > LOSCFG_KERNEL_CPU_MASK) {
1118 return -EINVAL;
1119 }
1120
1121 ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID);
1122 if (ret != LOS_OK) {
1123 return ret;
1124 }
1125
1126 if (flag >= 0) {
1127 ret = OsPermissionToCheck(processID, LOS_GetCurrProcessID());
1128 if (ret != LOS_OK) {
1129 return ret;
1130 }
1131 SCHEDULER_LOCK(intSave);
1132 if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) {
1133 SCHEDULER_UNLOCK(intSave);
1134 return -ESRCH;
1135 }
1136 } else {
1137 SCHEDULER_LOCK(intSave);
1138 ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID));
1139 if (ret != LOS_OK) {
1140 SCHEDULER_UNLOCK(intSave);
1141 if (ret == EINVAL) {
1142 return -ESRCH;
1143 }
1144 return -ret;
1145 }
1146 }
1147
1148 needSched = OsTaskCpuAffiSetUnsafe(taskID, cpuset, &currCpuMask);
1149 SCHEDULER_UNLOCK(intSave);
1150 if (needSched && OS_SCHEDULER_ACTIVE) {
1151 LOS_MpSchedule(currCpuMask);
1152 LOS_Schedule();
1153 }
1154
1155 return LOS_OK;
1156}
1157
BOOL IsCapPermit(UINT32 capIndex)
Definition: capability.c:43
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
Definition: los_memory.c:1123
UINT8 * m_aucSysMem1
系统动态内存池地址的起始地址 @note_thinking 能否不要用 0,1来命名核心变量 ???
Definition: los_memory.c:108
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
Definition: los_memory.c:1369
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID)
Delete a task.
Definition: los_task.c:968
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
Change the scheduling sequence of tasks with the same priority.
Definition: los_task.c:1115
VOID LOS_Schedule(VOID)
Trigger active task scheduling.
Definition: los_sched.c:469
VOID *(* TSK_ENTRY_FUNC)(UINTPTR param1, UINTPTR param2, UINTPTR param3, UINTPTR param4)
Define the type of a task entrance function.
Definition: los_task.h:480
INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime)
设置线程等待 | 向Futex表中插入代表被阻塞的线程的node
Definition: los_futex.c:693
INT32 OsFutexRequeue(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber, INT32 count, const UINT32 *newUserVaddr)
调整指定锁在Futex表中的位置
Definition: los_futex.c:1022
INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber)
唤醒一个被指定锁阻塞的线程
Definition: los_futex.c:815
VOID LOS_MpSchedule(UINT32 target)
Definition: los_mp.c:76
LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
接口封装 - 获取进程优先级 which:标识进程,进程组,用户
Definition: los_process.c:1055
LITE_OS_SEC_TEXT UINT32 OsGetUserInitProcessID(VOID)
获取用户态进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的
Definition: los_process.c:2244
LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
设置进程调度计划
Definition: los_process.c:983
LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID)
Definition: los_process.c:826
LITE_OS_SEC_TEXT INT32 LOS_Waitid(INT32 pid, USER siginfo_t *info, UINT32 options, VOID *rusage)
Definition: los_process.c:1350
LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid)
获得指定进程的调度策略
Definition: los_process.c:1030
LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID)
Definition: los_process.c:842
LITE_OS_SEC_TEXT INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, VOID *rusage)
Definition: los_process.c:1313
LITE_OS_SEC_TEXT INT32 LOS_GetProcessGroupID(UINT32 pid)
Definition: los_process.c:1461
LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID)
Definition: los_process.c:2200
LITE_OS_SEC_TEXT INT32 OsSetProcessGroupID(UINT32 pid, UINT32 gid)
Definition: los_process.c:1439
LITE_OS_SEC_TEXT INT32 LOS_GetCurrProcessGroupID(VOID)
获取当前进程的组ID
Definition: los_process.c:1485
LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size)
OsClone 进程克隆
Definition: los_process.c:2049
LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID)
获取当前进程的进程ID
Definition: los_process.c:2161
STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB)
进程不活跃函数定义:身上贴有不使用且不活跃标签的进程
STATIC INLINE User * OsCurrUserGet(VOID)
STATIC INLINE LosProcessCB * OsCurrProcessGet(VOID)
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB)
LITE_OS_SEC_TEXT BOOL OsTaskCpuAffiSetUnsafe(UINT32 taskID, UINT16 newCpuAffiMask, UINT16 *oldCpuAffiMask)
CPU亲和性(affinity)将任务绑在指定CPU上,用于多核CPU情况,(该函数仅在SMP模式下支持)
Definition: los_task.c:1212
LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
挂起任务,任务进入等待链表,Join代表是支持通过一个任务去唤醒其他的任务
Definition: los_task.c:224
INT32 OsUserTaskOperatePermissionsCheck(const LosTaskCB *taskCB)
Definition: los_task.c:1380
LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB)
任务设置分离模式 Deatch和JOIN是一对有你没我的状态
Definition: los_task.c:243
LITE_OS_SEC_TEXT VOID OsRunningTaskToExit(LosTaskCB *runTask, UINT32 status)
Definition: los_task.c:908
LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam)
创建一个用户态任务
Definition: los_task.c:1434
unsigned int UINT32
Definition: los_typedef.h:57
STATIC INLINE BOOL LOS_IsUserAddress(VADDR_T vaddr)
虚拟地址是否在用户空间
Definition: los_vm_map.h:275
static int OsUserTaskSchedulerSet(unsigned int tid, unsigned short policy, unsigned short priority, bool policyFlag)
设置用户级任务调度信息
int SysGetProcessGroupID(unsigned int pid)
获取指定进程的组ID,为0时返回当前进程ID
void SysUserExitGroup(int status)
int SysGetCurrProcessGroupID(void)
获取当前进程组ID
int SysGetRealEffSaveGroupID(int *rgid, int *egid, int *sgid)
int SysSchedGetPriorityMin(int policy)
int SysThreadJoin(unsigned int taskID)
static int OsPermissionToCheck(unsigned int pid, unsigned int who)
static int GetGroups(int size, int list[])
int SysGetRealEffSaveUserID(int *ruid, int *euid, int *suid)
int SysSetGroupID(int gid)
int SysSchedGetAffinity(int id, unsigned int *cpuset, int flag)
static int SetRealEffSaveGroupIDCheck(int rgid, int egid, int sgid)
unsigned int SysCreateUserThread(const TSK_ENTRY_FUNC func, const UserTaskParam *userParam, bool joinable)
int SysSetThreadArea(const char *area)
int SysSchedSetParam(int id, unsigned int prio, int flag)
int SysSetGroups(int size, const int list[])
int SysGetProcessPriority(int which, int who)
int SysSchedSetScheduler(int id, int policy, int prio, int flag)
unsigned int SysGetPPID(void)
int SysSchedGetParam(int id, int flag)
int SysSetRealEffSaveUserID(int ruid, int euid, int suid)
static int SetRealEffSaveUserIDCheck(int ruid, int euid, int suid)
static int SchedAffinityParameterPreprocess(int id, int flag, unsigned int *taskID, unsigned int *processID)
int SysGetEffGID(void)
unsigned int SysGetTid(void)
获取当前任务ID
void SysSchedYield(int type)
int SysFutex(const unsigned int *uAddr, unsigned int flags, int val, unsigned int absTime, const unsigned int *newUserAddr)
SysFutex 操作用户态快速互斥锁 系统调用
char * SysGetThreadArea(void)
int SysWaitid(idtype_t type, int pid, USER siginfo_t *info, int options, void *rusage)
int SysGetUserID(void)
获取用户ID
int SysGetEffUserID(void)
int SysUserThreadDetach(unsigned int taskID)
unsigned int SysGetPID(void)
int SysSetRealEffSaveGroupID(int rgid, int egid, int sgid)
int SysSetRealEffUserID(int ruid, int euid)
int SysWait(int pid, USER int *status, int options, void *rusage)
int SysSetUserID(int uid)
static int SetGroups(int listSize, const int *safeList, int size)
int SysSchedGetPriorityMax(int policy)
int SysSetRealEffGroupID(int rgid, int egid)
int SysGetGroupID(void)
int SysSchedSetAffinity(int id, const unsigned short cpuset, int flag)
int SysGetGroups(int size, int list[])
int SysSchedGetScheduler(int id, int flag)
int SysFork(void)
int SysSchedRRGetInterval(int pid, struct timespec *tp)
int SysVfork(void)
int SysSetProcessPriority(int which, int who, unsigned int prio)
void SysThreadExit(int status)
int SysUserThreadSetDetach(unsigned int taskID)
int SysSetProcessGroupID(unsigned int pid, unsigned int gid)
为指定进程设置进程组ID
UINT16 processMode
User * user
进程的拥有者
LOS_DL_LIST threadSiblingList
UINT32 parentProcessID
BOOL(* schedParamModify)(LosTaskCB *taskCB, const SchedParam *param)
修改调度参数
UINT32(* schedParamGet)(const LosTaskCB *taskCB, SchedParam *param)
获取调度参数
UINT16 policy
UINT16 priority
UINT32 timeSlice
UINT32 taskID
UINT32 processID
const SchedOps * ops
UINTPTR userArea
用户空间的堆区开始位置
UINT32 groupNumber
用户组数量
UINT32 groups[1]
UINT32 effUserID
UINT32 userID
用户ID [0,60000],0为root用户
UINT32 gid
用户组ID [0,60000],0为root用户组
UINT32 effGid
TSK_ENTRY_FUNC pfnTaskEntry
Definition: los_task.h:504
UserTaskParam userParam
任务用户态运行时任何参数
Definition: los_task.h:517
UINT32 uwResved
Definition: los_task.h:513
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 ARG_NUM_0 ARG_NUM_2 ARG_NUM_1 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_4 ARG_NUM_5 ARG_NUM_6 ARG_NUM_3 ARG_NUM_5 ARG_NUM_7 ARG_NUM_1 ARG_NUM_4 ARG_NUM_5 ARG_NUM_4 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_7 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_7 ARG_NUM_3 ARG_NUM_2 char ARG_NUM_2 ARG_NUM_1 ARG_NUM_0 ARG_NUM_0 ARG_NUM_3 void ARG_NUM_1 ARG_NUM_0 unsigned ARG_NUM_0 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_5 ARG_NUM_3 ARG_NUM_3 ARG_NUM_4 ARG_NUM_1 ARG_NUM_1 ARG_NUM_3 ARG_NUM_2 ARG_NUM_1 ARG_NUM_4 ARG_NUM_4 ARG_NUM_5 ARG_NUM_3 ARG_NUM_2 void ARG_NUM_6 unsigned ARG_NUM_0 unsigned ARG_NUM_0 ARG_NUM_3 ARG_NUM_3 ARG_NUM_2 ARG_NUM_2 ARG_NUM_1 ARG_NUM_2 ARG_NUM_1 char ARG_NUM_0 ARG_NUM_4 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_4 ARG_NUM_5 ARG_NUM_2 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_6 ARG_NUM_6 ARG_NUM_5 ARG_NUM_3 void ARG_NUM_3 ARG_NUM_3 ARG_NUM_5 ARG_NUM_1 unsigned ARG_NUM_3 long
ARG_NUM_3 int
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void
size_t LOS_ArchCopyToUser(void *dst, const void *src, size_t len)
从内核空间拷贝到用户空间
Definition: user_copy.c:79
size_t LOS_ArchCopyFromUser(void *dst, const void *src, size_t len)
Definition: user_copy.c:58