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, &param);
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, &param);
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, &param);
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(&param, userParam, sizeof(LosSchedParam)) != 0) {
1900d163575Sopenharmony_ci        return -EFAULT;
1910d163575Sopenharmony_ci    }
1920d163575Sopenharmony_ci
1930d163575Sopenharmony_ci    if (flag < 0) {
1940d163575Sopenharmony_ci        return -OsUserTaskSchedulerSet(id, policy, &param, 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, &param);
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, &param);
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(&param, userParam, sizeof(LosSchedParam)) != 0) {
3080d163575Sopenharmony_ci            return -EFAULT;
3090d163575Sopenharmony_ci        }
3100d163575Sopenharmony_ci        return -OsUserTaskSchedulerSet(id, LOS_SCHED_RR, &param, 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, &param);
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, &param);
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