10d163575Sopenharmony_ci/* 20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 30d163575Sopenharmony_ci * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. 40d163575Sopenharmony_ci * 50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 60d163575Sopenharmony_ci * are permitted provided that the following conditions are met: 70d163575Sopenharmony_ci * 80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 90d163575Sopenharmony_ci * conditions and the following disclaimer. 100d163575Sopenharmony_ci * 110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 120d163575Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 130d163575Sopenharmony_ci * provided with the distribution. 140d163575Sopenharmony_ci * 150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 160d163575Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 170d163575Sopenharmony_ci * permission. 180d163575Sopenharmony_ci * 190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 300d163575Sopenharmony_ci */ 310d163575Sopenharmony_ci 320d163575Sopenharmony_ci#include "los_process_pri.h" 330d163575Sopenharmony_ci#include "los_task_pri.h" 340d163575Sopenharmony_ci#include "los_sched_pri.h" 350d163575Sopenharmony_ci#include "los_hw_pri.h" 360d163575Sopenharmony_ci#include "los_sys_pri.h" 370d163575Sopenharmony_ci#include "los_futex_pri.h" 380d163575Sopenharmony_ci#include "los_mp.h" 390d163575Sopenharmony_ci#include "sys/wait.h" 400d163575Sopenharmony_ci#include "user_copy.h" 410d163575Sopenharmony_ci#include "time.h" 420d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 430d163575Sopenharmony_ci#include "capability_api.h" 440d163575Sopenharmony_ci#endif 450d163575Sopenharmony_ci 460d163575Sopenharmony_cistatic int OsPermissionToCheck(unsigned int pid, unsigned int who) 470d163575Sopenharmony_ci{ 480d163575Sopenharmony_ci uintptr_t pgroupID = 0; 490d163575Sopenharmony_ci unsigned int ret = OsGetProcessGroupCB(pid, &pgroupID); 500d163575Sopenharmony_ci if (ret != 0) { 510d163575Sopenharmony_ci return -ret; 520d163575Sopenharmony_ci } else if (pgroupID == OS_KERNEL_PROCESS_GROUP) { 530d163575Sopenharmony_ci return -EPERM; 540d163575Sopenharmony_ci } else if ((pgroupID == OS_USER_PRIVILEGE_PROCESS_GROUP) && (pid != who)) { 550d163575Sopenharmony_ci return -EPERM; 560d163575Sopenharmony_ci } else if ((UINTPTR)OS_PCB_FROM_PID(pid) == OS_USER_PRIVILEGE_PROCESS_GROUP) { 570d163575Sopenharmony_ci return -EPERM; 580d163575Sopenharmony_ci } 590d163575Sopenharmony_ci 600d163575Sopenharmony_ci return 0; 610d163575Sopenharmony_ci} 620d163575Sopenharmony_ci 630d163575Sopenharmony_cistatic int UserTaskSchedulerCheck(unsigned int tid, int policy, const LosSchedParam *schedParam, bool policyFlag) 640d163575Sopenharmony_ci{ 650d163575Sopenharmony_ci int ret; 660d163575Sopenharmony_ci int processPolicy; 670d163575Sopenharmony_ci 680d163575Sopenharmony_ci if (OS_TID_CHECK_INVALID(tid)) { 690d163575Sopenharmony_ci return EINVAL; 700d163575Sopenharmony_ci } 710d163575Sopenharmony_ci 720d163575Sopenharmony_ci ret = OsSchedulerParamCheck(policy, TRUE, schedParam); 730d163575Sopenharmony_ci if (ret != 0) { 740d163575Sopenharmony_ci return ret; 750d163575Sopenharmony_ci } 760d163575Sopenharmony_ci 770d163575Sopenharmony_ci if (policyFlag) { 780d163575Sopenharmony_ci ret = LOS_GetProcessScheduler(LOS_GetCurrProcessID(), &processPolicy, NULL); 790d163575Sopenharmony_ci if (ret < 0) { 800d163575Sopenharmony_ci return -ret; 810d163575Sopenharmony_ci } 820d163575Sopenharmony_ci if ((processPolicy != LOS_SCHED_DEADLINE) && (policy == LOS_SCHED_DEADLINE)) { 830d163575Sopenharmony_ci return EPERM; 840d163575Sopenharmony_ci } else if ((processPolicy == LOS_SCHED_DEADLINE) && (policy != LOS_SCHED_DEADLINE)) { 850d163575Sopenharmony_ci return EPERM; 860d163575Sopenharmony_ci } 870d163575Sopenharmony_ci } 880d163575Sopenharmony_ci return 0; 890d163575Sopenharmony_ci} 900d163575Sopenharmony_ci 910d163575Sopenharmony_cistatic int OsUserTaskSchedulerSet(unsigned int tid, int policy, const LosSchedParam *schedParam, bool policyFlag) 920d163575Sopenharmony_ci{ 930d163575Sopenharmony_ci int ret; 940d163575Sopenharmony_ci unsigned int intSave; 950d163575Sopenharmony_ci bool needSched = false; 960d163575Sopenharmony_ci SchedParam param = { 0 }; 970d163575Sopenharmony_ci 980d163575Sopenharmony_ci ret = UserTaskSchedulerCheck(tid, policy, schedParam, policyFlag); 990d163575Sopenharmony_ci if (ret != 0) { 1000d163575Sopenharmony_ci return ret; 1010d163575Sopenharmony_ci } 1020d163575Sopenharmony_ci 1030d163575Sopenharmony_ci LosTaskCB *taskCB = OS_TCB_FROM_TID(tid); 1040d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 1050d163575Sopenharmony_ci ret = OsUserTaskOperatePermissionsCheck(taskCB); 1060d163575Sopenharmony_ci if (ret != LOS_OK) { 1070d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 1080d163575Sopenharmony_ci return ret; 1090d163575Sopenharmony_ci } 1100d163575Sopenharmony_ci 1110d163575Sopenharmony_ci taskCB->ops->schedParamGet(taskCB, ¶m); 1120d163575Sopenharmony_ci param.policy = (policyFlag == true) ? (UINT16)policy : param.policy; 1130d163575Sopenharmony_ci if ((param.policy == LOS_SCHED_RR) || (param.policy == LOS_SCHED_FIFO)) { 1140d163575Sopenharmony_ci param.priority = schedParam->priority; 1150d163575Sopenharmony_ci } else if (param.policy == LOS_SCHED_DEADLINE) { 1160d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 1170d163575Sopenharmony_ci /* user mode process with privilege of CAP_SCHED_SETPRIORITY can change the priority */ 1180d163575Sopenharmony_ci if (!IsCapPermit(CAP_SCHED_SETPRIORITY)) { 1190d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 1200d163575Sopenharmony_ci return EPERM; 1210d163575Sopenharmony_ci } 1220d163575Sopenharmony_ci#endif 1230d163575Sopenharmony_ci param.runTimeUs = schedParam->runTimeUs; 1240d163575Sopenharmony_ci param.deadlineUs = schedParam->deadlineUs; 1250d163575Sopenharmony_ci param.periodUs = schedParam->periodUs; 1260d163575Sopenharmony_ci } 1270d163575Sopenharmony_ci 1280d163575Sopenharmony_ci needSched = taskCB->ops->schedParamModify(taskCB, ¶m); 1290d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 1300d163575Sopenharmony_ci 1310d163575Sopenharmony_ci LOS_MpSchedule(OS_MP_CPU_ALL); 1320d163575Sopenharmony_ci if (needSched && OS_SCHEDULER_ACTIVE) { 1330d163575Sopenharmony_ci LOS_Schedule(); 1340d163575Sopenharmony_ci } 1350d163575Sopenharmony_ci 1360d163575Sopenharmony_ci return LOS_OK; 1370d163575Sopenharmony_ci} 1380d163575Sopenharmony_ci 1390d163575Sopenharmony_civoid SysSchedYield(int type) 1400d163575Sopenharmony_ci{ 1410d163575Sopenharmony_ci (void)type; 1420d163575Sopenharmony_ci 1430d163575Sopenharmony_ci (void)LOS_TaskYield(); 1440d163575Sopenharmony_ci return; 1450d163575Sopenharmony_ci} 1460d163575Sopenharmony_ci 1470d163575Sopenharmony_ciint SysSchedGetScheduler(int id, int flag) 1480d163575Sopenharmony_ci{ 1490d163575Sopenharmony_ci unsigned int intSave; 1500d163575Sopenharmony_ci SchedParam param = { 0 }; 1510d163575Sopenharmony_ci int policy; 1520d163575Sopenharmony_ci int ret; 1530d163575Sopenharmony_ci 1540d163575Sopenharmony_ci if (flag < 0) { 1550d163575Sopenharmony_ci if (OS_TID_CHECK_INVALID(id)) { 1560d163575Sopenharmony_ci return -EINVAL; 1570d163575Sopenharmony_ci } 1580d163575Sopenharmony_ci 1590d163575Sopenharmony_ci LosTaskCB *taskCB = OS_TCB_FROM_TID(id); 1600d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 1610d163575Sopenharmony_ci ret = OsUserTaskOperatePermissionsCheck(taskCB); 1620d163575Sopenharmony_ci if (ret != LOS_OK) { 1630d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 1640d163575Sopenharmony_ci return -ret; 1650d163575Sopenharmony_ci } 1660d163575Sopenharmony_ci 1670d163575Sopenharmony_ci taskCB->ops->schedParamGet(taskCB, ¶m); 1680d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 1690d163575Sopenharmony_ci return (int)param.policy; 1700d163575Sopenharmony_ci } 1710d163575Sopenharmony_ci 1720d163575Sopenharmony_ci if (id == 0) { 1730d163575Sopenharmony_ci id = (int)LOS_GetCurrProcessID(); 1740d163575Sopenharmony_ci } 1750d163575Sopenharmony_ci 1760d163575Sopenharmony_ci ret = LOS_GetProcessScheduler(id, &policy, NULL); 1770d163575Sopenharmony_ci if (ret < 0) { 1780d163575Sopenharmony_ci return ret; 1790d163575Sopenharmony_ci } 1800d163575Sopenharmony_ci 1810d163575Sopenharmony_ci return policy; 1820d163575Sopenharmony_ci} 1830d163575Sopenharmony_ci 1840d163575Sopenharmony_ciint SysSchedSetScheduler(int id, int policy, const LosSchedParam *userParam, int flag) 1850d163575Sopenharmony_ci{ 1860d163575Sopenharmony_ci int ret; 1870d163575Sopenharmony_ci LosSchedParam param; 1880d163575Sopenharmony_ci 1890d163575Sopenharmony_ci if (LOS_ArchCopyFromUser(¶m, userParam, sizeof(LosSchedParam)) != 0) { 1900d163575Sopenharmony_ci return -EFAULT; 1910d163575Sopenharmony_ci } 1920d163575Sopenharmony_ci 1930d163575Sopenharmony_ci if (flag < 0) { 1940d163575Sopenharmony_ci return -OsUserTaskSchedulerSet(id, policy, ¶m, true); 1950d163575Sopenharmony_ci } 1960d163575Sopenharmony_ci 1970d163575Sopenharmony_ci if (policy == LOS_SCHED_RR) { 1980d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_PLIMITS 1990d163575Sopenharmony_ci if (param.priority < OsPidLimitGetPriorityLimit()) { 2000d163575Sopenharmony_ci return -EINVAL; 2010d163575Sopenharmony_ci } 2020d163575Sopenharmony_ci#else 2030d163575Sopenharmony_ci if (param.priority < OS_USER_PROCESS_PRIORITY_HIGHEST) { 2040d163575Sopenharmony_ci return -EINVAL; 2050d163575Sopenharmony_ci } 2060d163575Sopenharmony_ci#endif 2070d163575Sopenharmony_ci } 2080d163575Sopenharmony_ci 2090d163575Sopenharmony_ci if (id == 0) { 2100d163575Sopenharmony_ci id = (int)LOS_GetCurrProcessID(); 2110d163575Sopenharmony_ci } 2120d163575Sopenharmony_ci 2130d163575Sopenharmony_ci ret = OsPermissionToCheck(id, LOS_GetCurrProcessID()); 2140d163575Sopenharmony_ci if (ret < 0) { 2150d163575Sopenharmony_ci return ret; 2160d163575Sopenharmony_ci } 2170d163575Sopenharmony_ci 2180d163575Sopenharmony_ci return OsSetProcessScheduler(LOS_PRIO_PROCESS, id, policy, ¶m); 2190d163575Sopenharmony_ci} 2200d163575Sopenharmony_ci 2210d163575Sopenharmony_ciint SysSchedGetParam(int id, LosSchedParam *userParam, int flag) 2220d163575Sopenharmony_ci{ 2230d163575Sopenharmony_ci LosSchedParam schedParam = {0}; 2240d163575Sopenharmony_ci SchedParam param = { 0 }; 2250d163575Sopenharmony_ci unsigned int intSave; 2260d163575Sopenharmony_ci int ret; 2270d163575Sopenharmony_ci 2280d163575Sopenharmony_ci if (flag < 0) { 2290d163575Sopenharmony_ci if (OS_TID_CHECK_INVALID(id)) { 2300d163575Sopenharmony_ci return -EINVAL; 2310d163575Sopenharmony_ci } 2320d163575Sopenharmony_ci 2330d163575Sopenharmony_ci LosTaskCB *taskCB = OS_TCB_FROM_TID(id); 2340d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 2350d163575Sopenharmony_ci ret = OsUserTaskOperatePermissionsCheck(taskCB); 2360d163575Sopenharmony_ci if (ret != LOS_OK) { 2370d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 2380d163575Sopenharmony_ci return -ret; 2390d163575Sopenharmony_ci } 2400d163575Sopenharmony_ci 2410d163575Sopenharmony_ci taskCB->ops->schedParamGet(taskCB, ¶m); 2420d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 2430d163575Sopenharmony_ci if (param.policy == LOS_SCHED_DEADLINE) { 2440d163575Sopenharmony_ci schedParam.runTimeUs = param.runTimeUs; 2450d163575Sopenharmony_ci schedParam.deadlineUs = param.deadlineUs; 2460d163575Sopenharmony_ci schedParam.periodUs = param.periodUs; 2470d163575Sopenharmony_ci } else { 2480d163575Sopenharmony_ci schedParam.priority = param.priority; 2490d163575Sopenharmony_ci } 2500d163575Sopenharmony_ci } else { 2510d163575Sopenharmony_ci if (id == 0) { 2520d163575Sopenharmony_ci id = (int)LOS_GetCurrProcessID(); 2530d163575Sopenharmony_ci } 2540d163575Sopenharmony_ci 2550d163575Sopenharmony_ci if (OS_PID_CHECK_INVALID(id)) { 2560d163575Sopenharmony_ci return -EINVAL; 2570d163575Sopenharmony_ci } 2580d163575Sopenharmony_ci 2590d163575Sopenharmony_ci ret = LOS_GetProcessScheduler(id, NULL, &schedParam); 2600d163575Sopenharmony_ci if (ret < 0) { 2610d163575Sopenharmony_ci return ret; 2620d163575Sopenharmony_ci } 2630d163575Sopenharmony_ci } 2640d163575Sopenharmony_ci 2650d163575Sopenharmony_ci if (LOS_ArchCopyToUser(userParam, &schedParam, sizeof(LosSchedParam))) { 2660d163575Sopenharmony_ci return -EFAULT; 2670d163575Sopenharmony_ci } 2680d163575Sopenharmony_ci return 0; 2690d163575Sopenharmony_ci} 2700d163575Sopenharmony_ci 2710d163575Sopenharmony_ciint SysSetProcessPriority(int which, int who, int prio) 2720d163575Sopenharmony_ci{ 2730d163575Sopenharmony_ci int ret; 2740d163575Sopenharmony_ci 2750d163575Sopenharmony_ci if (which != LOS_PRIO_PROCESS) { 2760d163575Sopenharmony_ci return -EINVAL; 2770d163575Sopenharmony_ci } 2780d163575Sopenharmony_ci 2790d163575Sopenharmony_ci if (who == 0) { 2800d163575Sopenharmony_ci who = (int)LOS_GetCurrProcessID(); 2810d163575Sopenharmony_ci } 2820d163575Sopenharmony_ci 2830d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_PLIMITS 2840d163575Sopenharmony_ci if (prio < OsPidLimitGetPriorityLimit()) { 2850d163575Sopenharmony_ci return -EINVAL; 2860d163575Sopenharmony_ci } 2870d163575Sopenharmony_ci#else 2880d163575Sopenharmony_ci if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) { 2890d163575Sopenharmony_ci return -EINVAL; 2900d163575Sopenharmony_ci } 2910d163575Sopenharmony_ci#endif 2920d163575Sopenharmony_ci 2930d163575Sopenharmony_ci ret = OsPermissionToCheck(who, LOS_GetCurrProcessID()); 2940d163575Sopenharmony_ci if (ret < 0) { 2950d163575Sopenharmony_ci return ret; 2960d163575Sopenharmony_ci } 2970d163575Sopenharmony_ci 2980d163575Sopenharmony_ci return LOS_SetProcessPriority(who, prio); 2990d163575Sopenharmony_ci} 3000d163575Sopenharmony_ci 3010d163575Sopenharmony_ciint SysSchedSetParam(int id, const LosSchedParam *userParam, int flag) 3020d163575Sopenharmony_ci{ 3030d163575Sopenharmony_ci int ret, policy; 3040d163575Sopenharmony_ci LosSchedParam param; 3050d163575Sopenharmony_ci 3060d163575Sopenharmony_ci if (flag < 0) { 3070d163575Sopenharmony_ci if (LOS_ArchCopyFromUser(¶m, userParam, sizeof(LosSchedParam)) != 0) { 3080d163575Sopenharmony_ci return -EFAULT; 3090d163575Sopenharmony_ci } 3100d163575Sopenharmony_ci return -OsUserTaskSchedulerSet(id, LOS_SCHED_RR, ¶m, false); 3110d163575Sopenharmony_ci } 3120d163575Sopenharmony_ci 3130d163575Sopenharmony_ci if (id == 0) { 3140d163575Sopenharmony_ci id = (int)LOS_GetCurrProcessID(); 3150d163575Sopenharmony_ci } 3160d163575Sopenharmony_ci 3170d163575Sopenharmony_ci ret = LOS_GetProcessScheduler(id, &policy, NULL); 3180d163575Sopenharmony_ci if (ret < 0) { 3190d163575Sopenharmony_ci return ret; 3200d163575Sopenharmony_ci } 3210d163575Sopenharmony_ci 3220d163575Sopenharmony_ci return SysSchedSetScheduler(id, policy, userParam, flag); 3230d163575Sopenharmony_ci} 3240d163575Sopenharmony_ci 3250d163575Sopenharmony_ciint SysGetProcessPriority(int which, int who) 3260d163575Sopenharmony_ci{ 3270d163575Sopenharmony_ci if (who == 0) { 3280d163575Sopenharmony_ci who = (int)LOS_GetCurrProcessID(); 3290d163575Sopenharmony_ci } 3300d163575Sopenharmony_ci 3310d163575Sopenharmony_ci return OsGetProcessPriority(which, who); 3320d163575Sopenharmony_ci} 3330d163575Sopenharmony_ci 3340d163575Sopenharmony_ciint SysSchedGetPriorityMin(int policy) 3350d163575Sopenharmony_ci{ 3360d163575Sopenharmony_ci if (policy != LOS_SCHED_RR) { 3370d163575Sopenharmony_ci return -EINVAL; 3380d163575Sopenharmony_ci } 3390d163575Sopenharmony_ci 3400d163575Sopenharmony_ci return OS_USER_PROCESS_PRIORITY_HIGHEST; 3410d163575Sopenharmony_ci} 3420d163575Sopenharmony_ci 3430d163575Sopenharmony_ciint SysSchedGetPriorityMax(int policy) 3440d163575Sopenharmony_ci{ 3450d163575Sopenharmony_ci if (policy != LOS_SCHED_RR) { 3460d163575Sopenharmony_ci return -EINVAL; 3470d163575Sopenharmony_ci } 3480d163575Sopenharmony_ci 3490d163575Sopenharmony_ci return OS_USER_PROCESS_PRIORITY_LOWEST; 3500d163575Sopenharmony_ci} 3510d163575Sopenharmony_ci 3520d163575Sopenharmony_ciint SysSchedRRGetInterval(int pid, struct timespec *tp) 3530d163575Sopenharmony_ci{ 3540d163575Sopenharmony_ci unsigned int intSave; 3550d163575Sopenharmony_ci int ret; 3560d163575Sopenharmony_ci SchedParam param = { 0 }; 3570d163575Sopenharmony_ci time_t timeSlice = 0; 3580d163575Sopenharmony_ci struct timespec tv = { 0 }; 3590d163575Sopenharmony_ci LosTaskCB *taskCB = NULL; 3600d163575Sopenharmony_ci LosProcessCB *processCB = NULL; 3610d163575Sopenharmony_ci 3620d163575Sopenharmony_ci if (tp == NULL) { 3630d163575Sopenharmony_ci return -EINVAL; 3640d163575Sopenharmony_ci } 3650d163575Sopenharmony_ci 3660d163575Sopenharmony_ci if (OS_PID_CHECK_INVALID(pid)) { 3670d163575Sopenharmony_ci return -EINVAL; 3680d163575Sopenharmony_ci } 3690d163575Sopenharmony_ci 3700d163575Sopenharmony_ci if (pid == 0) { 3710d163575Sopenharmony_ci processCB = OsCurrProcessGet(); 3720d163575Sopenharmony_ci } else { 3730d163575Sopenharmony_ci processCB = OS_PCB_FROM_PID(pid); 3740d163575Sopenharmony_ci } 3750d163575Sopenharmony_ci 3760d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 3770d163575Sopenharmony_ci /* if can not find process by pid return ESRCH */ 3780d163575Sopenharmony_ci if (OsProcessIsInactive(processCB)) { 3790d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 3800d163575Sopenharmony_ci return -ESRCH; 3810d163575Sopenharmony_ci } 3820d163575Sopenharmony_ci 3830d163575Sopenharmony_ci LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { 3840d163575Sopenharmony_ci if (!OsTaskIsInactive(taskCB)) { 3850d163575Sopenharmony_ci taskCB->ops->schedParamGet(taskCB, ¶m); 3860d163575Sopenharmony_ci if (param.policy == LOS_SCHED_RR) { 3870d163575Sopenharmony_ci timeSlice += param.timeSlice; 3880d163575Sopenharmony_ci } 3890d163575Sopenharmony_ci } 3900d163575Sopenharmony_ci } 3910d163575Sopenharmony_ci 3920d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 3930d163575Sopenharmony_ci 3940d163575Sopenharmony_ci timeSlice = timeSlice * OS_NS_PER_CYCLE; 3950d163575Sopenharmony_ci tv.tv_sec = timeSlice / OS_SYS_NS_PER_SECOND; 3960d163575Sopenharmony_ci tv.tv_nsec = timeSlice % OS_SYS_NS_PER_SECOND; 3970d163575Sopenharmony_ci ret = LOS_ArchCopyToUser(tp, &tv, sizeof(struct timespec)); 3980d163575Sopenharmony_ci if (ret != 0) { 3990d163575Sopenharmony_ci return -EFAULT; 4000d163575Sopenharmony_ci } 4010d163575Sopenharmony_ci 4020d163575Sopenharmony_ci return 0; 4030d163575Sopenharmony_ci} 4040d163575Sopenharmony_ci 4050d163575Sopenharmony_ciint SysWait(int pid, USER int *status, int options, void *rusage) 4060d163575Sopenharmony_ci{ 4070d163575Sopenharmony_ci (void)rusage; 4080d163575Sopenharmony_ci 4090d163575Sopenharmony_ci return LOS_Wait(pid, status, (unsigned int)options, NULL); 4100d163575Sopenharmony_ci} 4110d163575Sopenharmony_ci 4120d163575Sopenharmony_ciint SysWaitid(idtype_t type, int pid, USER siginfo_t *info, int options, void *rusage) 4130d163575Sopenharmony_ci{ 4140d163575Sopenharmony_ci (void)rusage; 4150d163575Sopenharmony_ci int ret; 4160d163575Sopenharmony_ci int truepid = 0; 4170d163575Sopenharmony_ci 4180d163575Sopenharmony_ci switch (type) { 4190d163575Sopenharmony_ci case P_ALL: 4200d163575Sopenharmony_ci /* Wait for any child; id is ignored. */ 4210d163575Sopenharmony_ci truepid = -1; 4220d163575Sopenharmony_ci break; 4230d163575Sopenharmony_ci case P_PID: 4240d163575Sopenharmony_ci /* Wait for the child whose process ID matches id */ 4250d163575Sopenharmony_ci if (pid <= 0) { 4260d163575Sopenharmony_ci return -EINVAL; 4270d163575Sopenharmony_ci } 4280d163575Sopenharmony_ci truepid = pid; 4290d163575Sopenharmony_ci break; 4300d163575Sopenharmony_ci case P_PGID: 4310d163575Sopenharmony_ci /* Wait for any child whose process group ID matches id */ 4320d163575Sopenharmony_ci if (pid <= 1) { 4330d163575Sopenharmony_ci return -EINVAL; 4340d163575Sopenharmony_ci } 4350d163575Sopenharmony_ci truepid = -pid; 4360d163575Sopenharmony_ci break; 4370d163575Sopenharmony_ci default: 4380d163575Sopenharmony_ci return -EINVAL; 4390d163575Sopenharmony_ci } 4400d163575Sopenharmony_ci 4410d163575Sopenharmony_ci ret = LOS_Waitid(truepid, info, (unsigned int)options, NULL); 4420d163575Sopenharmony_ci if (ret > 0) { 4430d163575Sopenharmony_ci ret = 0; 4440d163575Sopenharmony_ci } 4450d163575Sopenharmony_ci return ret; 4460d163575Sopenharmony_ci} 4470d163575Sopenharmony_ci 4480d163575Sopenharmony_ciint SysFork(void) 4490d163575Sopenharmony_ci{ 4500d163575Sopenharmony_ci return OsClone(0, 0, 0); 4510d163575Sopenharmony_ci} 4520d163575Sopenharmony_ci 4530d163575Sopenharmony_ciint SysVfork(void) 4540d163575Sopenharmony_ci{ 4550d163575Sopenharmony_ci return OsClone(CLONE_VFORK, 0, 0); 4560d163575Sopenharmony_ci} 4570d163575Sopenharmony_ci 4580d163575Sopenharmony_ciint SysClone(int flags, void *stack, int *parentTid, unsigned long tls, int *childTid) 4590d163575Sopenharmony_ci{ 4600d163575Sopenharmony_ci (void)parentTid; 4610d163575Sopenharmony_ci (void)tls; 4620d163575Sopenharmony_ci (void)childTid; 4630d163575Sopenharmony_ci 4640d163575Sopenharmony_ci return OsClone((UINT32)flags, (UINTPTR)stack, 0); 4650d163575Sopenharmony_ci} 4660d163575Sopenharmony_ci 4670d163575Sopenharmony_ciint SysUnshare(int flags) 4680d163575Sopenharmony_ci{ 4690d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_CONTAINER 4700d163575Sopenharmony_ci return OsUnshare(flags); 4710d163575Sopenharmony_ci#else 4720d163575Sopenharmony_ci return -ENOSYS; 4730d163575Sopenharmony_ci#endif 4740d163575Sopenharmony_ci} 4750d163575Sopenharmony_ci 4760d163575Sopenharmony_ciint SysSetns(int fd, int type) 4770d163575Sopenharmony_ci{ 4780d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_CONTAINER 4790d163575Sopenharmony_ci return OsSetNs(fd, type); 4800d163575Sopenharmony_ci#else 4810d163575Sopenharmony_ci return -ENOSYS; 4820d163575Sopenharmony_ci#endif 4830d163575Sopenharmony_ci} 4840d163575Sopenharmony_ci 4850d163575Sopenharmony_ciunsigned int SysGetPPID(void) 4860d163575Sopenharmony_ci{ 4870d163575Sopenharmony_ci#ifdef LOSCFG_PID_CONTAINER 4880d163575Sopenharmony_ci if (OsCurrProcessGet()->processID == OS_USER_ROOT_PROCESS_ID) { 4890d163575Sopenharmony_ci return 0; 4900d163575Sopenharmony_ci } 4910d163575Sopenharmony_ci#endif 4920d163575Sopenharmony_ci return OsCurrProcessGet()->parentProcess->processID; 4930d163575Sopenharmony_ci} 4940d163575Sopenharmony_ci 4950d163575Sopenharmony_ciunsigned int SysGetPID(void) 4960d163575Sopenharmony_ci{ 4970d163575Sopenharmony_ci return LOS_GetCurrProcessID(); 4980d163575Sopenharmony_ci} 4990d163575Sopenharmony_ci 5000d163575Sopenharmony_ciint SysSetProcessGroupID(unsigned int pid, unsigned int gid) 5010d163575Sopenharmony_ci{ 5020d163575Sopenharmony_ci int ret; 5030d163575Sopenharmony_ci 5040d163575Sopenharmony_ci if (pid == 0) { 5050d163575Sopenharmony_ci pid = LOS_GetCurrProcessID(); 5060d163575Sopenharmony_ci } 5070d163575Sopenharmony_ci 5080d163575Sopenharmony_ci if (gid == 0) { 5090d163575Sopenharmony_ci gid = pid; 5100d163575Sopenharmony_ci } 5110d163575Sopenharmony_ci 5120d163575Sopenharmony_ci ret = OsPermissionToCheck(pid, gid); 5130d163575Sopenharmony_ci if (ret < 0) { 5140d163575Sopenharmony_ci return ret; 5150d163575Sopenharmony_ci } 5160d163575Sopenharmony_ci 5170d163575Sopenharmony_ci return OsSetProcessGroupID(pid, gid); 5180d163575Sopenharmony_ci} 5190d163575Sopenharmony_ci 5200d163575Sopenharmony_ciint SysGetProcessGroupID(unsigned int pid) 5210d163575Sopenharmony_ci{ 5220d163575Sopenharmony_ci if (pid == 0) { 5230d163575Sopenharmony_ci pid = LOS_GetCurrProcessID(); 5240d163575Sopenharmony_ci } 5250d163575Sopenharmony_ci 5260d163575Sopenharmony_ci return LOS_GetProcessGroupID(pid); 5270d163575Sopenharmony_ci} 5280d163575Sopenharmony_ci 5290d163575Sopenharmony_ciint SysGetCurrProcessGroupID(void) 5300d163575Sopenharmony_ci{ 5310d163575Sopenharmony_ci return LOS_GetCurrProcessGroupID(); 5320d163575Sopenharmony_ci} 5330d163575Sopenharmony_ci 5340d163575Sopenharmony_ciint SysGetUserID(void) 5350d163575Sopenharmony_ci{ 5360d163575Sopenharmony_ci return LOS_GetUserID(); 5370d163575Sopenharmony_ci} 5380d163575Sopenharmony_ci 5390d163575Sopenharmony_ciint SysGetEffUserID(void) 5400d163575Sopenharmony_ci{ 5410d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 5420d163575Sopenharmony_ci UINT32 intSave; 5430d163575Sopenharmony_ci int euid; 5440d163575Sopenharmony_ci 5450d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 5460d163575Sopenharmony_ci#ifdef LOSCFG_USER_CONTAINER 5470d163575Sopenharmony_ci euid = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid); 5480d163575Sopenharmony_ci#else 5490d163575Sopenharmony_ci euid = (int)OsCurrUserGet()->effUserID; 5500d163575Sopenharmony_ci#endif 5510d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 5520d163575Sopenharmony_ci return euid; 5530d163575Sopenharmony_ci#else 5540d163575Sopenharmony_ci return 0; 5550d163575Sopenharmony_ci#endif 5560d163575Sopenharmony_ci} 5570d163575Sopenharmony_ci 5580d163575Sopenharmony_ciint SysGetEffGID(void) 5590d163575Sopenharmony_ci{ 5600d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 5610d163575Sopenharmony_ci UINT32 intSave; 5620d163575Sopenharmony_ci int egid; 5630d163575Sopenharmony_ci 5640d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 5650d163575Sopenharmony_ci#ifdef LOSCFG_USER_CONTAINER 5660d163575Sopenharmony_ci egid = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid); 5670d163575Sopenharmony_ci#else 5680d163575Sopenharmony_ci egid = (int)OsCurrUserGet()->effGid; 5690d163575Sopenharmony_ci#endif 5700d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 5710d163575Sopenharmony_ci return egid; 5720d163575Sopenharmony_ci#else 5730d163575Sopenharmony_ci return 0; 5740d163575Sopenharmony_ci#endif 5750d163575Sopenharmony_ci} 5760d163575Sopenharmony_ci 5770d163575Sopenharmony_ciint SysGetRealEffSaveUserID(int *ruid, int *euid, int *suid) 5780d163575Sopenharmony_ci{ 5790d163575Sopenharmony_ci int ret; 5800d163575Sopenharmony_ci int realUserID, effUserID, saveUserID; 5810d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 5820d163575Sopenharmony_ci unsigned int intSave; 5830d163575Sopenharmony_ci 5840d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 5850d163575Sopenharmony_ci#ifdef LOSCFG_USER_CONTAINER 5860d163575Sopenharmony_ci realUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->uid); 5870d163575Sopenharmony_ci effUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid); 5880d163575Sopenharmony_ci saveUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid); 5890d163575Sopenharmony_ci#else 5900d163575Sopenharmony_ci realUserID = OsCurrUserGet()->userID; 5910d163575Sopenharmony_ci effUserID = OsCurrUserGet()->effUserID; 5920d163575Sopenharmony_ci saveUserID = OsCurrUserGet()->effUserID; 5930d163575Sopenharmony_ci#endif 5940d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 5950d163575Sopenharmony_ci#else 5960d163575Sopenharmony_ci realUserID = 0; 5970d163575Sopenharmony_ci effUserID = 0; 5980d163575Sopenharmony_ci saveUserID = 0; 5990d163575Sopenharmony_ci#endif 6000d163575Sopenharmony_ci 6010d163575Sopenharmony_ci ret = LOS_ArchCopyToUser(ruid, &realUserID, sizeof(int)); 6020d163575Sopenharmony_ci if (ret != 0) { 6030d163575Sopenharmony_ci return -EFAULT; 6040d163575Sopenharmony_ci } 6050d163575Sopenharmony_ci 6060d163575Sopenharmony_ci ret = LOS_ArchCopyToUser(euid, &effUserID, sizeof(int)); 6070d163575Sopenharmony_ci if (ret != 0) { 6080d163575Sopenharmony_ci return -EFAULT; 6090d163575Sopenharmony_ci } 6100d163575Sopenharmony_ci 6110d163575Sopenharmony_ci ret = LOS_ArchCopyToUser(suid, &saveUserID, sizeof(int)); 6120d163575Sopenharmony_ci if (ret != 0) { 6130d163575Sopenharmony_ci return -EFAULT; 6140d163575Sopenharmony_ci } 6150d163575Sopenharmony_ci 6160d163575Sopenharmony_ci return 0; 6170d163575Sopenharmony_ci} 6180d163575Sopenharmony_ci 6190d163575Sopenharmony_ci#ifdef LOSCFG_USER_CONTAINER 6200d163575Sopenharmony_cilong SysSetUserID(int uid) 6210d163575Sopenharmony_ci{ 6220d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 6230d163575Sopenharmony_ci UserContainer *userContainer = CurrentCredentials()->userContainer; 6240d163575Sopenharmony_ci int retval = -EPERM; 6250d163575Sopenharmony_ci unsigned int intSave; 6260d163575Sopenharmony_ci 6270d163575Sopenharmony_ci if (uid < 0) { 6280d163575Sopenharmony_ci return -EINVAL; 6290d163575Sopenharmony_ci } 6300d163575Sopenharmony_ci 6310d163575Sopenharmony_ci UINT32 kuid = OsMakeKuid(userContainer, uid); 6320d163575Sopenharmony_ci if (kuid == (UINT32)-1) { 6330d163575Sopenharmony_ci return -EINVAL; 6340d163575Sopenharmony_ci } 6350d163575Sopenharmony_ci 6360d163575Sopenharmony_ci Credentials *newCredentials = PrepareCredential(OsCurrProcessGet()); 6370d163575Sopenharmony_ci if (newCredentials == NULL) { 6380d163575Sopenharmony_ci return -ENOMEM; 6390d163575Sopenharmony_ci } 6400d163575Sopenharmony_ci 6410d163575Sopenharmony_ci Credentials *oldCredentials = CurrentCredentials(); 6420d163575Sopenharmony_ci 6430d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 6440d163575Sopenharmony_ci User *user = OsCurrUserGet(); 6450d163575Sopenharmony_ci if (IsCapPermit(CAP_SETUID)) { 6460d163575Sopenharmony_ci newCredentials->uid = kuid; 6470d163575Sopenharmony_ci if (kuid != oldCredentials->uid) { 6480d163575Sopenharmony_ci user->userID = kuid; 6490d163575Sopenharmony_ci user->effUserID = kuid; 6500d163575Sopenharmony_ci } 6510d163575Sopenharmony_ci retval = LOS_OK; 6520d163575Sopenharmony_ci } else if (kuid != oldCredentials->uid) { 6530d163575Sopenharmony_ci goto ERROR; 6540d163575Sopenharmony_ci } 6550d163575Sopenharmony_ci newCredentials->euid = kuid; 6560d163575Sopenharmony_ci 6570d163575Sopenharmony_ci retval = CommitCredentials(newCredentials); 6580d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 6590d163575Sopenharmony_ci return retval; 6600d163575Sopenharmony_ci 6610d163575Sopenharmony_ciERROR: 6620d163575Sopenharmony_ci FreeCredential(newCredentials); 6630d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 6640d163575Sopenharmony_ci return retval; 6650d163575Sopenharmony_ci#else 6660d163575Sopenharmony_ci if (uid != 0) { 6670d163575Sopenharmony_ci return -EPERM; 6680d163575Sopenharmony_ci } 6690d163575Sopenharmony_ci return 0; 6700d163575Sopenharmony_ci#endif 6710d163575Sopenharmony_ci} 6720d163575Sopenharmony_ci 6730d163575Sopenharmony_ci#else 6740d163575Sopenharmony_ci 6750d163575Sopenharmony_ciint SysSetUserID(int uid) 6760d163575Sopenharmony_ci{ 6770d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 6780d163575Sopenharmony_ci int ret = -EPERM; 6790d163575Sopenharmony_ci unsigned int intSave; 6800d163575Sopenharmony_ci 6810d163575Sopenharmony_ci if (uid < 0) { 6820d163575Sopenharmony_ci return -EINVAL; 6830d163575Sopenharmony_ci } 6840d163575Sopenharmony_ci 6850d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 6860d163575Sopenharmony_ci User *user = OsCurrUserGet(); 6870d163575Sopenharmony_ci if (IsCapPermit(CAP_SETUID)) { 6880d163575Sopenharmony_ci user->userID = uid; 6890d163575Sopenharmony_ci user->effUserID = uid; 6900d163575Sopenharmony_ci /* add process to a user */ 6910d163575Sopenharmony_ci } else if (user->userID != uid) { 6920d163575Sopenharmony_ci goto EXIT; 6930d163575Sopenharmony_ci } 6940d163575Sopenharmony_ci 6950d163575Sopenharmony_ci ret = LOS_OK; 6960d163575Sopenharmony_ci /* add process to a user */ 6970d163575Sopenharmony_ciEXIT: 6980d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 6990d163575Sopenharmony_ci return ret; 7000d163575Sopenharmony_ci#else 7010d163575Sopenharmony_ci if (uid != 0) { 7020d163575Sopenharmony_ci return -EPERM; 7030d163575Sopenharmony_ci } 7040d163575Sopenharmony_ci 7050d163575Sopenharmony_ci return 0; 7060d163575Sopenharmony_ci#endif 7070d163575Sopenharmony_ci} 7080d163575Sopenharmony_ci#endif 7090d163575Sopenharmony_ci 7100d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 7110d163575Sopenharmony_cistatic int SetRealEffSaveUserIDCheck(int ruid, int euid, int suid) 7120d163575Sopenharmony_ci{ 7130d163575Sopenharmony_ci if ((ruid < 0) && (ruid != -1)) { 7140d163575Sopenharmony_ci return -EINVAL; 7150d163575Sopenharmony_ci } 7160d163575Sopenharmony_ci 7170d163575Sopenharmony_ci if ((euid < 0) && (euid != -1)) { 7180d163575Sopenharmony_ci return -EINVAL; 7190d163575Sopenharmony_ci } 7200d163575Sopenharmony_ci 7210d163575Sopenharmony_ci if ((suid < 0) && (suid != -1)) { 7220d163575Sopenharmony_ci return -EINVAL; 7230d163575Sopenharmony_ci } 7240d163575Sopenharmony_ci 7250d163575Sopenharmony_ci return 0; 7260d163575Sopenharmony_ci} 7270d163575Sopenharmony_ci#endif 7280d163575Sopenharmony_ci 7290d163575Sopenharmony_ciint SysSetRealEffSaveUserID(int ruid, int euid, int suid) 7300d163575Sopenharmony_ci{ 7310d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 7320d163575Sopenharmony_ci int ret; 7330d163575Sopenharmony_ci 7340d163575Sopenharmony_ci if ((ruid == -1) && (euid == -1) && (suid == -1)) { 7350d163575Sopenharmony_ci return 0; 7360d163575Sopenharmony_ci } 7370d163575Sopenharmony_ci 7380d163575Sopenharmony_ci ret = SetRealEffSaveUserIDCheck(ruid, euid, suid); 7390d163575Sopenharmony_ci if (ret != 0) { 7400d163575Sopenharmony_ci return ret; 7410d163575Sopenharmony_ci } 7420d163575Sopenharmony_ci 7430d163575Sopenharmony_ci if (ruid >= 0) { 7440d163575Sopenharmony_ci if (((euid != -1) && (euid != ruid)) || ((suid != -1) && (suid != ruid))) { 7450d163575Sopenharmony_ci return -EPERM; 7460d163575Sopenharmony_ci } 7470d163575Sopenharmony_ci return SysSetUserID(ruid); 7480d163575Sopenharmony_ci } else if (euid >= 0) { 7490d163575Sopenharmony_ci if ((suid != -1) && (suid != euid)) { 7500d163575Sopenharmony_ci return -EPERM; 7510d163575Sopenharmony_ci } 7520d163575Sopenharmony_ci return SysSetUserID(euid); 7530d163575Sopenharmony_ci } else { 7540d163575Sopenharmony_ci return SysSetUserID(suid); 7550d163575Sopenharmony_ci } 7560d163575Sopenharmony_ci#else 7570d163575Sopenharmony_ci if ((ruid != 0) || (euid != 0) || (suid != 0)) { 7580d163575Sopenharmony_ci return -EPERM; 7590d163575Sopenharmony_ci } 7600d163575Sopenharmony_ci return 0; 7610d163575Sopenharmony_ci#endif 7620d163575Sopenharmony_ci} 7630d163575Sopenharmony_ci 7640d163575Sopenharmony_ciint SysSetRealEffUserID(int ruid, int euid) 7650d163575Sopenharmony_ci{ 7660d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 7670d163575Sopenharmony_ci return SysSetRealEffSaveUserID(ruid, euid, -1); 7680d163575Sopenharmony_ci#else 7690d163575Sopenharmony_ci if ((ruid != 0) || (euid != 0)) { 7700d163575Sopenharmony_ci return -EPERM; 7710d163575Sopenharmony_ci } 7720d163575Sopenharmony_ci return 0; 7730d163575Sopenharmony_ci#endif 7740d163575Sopenharmony_ci} 7750d163575Sopenharmony_ci 7760d163575Sopenharmony_ci#ifdef LOSCFG_USER_CONTAINER 7770d163575Sopenharmony_ciint SysSetGroupID(int gid) 7780d163575Sopenharmony_ci{ 7790d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 7800d163575Sopenharmony_ci UserContainer *userContainer = CurrentCredentials()->userContainer; 7810d163575Sopenharmony_ci int retval = -EPERM; 7820d163575Sopenharmony_ci unsigned int oldGid; 7830d163575Sopenharmony_ci unsigned int intSave; 7840d163575Sopenharmony_ci int count; 7850d163575Sopenharmony_ci 7860d163575Sopenharmony_ci if (gid < 0) { 7870d163575Sopenharmony_ci return -EINVAL; 7880d163575Sopenharmony_ci } 7890d163575Sopenharmony_ci 7900d163575Sopenharmony_ci unsigned int kgid = OsMakeKgid(userContainer, gid); 7910d163575Sopenharmony_ci if (kgid == (UINT32)-1) { 7920d163575Sopenharmony_ci return -EINVAL; 7930d163575Sopenharmony_ci } 7940d163575Sopenharmony_ci 7950d163575Sopenharmony_ci Credentials *newCredentials = PrepareCredential(OsCurrProcessGet()); 7960d163575Sopenharmony_ci if (newCredentials == NULL) { 7970d163575Sopenharmony_ci return -ENOMEM; 7980d163575Sopenharmony_ci } 7990d163575Sopenharmony_ci 8000d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 8010d163575Sopenharmony_ci User *user = OsCurrUserGet(); 8020d163575Sopenharmony_ci if (IsCapPermit(CAP_SETGID)) { 8030d163575Sopenharmony_ci newCredentials->gid = kgid; 8040d163575Sopenharmony_ci newCredentials->egid = kgid; 8050d163575Sopenharmony_ci oldGid = user->gid; 8060d163575Sopenharmony_ci user->gid = kgid; 8070d163575Sopenharmony_ci user->effGid = kgid; 8080d163575Sopenharmony_ci for (count = 0; count < user->groupNumber; count++) { 8090d163575Sopenharmony_ci if (user->groups[count] == oldGid) { 8100d163575Sopenharmony_ci user->groups[count] = kgid; 8110d163575Sopenharmony_ci retval = LOS_OK; 8120d163575Sopenharmony_ci break; 8130d163575Sopenharmony_ci } 8140d163575Sopenharmony_ci } 8150d163575Sopenharmony_ci } else if (user->gid != kgid) { 8160d163575Sopenharmony_ci goto ERROR; 8170d163575Sopenharmony_ci } 8180d163575Sopenharmony_ci 8190d163575Sopenharmony_ci retval = CommitCredentials(newCredentials); 8200d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 8210d163575Sopenharmony_ci return retval; 8220d163575Sopenharmony_ci 8230d163575Sopenharmony_ciERROR: 8240d163575Sopenharmony_ci FreeCredential(newCredentials); 8250d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 8260d163575Sopenharmony_ci return retval; 8270d163575Sopenharmony_ci 8280d163575Sopenharmony_ci#else 8290d163575Sopenharmony_ci if (gid != 0) { 8300d163575Sopenharmony_ci return -EPERM; 8310d163575Sopenharmony_ci } 8320d163575Sopenharmony_ci return 0; 8330d163575Sopenharmony_ci#endif 8340d163575Sopenharmony_ci} 8350d163575Sopenharmony_ci#else 8360d163575Sopenharmony_ciint SysSetGroupID(int gid) 8370d163575Sopenharmony_ci{ 8380d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 8390d163575Sopenharmony_ci int ret = -EPERM; 8400d163575Sopenharmony_ci unsigned int intSave; 8410d163575Sopenharmony_ci unsigned int count; 8420d163575Sopenharmony_ci unsigned int oldGid; 8430d163575Sopenharmony_ci User *user = NULL; 8440d163575Sopenharmony_ci 8450d163575Sopenharmony_ci if (gid < 0) { 8460d163575Sopenharmony_ci return -EINVAL; 8470d163575Sopenharmony_ci } 8480d163575Sopenharmony_ci 8490d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 8500d163575Sopenharmony_ci user = OsCurrUserGet(); 8510d163575Sopenharmony_ci if (IsCapPermit(CAP_SETGID)) { 8520d163575Sopenharmony_ci oldGid = user->gid; 8530d163575Sopenharmony_ci user->gid = gid; 8540d163575Sopenharmony_ci user->effGid = gid; 8550d163575Sopenharmony_ci for (count = 0; count < user->groupNumber; count++) { 8560d163575Sopenharmony_ci if (user->groups[count] == oldGid) { 8570d163575Sopenharmony_ci user->groups[count] = gid; 8580d163575Sopenharmony_ci ret = LOS_OK; 8590d163575Sopenharmony_ci goto EXIT; 8600d163575Sopenharmony_ci } 8610d163575Sopenharmony_ci } 8620d163575Sopenharmony_ci } else if (user->gid != gid) { 8630d163575Sopenharmony_ci goto EXIT; 8640d163575Sopenharmony_ci } 8650d163575Sopenharmony_ci 8660d163575Sopenharmony_ci ret = LOS_OK; 8670d163575Sopenharmony_ci /* add process to a user */ 8680d163575Sopenharmony_ciEXIT: 8690d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 8700d163575Sopenharmony_ci return ret; 8710d163575Sopenharmony_ci 8720d163575Sopenharmony_ci#else 8730d163575Sopenharmony_ci if (gid != 0) { 8740d163575Sopenharmony_ci return -EPERM; 8750d163575Sopenharmony_ci } 8760d163575Sopenharmony_ci 8770d163575Sopenharmony_ci return 0; 8780d163575Sopenharmony_ci#endif 8790d163575Sopenharmony_ci} 8800d163575Sopenharmony_ci#endif 8810d163575Sopenharmony_ci 8820d163575Sopenharmony_ciint SysGetRealEffSaveGroupID(int *rgid, int *egid, int *sgid) 8830d163575Sopenharmony_ci{ 8840d163575Sopenharmony_ci int ret; 8850d163575Sopenharmony_ci int realGroupID, effGroupID, saveGroupID; 8860d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 8870d163575Sopenharmony_ci unsigned int intSave; 8880d163575Sopenharmony_ci 8890d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 8900d163575Sopenharmony_ci#ifdef LOSCFG_USER_CONTAINER 8910d163575Sopenharmony_ci realGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->gid); 8920d163575Sopenharmony_ci effGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid); 8930d163575Sopenharmony_ci saveGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid); 8940d163575Sopenharmony_ci#else 8950d163575Sopenharmony_ci realGroupID = OsCurrUserGet()->gid; 8960d163575Sopenharmony_ci effGroupID = OsCurrUserGet()->effGid; 8970d163575Sopenharmony_ci saveGroupID = OsCurrUserGet()->effGid; 8980d163575Sopenharmony_ci#endif 8990d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 9000d163575Sopenharmony_ci#else 9010d163575Sopenharmony_ci realGroupID = 0; 9020d163575Sopenharmony_ci effGroupID = 0; 9030d163575Sopenharmony_ci saveGroupID = 0; 9040d163575Sopenharmony_ci#endif 9050d163575Sopenharmony_ci 9060d163575Sopenharmony_ci ret = LOS_ArchCopyToUser(rgid, &realGroupID, sizeof(int)); 9070d163575Sopenharmony_ci if (ret != 0) { 9080d163575Sopenharmony_ci return -EFAULT; 9090d163575Sopenharmony_ci } 9100d163575Sopenharmony_ci 9110d163575Sopenharmony_ci ret = LOS_ArchCopyToUser(egid, &effGroupID, sizeof(int)); 9120d163575Sopenharmony_ci if (ret != 0) { 9130d163575Sopenharmony_ci return -EFAULT; 9140d163575Sopenharmony_ci } 9150d163575Sopenharmony_ci 9160d163575Sopenharmony_ci ret = LOS_ArchCopyToUser(sgid, &saveGroupID, sizeof(int)); 9170d163575Sopenharmony_ci if (ret != 0) { 9180d163575Sopenharmony_ci return -EFAULT; 9190d163575Sopenharmony_ci } 9200d163575Sopenharmony_ci 9210d163575Sopenharmony_ci return 0; 9220d163575Sopenharmony_ci} 9230d163575Sopenharmony_ci 9240d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 9250d163575Sopenharmony_cistatic int SetRealEffSaveGroupIDCheck(int rgid, int egid, int sgid) 9260d163575Sopenharmony_ci{ 9270d163575Sopenharmony_ci if ((rgid < 0) && (rgid != -1)) { 9280d163575Sopenharmony_ci return -EINVAL; 9290d163575Sopenharmony_ci } 9300d163575Sopenharmony_ci 9310d163575Sopenharmony_ci if ((egid < 0) && (egid != -1)) { 9320d163575Sopenharmony_ci return -EINVAL; 9330d163575Sopenharmony_ci } 9340d163575Sopenharmony_ci 9350d163575Sopenharmony_ci if ((sgid < 0) && (sgid != -1)) { 9360d163575Sopenharmony_ci return -EINVAL; 9370d163575Sopenharmony_ci } 9380d163575Sopenharmony_ci 9390d163575Sopenharmony_ci return 0; 9400d163575Sopenharmony_ci} 9410d163575Sopenharmony_ci#endif 9420d163575Sopenharmony_ci 9430d163575Sopenharmony_ciint SysSetRealEffSaveGroupID(int rgid, int egid, int sgid) 9440d163575Sopenharmony_ci{ 9450d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 9460d163575Sopenharmony_ci int ret; 9470d163575Sopenharmony_ci 9480d163575Sopenharmony_ci if ((rgid == -1) && (egid == -1) && (sgid == -1)) { 9490d163575Sopenharmony_ci return 0; 9500d163575Sopenharmony_ci } 9510d163575Sopenharmony_ci 9520d163575Sopenharmony_ci ret = SetRealEffSaveGroupIDCheck(rgid, egid, sgid); 9530d163575Sopenharmony_ci if (ret != 0) { 9540d163575Sopenharmony_ci return ret; 9550d163575Sopenharmony_ci } 9560d163575Sopenharmony_ci 9570d163575Sopenharmony_ci if (rgid >= 0) { 9580d163575Sopenharmony_ci if (((egid != -1) && (egid != rgid)) || ((sgid != -1) && (sgid != rgid))) { 9590d163575Sopenharmony_ci return -EPERM; 9600d163575Sopenharmony_ci } 9610d163575Sopenharmony_ci return SysSetGroupID(rgid); 9620d163575Sopenharmony_ci } else if (egid >= 0) { 9630d163575Sopenharmony_ci if ((sgid != -1) && (sgid != egid)) { 9640d163575Sopenharmony_ci return -EPERM; 9650d163575Sopenharmony_ci } 9660d163575Sopenharmony_ci return SysSetGroupID(egid); 9670d163575Sopenharmony_ci } else { 9680d163575Sopenharmony_ci return SysSetGroupID(sgid); 9690d163575Sopenharmony_ci } 9700d163575Sopenharmony_ci 9710d163575Sopenharmony_ci#else 9720d163575Sopenharmony_ci if ((rgid != 0) || (egid != 0) || (sgid != 0)) { 9730d163575Sopenharmony_ci return -EPERM; 9740d163575Sopenharmony_ci } 9750d163575Sopenharmony_ci return 0; 9760d163575Sopenharmony_ci#endif 9770d163575Sopenharmony_ci} 9780d163575Sopenharmony_ci 9790d163575Sopenharmony_ciint SysSetRealEffGroupID(int rgid, int egid) 9800d163575Sopenharmony_ci{ 9810d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 9820d163575Sopenharmony_ci return SysSetRealEffSaveGroupID(rgid, egid, -1); 9830d163575Sopenharmony_ci#else 9840d163575Sopenharmony_ci if ((rgid != 0) || (egid != 0)) { 9850d163575Sopenharmony_ci return -EPERM; 9860d163575Sopenharmony_ci } 9870d163575Sopenharmony_ci return 0; 9880d163575Sopenharmony_ci#endif 9890d163575Sopenharmony_ci} 9900d163575Sopenharmony_ci 9910d163575Sopenharmony_ciint SysGetGroupID(void) 9920d163575Sopenharmony_ci{ 9930d163575Sopenharmony_ci return LOS_GetGroupID(); 9940d163575Sopenharmony_ci} 9950d163575Sopenharmony_ci 9960d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 9970d163575Sopenharmony_cistatic int SetGroups(int listSize, const int *safeList, int size) 9980d163575Sopenharmony_ci{ 9990d163575Sopenharmony_ci User *oldUser = NULL; 10000d163575Sopenharmony_ci unsigned int intSave; 10010d163575Sopenharmony_ci 10020d163575Sopenharmony_ci User *newUser = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + listSize * sizeof(int)); 10030d163575Sopenharmony_ci if (newUser == NULL) { 10040d163575Sopenharmony_ci return -ENOMEM; 10050d163575Sopenharmony_ci } 10060d163575Sopenharmony_ci 10070d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 10080d163575Sopenharmony_ci oldUser = OsCurrUserGet(); 10090d163575Sopenharmony_ci (VOID)memcpy_s(newUser, sizeof(User), oldUser, sizeof(User)); 10100d163575Sopenharmony_ci if (safeList != NULL) { 10110d163575Sopenharmony_ci (VOID)memcpy_s(newUser->groups, size * sizeof(int), safeList, size * sizeof(int)); 10120d163575Sopenharmony_ci } 10130d163575Sopenharmony_ci if (listSize == size) { 10140d163575Sopenharmony_ci newUser->groups[listSize] = oldUser->gid; 10150d163575Sopenharmony_ci } 10160d163575Sopenharmony_ci 10170d163575Sopenharmony_ci newUser->groupNumber = listSize + 1; 10180d163575Sopenharmony_ci OsCurrProcessGet()->user = newUser; 10190d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 10200d163575Sopenharmony_ci 10210d163575Sopenharmony_ci (void)LOS_MemFree(m_aucSysMem1, oldUser); 10220d163575Sopenharmony_ci return 0; 10230d163575Sopenharmony_ci} 10240d163575Sopenharmony_ci 10250d163575Sopenharmony_cistatic int GetGroups(int size, int list[]) 10260d163575Sopenharmony_ci{ 10270d163575Sopenharmony_ci unsigned int intSave; 10280d163575Sopenharmony_ci int groupCount; 10290d163575Sopenharmony_ci int ret; 10300d163575Sopenharmony_ci int *safeList = NULL; 10310d163575Sopenharmony_ci unsigned int listSize; 10320d163575Sopenharmony_ci 10330d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 10340d163575Sopenharmony_ci groupCount = OsCurrUserGet()->groupNumber; 10350d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 10360d163575Sopenharmony_ci 10370d163575Sopenharmony_ci listSize = groupCount * sizeof(int); 10380d163575Sopenharmony_ci if (size == 0) { 10390d163575Sopenharmony_ci return groupCount; 10400d163575Sopenharmony_ci } else if (list == NULL) { 10410d163575Sopenharmony_ci return -EFAULT; 10420d163575Sopenharmony_ci } else if (size < groupCount) { 10430d163575Sopenharmony_ci return -EINVAL; 10440d163575Sopenharmony_ci } 10450d163575Sopenharmony_ci 10460d163575Sopenharmony_ci safeList = LOS_MemAlloc(m_aucSysMem1, listSize); 10470d163575Sopenharmony_ci if (safeList == NULL) { 10480d163575Sopenharmony_ci return -ENOMEM; 10490d163575Sopenharmony_ci } 10500d163575Sopenharmony_ci 10510d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 10520d163575Sopenharmony_ci (void)memcpy_s(safeList, listSize, &OsCurrProcessGet()->user->groups[0], listSize); 10530d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 10540d163575Sopenharmony_ci 10550d163575Sopenharmony_ci ret = LOS_ArchCopyToUser(list, safeList, listSize); 10560d163575Sopenharmony_ci if (ret != 0) { 10570d163575Sopenharmony_ci groupCount = -EFAULT; 10580d163575Sopenharmony_ci } 10590d163575Sopenharmony_ci 10600d163575Sopenharmony_ci (void)LOS_MemFree(m_aucSysMem1, safeList); 10610d163575Sopenharmony_ci return groupCount; 10620d163575Sopenharmony_ci} 10630d163575Sopenharmony_ci#endif 10640d163575Sopenharmony_ci 10650d163575Sopenharmony_ciint SysGetGroups(int size, int list[]) 10660d163575Sopenharmony_ci{ 10670d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 10680d163575Sopenharmony_ci return GetGroups(size, list); 10690d163575Sopenharmony_ci#else 10700d163575Sopenharmony_ci int group = 0; 10710d163575Sopenharmony_ci int groupCount = 1; 10720d163575Sopenharmony_ci int ret; 10730d163575Sopenharmony_ci 10740d163575Sopenharmony_ci if (size == 0) { 10750d163575Sopenharmony_ci return groupCount; 10760d163575Sopenharmony_ci } else if (list == NULL) { 10770d163575Sopenharmony_ci return -EFAULT; 10780d163575Sopenharmony_ci } else if (size < groupCount) { 10790d163575Sopenharmony_ci return -EINVAL; 10800d163575Sopenharmony_ci } 10810d163575Sopenharmony_ci 10820d163575Sopenharmony_ci ret = LOS_ArchCopyToUser(list, &group, sizeof(int)); 10830d163575Sopenharmony_ci if (ret != 0) { 10840d163575Sopenharmony_ci return -EFAULT; 10850d163575Sopenharmony_ci } 10860d163575Sopenharmony_ci 10870d163575Sopenharmony_ci return groupCount; 10880d163575Sopenharmony_ci#endif 10890d163575Sopenharmony_ci} 10900d163575Sopenharmony_ci 10910d163575Sopenharmony_ciint SysSetGroups(int size, const int list[]) 10920d163575Sopenharmony_ci{ 10930d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 10940d163575Sopenharmony_ci int ret; 10950d163575Sopenharmony_ci int gid; 10960d163575Sopenharmony_ci int listSize = size; 10970d163575Sopenharmony_ci unsigned int count; 10980d163575Sopenharmony_ci int *safeList = NULL; 10990d163575Sopenharmony_ci#endif 11000d163575Sopenharmony_ci 11010d163575Sopenharmony_ci if ((size != 0) && (list == NULL)) { 11020d163575Sopenharmony_ci return -EFAULT; 11030d163575Sopenharmony_ci } 11040d163575Sopenharmony_ci 11050d163575Sopenharmony_ci if ((size < 0) || (size > OS_GROUPS_NUMBER_MAX)) { 11060d163575Sopenharmony_ci return -EINVAL; 11070d163575Sopenharmony_ci } 11080d163575Sopenharmony_ci 11090d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 11100d163575Sopenharmony_ci if (!IsCapPermit(CAP_SETGID)) { 11110d163575Sopenharmony_ci return -EPERM; 11120d163575Sopenharmony_ci } 11130d163575Sopenharmony_ci 11140d163575Sopenharmony_ci if (size != 0) { 11150d163575Sopenharmony_ci safeList = LOS_MemAlloc(m_aucSysMem1, size * sizeof(int)); 11160d163575Sopenharmony_ci if (safeList == NULL) { 11170d163575Sopenharmony_ci return -ENOMEM; 11180d163575Sopenharmony_ci } 11190d163575Sopenharmony_ci 11200d163575Sopenharmony_ci ret = LOS_ArchCopyFromUser(safeList, list, size * sizeof(int)); 11210d163575Sopenharmony_ci if (ret != 0) { 11220d163575Sopenharmony_ci ret = -EFAULT; 11230d163575Sopenharmony_ci goto EXIT; 11240d163575Sopenharmony_ci } 11250d163575Sopenharmony_ci gid = OsCurrUserGet()->gid; 11260d163575Sopenharmony_ci for (count = 0; count < size; count++) { 11270d163575Sopenharmony_ci if (safeList[count] == gid) { 11280d163575Sopenharmony_ci listSize = size - 1; 11290d163575Sopenharmony_ci } else if (safeList[count] < 0) { 11300d163575Sopenharmony_ci ret = -EINVAL; 11310d163575Sopenharmony_ci goto EXIT; 11320d163575Sopenharmony_ci } 11330d163575Sopenharmony_ci } 11340d163575Sopenharmony_ci } 11350d163575Sopenharmony_ci 11360d163575Sopenharmony_ci ret = SetGroups(listSize, safeList, size); 11370d163575Sopenharmony_ciEXIT: 11380d163575Sopenharmony_ci if (safeList != NULL) { 11390d163575Sopenharmony_ci (void)LOS_MemFree(m_aucSysMem1, safeList); 11400d163575Sopenharmony_ci } 11410d163575Sopenharmony_ci 11420d163575Sopenharmony_ci return ret; 11430d163575Sopenharmony_ci#else 11440d163575Sopenharmony_ci return 0; 11450d163575Sopenharmony_ci#endif 11460d163575Sopenharmony_ci} 11470d163575Sopenharmony_ci 11480d163575Sopenharmony_ciunsigned int SysCreateUserThread(const TSK_ENTRY_FUNC func, const UserTaskParam *userParam, bool joinable) 11490d163575Sopenharmony_ci{ 11500d163575Sopenharmony_ci TSK_INIT_PARAM_S param = { 0 }; 11510d163575Sopenharmony_ci int ret; 11520d163575Sopenharmony_ci 11530d163575Sopenharmony_ci ret = LOS_ArchCopyFromUser(&(param.userParam), userParam, sizeof(UserTaskParam)); 11540d163575Sopenharmony_ci if (ret != 0) { 11550d163575Sopenharmony_ci return OS_INVALID_VALUE; 11560d163575Sopenharmony_ci } 11570d163575Sopenharmony_ci 11580d163575Sopenharmony_ci param.pfnTaskEntry = func; 11590d163575Sopenharmony_ci if (joinable == TRUE) { 11600d163575Sopenharmony_ci param.uwResved = LOS_TASK_ATTR_JOINABLE; 11610d163575Sopenharmony_ci } else { 11620d163575Sopenharmony_ci param.uwResved = LOS_TASK_STATUS_DETACHED; 11630d163575Sopenharmony_ci } 11640d163575Sopenharmony_ci 11650d163575Sopenharmony_ci return OsCreateUserTask(OS_INVALID_VALUE, ¶m); 11660d163575Sopenharmony_ci} 11670d163575Sopenharmony_ci 11680d163575Sopenharmony_ciint SysSetThreadArea(const char *area) 11690d163575Sopenharmony_ci{ 11700d163575Sopenharmony_ci unsigned int intSave; 11710d163575Sopenharmony_ci int ret = LOS_OK; 11720d163575Sopenharmony_ci 11730d163575Sopenharmony_ci if (!LOS_IsUserAddress((unsigned long)(uintptr_t)area)) { 11740d163575Sopenharmony_ci return EINVAL; 11750d163575Sopenharmony_ci } 11760d163575Sopenharmony_ci 11770d163575Sopenharmony_ci LosTaskCB *taskCB = OsCurrTaskGet(); 11780d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 11790d163575Sopenharmony_ci LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB); 11800d163575Sopenharmony_ci if (processCB->processMode != OS_USER_MODE) { 11810d163575Sopenharmony_ci ret = EPERM; 11820d163575Sopenharmony_ci goto OUT; 11830d163575Sopenharmony_ci } 11840d163575Sopenharmony_ci 11850d163575Sopenharmony_ci taskCB->userArea = (unsigned long)(uintptr_t)area; 11860d163575Sopenharmony_ciOUT: 11870d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 11880d163575Sopenharmony_ci return ret; 11890d163575Sopenharmony_ci} 11900d163575Sopenharmony_ci 11910d163575Sopenharmony_cichar *SysGetThreadArea(void) 11920d163575Sopenharmony_ci{ 11930d163575Sopenharmony_ci return (char *)(OsCurrTaskGet()->userArea); 11940d163575Sopenharmony_ci} 11950d163575Sopenharmony_ci 11960d163575Sopenharmony_ciint SysUserThreadSetDetach(unsigned int taskID) 11970d163575Sopenharmony_ci{ 11980d163575Sopenharmony_ci unsigned int intSave; 11990d163575Sopenharmony_ci int ret; 12000d163575Sopenharmony_ci 12010d163575Sopenharmony_ci if (OS_TID_CHECK_INVALID(taskID)) { 12020d163575Sopenharmony_ci return EINVAL; 12030d163575Sopenharmony_ci } 12040d163575Sopenharmony_ci 12050d163575Sopenharmony_ci LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); 12060d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 12070d163575Sopenharmony_ci ret = OsUserTaskOperatePermissionsCheck(taskCB); 12080d163575Sopenharmony_ci if (ret != LOS_OK) { 12090d163575Sopenharmony_ci goto EXIT; 12100d163575Sopenharmony_ci } 12110d163575Sopenharmony_ci 12120d163575Sopenharmony_ci ret = (int)OsTaskSetDetachUnsafe(taskCB); 12130d163575Sopenharmony_ci 12140d163575Sopenharmony_ciEXIT: 12150d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 12160d163575Sopenharmony_ci return ret; 12170d163575Sopenharmony_ci} 12180d163575Sopenharmony_ci 12190d163575Sopenharmony_ciint SysUserThreadDetach(unsigned int taskID) 12200d163575Sopenharmony_ci{ 12210d163575Sopenharmony_ci unsigned int intSave; 12220d163575Sopenharmony_ci int ret; 12230d163575Sopenharmony_ci 12240d163575Sopenharmony_ci if (OS_TID_CHECK_INVALID(taskID)) { 12250d163575Sopenharmony_ci return EINVAL; 12260d163575Sopenharmony_ci } 12270d163575Sopenharmony_ci 12280d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 12290d163575Sopenharmony_ci ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID)); 12300d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 12310d163575Sopenharmony_ci if (ret != LOS_OK) { 12320d163575Sopenharmony_ci return ret; 12330d163575Sopenharmony_ci } 12340d163575Sopenharmony_ci 12350d163575Sopenharmony_ci if (LOS_TaskDelete(taskID) != LOS_OK) { 12360d163575Sopenharmony_ci return ESRCH; 12370d163575Sopenharmony_ci } 12380d163575Sopenharmony_ci 12390d163575Sopenharmony_ci return LOS_OK; 12400d163575Sopenharmony_ci} 12410d163575Sopenharmony_ci 12420d163575Sopenharmony_ciint SysThreadJoin(unsigned int taskID) 12430d163575Sopenharmony_ci{ 12440d163575Sopenharmony_ci unsigned int intSave; 12450d163575Sopenharmony_ci int ret; 12460d163575Sopenharmony_ci 12470d163575Sopenharmony_ci if (OS_TID_CHECK_INVALID(taskID)) { 12480d163575Sopenharmony_ci return EINVAL; 12490d163575Sopenharmony_ci } 12500d163575Sopenharmony_ci 12510d163575Sopenharmony_ci LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); 12520d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 12530d163575Sopenharmony_ci ret = OsUserTaskOperatePermissionsCheck(taskCB); 12540d163575Sopenharmony_ci if (ret != LOS_OK) { 12550d163575Sopenharmony_ci goto EXIT; 12560d163575Sopenharmony_ci } 12570d163575Sopenharmony_ci 12580d163575Sopenharmony_ci ret = (int)OsTaskJoinPendUnsafe(OS_TCB_FROM_TID(taskID)); 12590d163575Sopenharmony_ci 12600d163575Sopenharmony_ciEXIT: 12610d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 12620d163575Sopenharmony_ci return ret; 12630d163575Sopenharmony_ci} 12640d163575Sopenharmony_ci 12650d163575Sopenharmony_civoid SysUserExitGroup(int status) 12660d163575Sopenharmony_ci{ 12670d163575Sopenharmony_ci (void)status; 12680d163575Sopenharmony_ci OsProcessThreadGroupDestroy(); 12690d163575Sopenharmony_ci} 12700d163575Sopenharmony_ci 12710d163575Sopenharmony_civoid SysThreadExit(int status) 12720d163575Sopenharmony_ci{ 12730d163575Sopenharmony_ci OsRunningTaskToExit(OsCurrTaskGet(), (unsigned int)status); 12740d163575Sopenharmony_ci} 12750d163575Sopenharmony_ci 12760d163575Sopenharmony_ciint SysFutex(const unsigned int *uAddr, unsigned int flags, int val, 12770d163575Sopenharmony_ci unsigned int absTime, const unsigned int *newUserAddr) 12780d163575Sopenharmony_ci{ 12790d163575Sopenharmony_ci if ((flags & FUTEX_MASK) == FUTEX_REQUEUE) { 12800d163575Sopenharmony_ci return -OsFutexRequeue(uAddr, flags, val, absTime, newUserAddr); 12810d163575Sopenharmony_ci } 12820d163575Sopenharmony_ci 12830d163575Sopenharmony_ci if ((flags & FUTEX_MASK) == FUTEX_WAKE) { 12840d163575Sopenharmony_ci return -OsFutexWake(uAddr, flags, val); 12850d163575Sopenharmony_ci } 12860d163575Sopenharmony_ci 12870d163575Sopenharmony_ci return -OsFutexWait(uAddr, flags, val, absTime); 12880d163575Sopenharmony_ci} 12890d163575Sopenharmony_ci 12900d163575Sopenharmony_ciunsigned int SysGetTid(void) 12910d163575Sopenharmony_ci{ 12920d163575Sopenharmony_ci return OsCurrTaskGet()->taskID; 12930d163575Sopenharmony_ci} 12940d163575Sopenharmony_ci 12950d163575Sopenharmony_ci/* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */ 12960d163575Sopenharmony_cistatic int SchedAffinityParameterPreprocess(int id, int flag, unsigned int *taskID, unsigned int *processID) 12970d163575Sopenharmony_ci{ 12980d163575Sopenharmony_ci if (flag >= 0) { 12990d163575Sopenharmony_ci if (OS_PID_CHECK_INVALID(id)) { 13000d163575Sopenharmony_ci return -ESRCH; 13010d163575Sopenharmony_ci } 13020d163575Sopenharmony_ci LosProcessCB *ProcessCB = OS_PCB_FROM_PID((UINT32)id); 13030d163575Sopenharmony_ci if (ProcessCB->threadGroup == NULL) { 13040d163575Sopenharmony_ci return -ESRCH; 13050d163575Sopenharmony_ci } 13060d163575Sopenharmony_ci *taskID = (id == 0) ? (OsCurrTaskGet()->taskID) : (ProcessCB->threadGroup->taskID); 13070d163575Sopenharmony_ci *processID = (id == 0) ? (OS_PCB_FROM_TID(*taskID)->processID) : id; 13080d163575Sopenharmony_ci } else { 13090d163575Sopenharmony_ci if (OS_TID_CHECK_INVALID(id)) { 13100d163575Sopenharmony_ci return -ESRCH; 13110d163575Sopenharmony_ci } 13120d163575Sopenharmony_ci *taskID = id; 13130d163575Sopenharmony_ci *processID = OS_INVALID_VALUE; 13140d163575Sopenharmony_ci } 13150d163575Sopenharmony_ci return LOS_OK; 13160d163575Sopenharmony_ci} 13170d163575Sopenharmony_ci 13180d163575Sopenharmony_ci/* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */ 13190d163575Sopenharmony_ciint SysSchedGetAffinity(int id, unsigned int *cpuset, int flag) 13200d163575Sopenharmony_ci{ 13210d163575Sopenharmony_ci int ret; 13220d163575Sopenharmony_ci unsigned int processID; 13230d163575Sopenharmony_ci unsigned int taskID; 13240d163575Sopenharmony_ci unsigned int intSave; 13250d163575Sopenharmony_ci unsigned int cpuAffiMask; 13260d163575Sopenharmony_ci 13270d163575Sopenharmony_ci ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID); 13280d163575Sopenharmony_ci if (ret != LOS_OK) { 13290d163575Sopenharmony_ci return ret; 13300d163575Sopenharmony_ci } 13310d163575Sopenharmony_ci 13320d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 13330d163575Sopenharmony_ci if (flag >= 0) { 13340d163575Sopenharmony_ci if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) { 13350d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 13360d163575Sopenharmony_ci return -ESRCH; 13370d163575Sopenharmony_ci } 13380d163575Sopenharmony_ci } else { 13390d163575Sopenharmony_ci ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID)); 13400d163575Sopenharmony_ci if (ret != LOS_OK) { 13410d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 13420d163575Sopenharmony_ci if (ret == EINVAL) { 13430d163575Sopenharmony_ci return -ESRCH; 13440d163575Sopenharmony_ci } 13450d163575Sopenharmony_ci return -ret; 13460d163575Sopenharmony_ci } 13470d163575Sopenharmony_ci } 13480d163575Sopenharmony_ci 13490d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_SMP 13500d163575Sopenharmony_ci cpuAffiMask = (unsigned int)OS_TCB_FROM_TID(taskID)->cpuAffiMask; 13510d163575Sopenharmony_ci#else 13520d163575Sopenharmony_ci cpuAffiMask = 1; 13530d163575Sopenharmony_ci#endif /* LOSCFG_KERNEL_SMP */ 13540d163575Sopenharmony_ci 13550d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 13560d163575Sopenharmony_ci ret = LOS_ArchCopyToUser(cpuset, &cpuAffiMask, sizeof(unsigned int)); 13570d163575Sopenharmony_ci if (ret != LOS_OK) { 13580d163575Sopenharmony_ci return -EFAULT; 13590d163575Sopenharmony_ci } 13600d163575Sopenharmony_ci 13610d163575Sopenharmony_ci return LOS_OK; 13620d163575Sopenharmony_ci} 13630d163575Sopenharmony_ci 13640d163575Sopenharmony_ci/* If flag >= 0, the process mode is used. If flag < 0, the thread mode is used. */ 13650d163575Sopenharmony_ciint SysSchedSetAffinity(int id, const unsigned short cpuset, int flag) 13660d163575Sopenharmony_ci{ 13670d163575Sopenharmony_ci int ret; 13680d163575Sopenharmony_ci unsigned int processID; 13690d163575Sopenharmony_ci unsigned int taskID; 13700d163575Sopenharmony_ci unsigned int intSave; 13710d163575Sopenharmony_ci unsigned short currCpuMask; 13720d163575Sopenharmony_ci bool needSched = FALSE; 13730d163575Sopenharmony_ci 13740d163575Sopenharmony_ci if (cpuset > LOSCFG_KERNEL_CPU_MASK) { 13750d163575Sopenharmony_ci return -EINVAL; 13760d163575Sopenharmony_ci } 13770d163575Sopenharmony_ci 13780d163575Sopenharmony_ci ret = SchedAffinityParameterPreprocess(id, flag, &taskID, &processID); 13790d163575Sopenharmony_ci if (ret != LOS_OK) { 13800d163575Sopenharmony_ci return ret; 13810d163575Sopenharmony_ci } 13820d163575Sopenharmony_ci 13830d163575Sopenharmony_ci if (flag >= 0) { 13840d163575Sopenharmony_ci ret = OsPermissionToCheck(processID, LOS_GetCurrProcessID()); 13850d163575Sopenharmony_ci if (ret != LOS_OK) { 13860d163575Sopenharmony_ci return ret; 13870d163575Sopenharmony_ci } 13880d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 13890d163575Sopenharmony_ci if (OsProcessIsInactive(OS_PCB_FROM_PID(processID))) { 13900d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 13910d163575Sopenharmony_ci return -ESRCH; 13920d163575Sopenharmony_ci } 13930d163575Sopenharmony_ci } else { 13940d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 13950d163575Sopenharmony_ci ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID)); 13960d163575Sopenharmony_ci if (ret != LOS_OK) { 13970d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 13980d163575Sopenharmony_ci if (ret == EINVAL) { 13990d163575Sopenharmony_ci return -ESRCH; 14000d163575Sopenharmony_ci } 14010d163575Sopenharmony_ci return -ret; 14020d163575Sopenharmony_ci } 14030d163575Sopenharmony_ci } 14040d163575Sopenharmony_ci 14050d163575Sopenharmony_ci needSched = OsTaskCpuAffiSetUnsafe(taskID, cpuset, &currCpuMask); 14060d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 14070d163575Sopenharmony_ci if (needSched && OS_SCHEDULER_ACTIVE) { 14080d163575Sopenharmony_ci LOS_MpSchedule(currCpuMask); 14090d163575Sopenharmony_ci LOS_Schedule(); 14100d163575Sopenharmony_ci } 14110d163575Sopenharmony_ci 14120d163575Sopenharmony_ci return LOS_OK; 14130d163575Sopenharmony_ci} 14140d163575Sopenharmony_ci 1415