diff --git a/fs/proc/os_adapt/process_proc.c b/fs/proc/os_adapt/process_proc.c index 8c18d38d3737083780cdd06a4ce3fa916f84fd6f..f85f0c046c76a6039845c8443edb916dd6d63440 100644 --- a/fs/proc/os_adapt/process_proc.c +++ b/fs/proc/os_adapt/process_proc.c @@ -212,7 +212,7 @@ static int ProcSetTimensOffset(const char *buf, LosProcessCB *processCB) char *endptr = NULL; offsets.tv_sec = strtoll(buf, &endptr, DECIMAL_BASE); - offsets.tv_sec = strtoll(endptr, NULL, DECIMAL_BASE); + offsets.tv_nsec = strtoll(endptr, NULL, DECIMAL_BASE); if (offsets.tv_nsec >= OS_SYS_NS_PER_SECOND) { return -EACCES; } @@ -308,7 +308,7 @@ static const struct ProcFileOperations PID_FOPS = { static struct ProcProcess g_procProcess[] = { { .name = NULL, - .mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, + .mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IROTH, .type = PROC_PID, .fileOps = &PID_FOPS diff --git a/kernel/base/container/los_container.c b/kernel/base/container/los_container.c index cf6ac418dbbb1a62b750b1f6917b5e42ffc31ce8..2c89e5953b211a14ddb131aa5f242d907eb8138f 100644 --- a/kernel/base/container/los_container.c +++ b/kernel/base/container/los_container.c @@ -84,27 +84,9 @@ STATIC INLINE Container *CreateContainer(VOID) return container; } -/* - * called from clone. This now handles copy for Container and all - * namespaces therein. - */ -UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID) +STATIC UINT32 CopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID) { - UINT32 intSave; UINT32 ret = LOS_OK; - - if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWTIME))) { - SCHEDULER_LOCK(intSave); - child->container = parent->container; - LOS_AtomicInc(&child->container->rc); - SCHEDULER_UNLOCK(intSave); - } else { - child->container = CreateContainer(); - if (child->container == NULL) { - return ENOMEM; - } - } - /* Pid container initialization must precede other container initialization. */ #ifdef LOSCFG_PID_CONTAINER ret = OsCopyPidContainer(flags, child, parent, processID); @@ -139,6 +121,58 @@ UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent return ret; } +/* + * called from clone. This now handles copy for Container and all + * namespaces therein. + */ +UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID) +{ + UINT32 intSave; + + if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWTIME))) { +#ifdef LOSCFG_PID_CONTAINER + if (parent->container->pidContainer != parent->container->pidForChildContainer) { + goto CREATE_CONTAINER; + } +#endif +#ifdef LOSCFG_TIME_CONTAINER + if (parent->container->timeContainer != parent->container->timeForChildContainer) { + goto CREATE_CONTAINER; + } +#endif + SCHEDULER_LOCK(intSave); + child->container = parent->container; + LOS_AtomicInc(&child->container->rc); + SCHEDULER_UNLOCK(intSave); + goto COPY_CONTAINERS; + } + +#if defined(LOSCFG_PID_CONTAINER) || defined(LOSCFG_TIME_CONTAINER) +CREATE_CONTAINER: +#endif + child->container = CreateContainer(); + if (child->container == NULL) { + return ENOMEM; + } + +COPY_CONTAINERS: + return CopyContainers(flags, child, parent, processID); +} + +#ifndef LOSCFG_PID_CONTAINER +STATIC VOID ContainersFree(LosProcessCB *processCB) +{ + UINT32 intSave; + SCHEDULER_LOCK(intSave); + LOS_AtomicDec(&processCB->container->rc); + if (LOS_AtomicRead(&processCB->container->rc) == 0) { + (VOID)LOS_MemFree(m_aucSysMem1, processCB->container); + processCB->container = NULL; + } + SCHEDULER_UNLOCK(intSave); +} +#endif + VOID OsContainersDestroy(LosProcessCB *processCB) { /* All processes in the container must be destroyed before the container is destroyed. */ @@ -149,15 +183,15 @@ VOID OsContainersDestroy(LosProcessCB *processCB) #endif #ifdef LOSCFG_UTS_CONTAINER - OsUtsContainersDestroy(processCB); + OsUtsContainersDestroy(processCB->container); #endif #ifdef LOSCFG_MNT_CONTAINER - OsMntContainersDestroy(processCB); + OsMntContainersDestroy(processCB->container); #endif #ifdef LOSCFG_IPC_CONTAINER - OsIpcContainersDestroy(processCB); + OsIpcContainersDestroy(processCB->container); #endif #ifdef LOSCFG_TIME_CONTAINER @@ -165,11 +199,7 @@ VOID OsContainersDestroy(LosProcessCB *processCB) #endif #ifndef LOSCFG_PID_CONTAINER - LOS_AtomicDec(&curr->container->rc); - if (LOS_AtomicRead(&processCB->container->rc) == 0) { - (VOID)LOS_MemFree(m_aucSysMem1, processCB->container); - processCB->container = NULL; - } + ContainersFree(processCB); #endif } @@ -209,4 +239,126 @@ UINT32 OsGetContainerID(Container *container, ContainerType type) } return OS_INVALID_VALUE; } + +STATIC VOID UnshareDeinitContainerCommon(UINT32 flags, Container *container) +{ +#ifdef LOSCFG_UTS_CONTAINER + if ((flags & CLONE_NEWUTS) != 0) { + OsUtsContainersDestroy(container); + } +#endif +#ifdef LOSCFG_MNT_CONTAINER + if ((flags & CLONE_NEWNS) != 0) { + OsMntContainersDestroy(container); + } +#endif +#ifdef LOSCFG_IPC_CONTAINER + if ((flags & CLONE_NEWIPC) != 0) { + OsIpcContainersDestroy(container); + } +#endif +} + +STATIC VOID UnshareDeinitContainer(UINT32 flags, Container *container) +{ + if (container == NULL) { + return; + } + +#ifdef LOSCFG_PID_CONTAINER + if ((container->pidForChildContainer != NULL) && (container->pidForChildContainer != container->pidContainer)) { + (VOID)LOS_MemFree(m_aucSysMem1, container->pidForChildContainer); + container->pidForChildContainer = NULL; + container->pidContainer = NULL; + } +#endif + + UnshareDeinitContainerCommon(flags, container); + +#ifdef LOSCFG_TIME_CONTAINER + if ((container->timeForChildContainer != NULL) && (container->timeForChildContainer != container->timeContainer)) { + (VOID)LOS_MemFree(m_aucSysMem1, container->timeForChildContainer); + container->timeForChildContainer = NULL; + container->timeContainer = NULL; + } +#endif + + (VOID)LOS_MemFree(m_aucSysMem1, container); +} + +STATIC UINT32 CreateNewContainers(UINT32 flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 ret = LOS_OK; +#ifdef LOSCFG_PID_CONTAINER + ret = OsUnsharePidContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_UTS_CONTAINER + ret = OsUnshareUtsContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_MNT_CONTAINER + ret = OsUnshareMntContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_IPC_CONTAINER + ret = OsUnshareIpcContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif +#ifdef LOSCFG_TIME_CONTAINER + ret = OsUnshareTimeContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } +#endif + return ret; +} + +INT32 OsUnshare(UINT32 flags) +{ + UINT32 ret; + UINT32 intSave; + LosProcessCB *curr = OsCurrProcessGet(); + Container *oldContainer = curr->container; + if (!(flags & (CLONE_NEWPID | CLONE_NEWTIME | CLONE_NEWUTS | CLONE_NEWNS | CLONE_NEWIPC))) { + return -EINVAL; + } + + Container *newContainer = CreateContainer(); + if (newContainer == NULL) { + return -ENOMEM; + } + + ret = CreateNewContainers(flags, curr, newContainer); + if (ret != LOS_OK) { + goto EXIT; + } + + SCHEDULER_LOCK(intSave); + oldContainer = curr->container; + curr->container = newContainer; + SCHEDULER_UNLOCK(intSave); + + UnshareDeinitContainerCommon(flags, oldContainer); + + SCHEDULER_LOCK(intSave); + LOS_AtomicDec(&oldContainer->rc); + if (LOS_AtomicRead(&oldContainer->rc) == 0) { + (VOID)LOS_MemFree(m_aucSysMem1, oldContainer); + } + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + +EXIT: + UnshareDeinitContainer(flags, newContainer); + return -ret; +} #endif diff --git a/kernel/base/container/los_ipc_container.c b/kernel/base/container/los_ipc_container.c index 0fb839cce7eba716636f64249118c8ed33c9b14b..030112e43f7aaca116c6812a173a08887bb7f433 100644 --- a/kernel/base/container/los_ipc_container.c +++ b/kernel/base/container/los_ipc_container.c @@ -124,22 +124,46 @@ UINT32 OsCopyIpcContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *pare return CreateIpcContainer(child, parent); } -VOID OsIpcContainersDestroy(LosProcessCB *curr) +UINT32 OsUnshareIpcContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) { UINT32 intSave; - if (curr->container == NULL) { + IpcContainer *parentContainer = curr->container->ipcContainer; + + if (!(flags & CLONE_NEWIPC)) { + SCHEDULER_LOCK(intSave); + newContainer->ipcContainer = parentContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + IpcContainer *ipcContainer = CreateNewIpcContainer(parentContainer); + if (ipcContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + newContainer->ipcContainer = ipcContainer; + g_currentIpcContainerNum++; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +VOID OsIpcContainersDestroy(Container *container) +{ + UINT32 intSave; + if (container == NULL) { return; } SCHEDULER_LOCK(intSave); - IpcContainer *ipcContainer = curr->container->ipcContainer; + IpcContainer *ipcContainer = container->ipcContainer; if (ipcContainer != NULL) { LOS_AtomicDec(&ipcContainer->rc); - if (LOS_AtomicRead(&ipcContainer->rc) == 0) { + if (LOS_AtomicRead(&ipcContainer->rc) <= 0) { g_currentIpcContainerNum--; SCHEDULER_UNLOCK(intSave); ShmDeinit(); - curr->container->ipcContainer = NULL; + container->ipcContainer = NULL; (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer->allQueue); (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer); return; diff --git a/kernel/base/container/los_mnt_container.c b/kernel/base/container/los_mnt_container.c index a8c26abdd2b9d8e3c064bf4266bf81ced7189bca..154a2d051c7f7019550f0e6a3958f8debca692bb 100644 --- a/kernel/base/container/los_mnt_container.c +++ b/kernel/base/container/los_mnt_container.c @@ -132,6 +132,37 @@ UINT32 OsCopyMntContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *pare return CopyMountList(currMntContainer, child->container->mntContainer); } +UINT32 OsUnshareMntContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 intSave; + UINT32 ret; + MntContainer *parentContainer = curr->container->mntContainer; + + if (!(flags & CLONE_NEWNS)) { + SCHEDULER_LOCK(intSave); + newContainer->mntContainer = parentContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + MntContainer *mntContainer = CreateNewMntContainer(parentContainer); + if (mntContainer == NULL) { + return ENOMEM; + } + + ret = CopyMountList(parentContainer, mntContainer); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, mntContainer); + return ret; + } + + SCHEDULER_LOCK(intSave); + newContainer->mntContainer = mntContainer; + g_currentMntContainerNum++; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + STATIC VOID FreeMountList(LIST_HEAD *mountList) { struct Mount *mnt = NULL; @@ -156,22 +187,22 @@ STATIC VOID FreeMountList(LIST_HEAD *mountList) return; } -VOID OsMntContainersDestroy(LosProcessCB *curr) +VOID OsMntContainersDestroy(Container *container) { UINT32 intSave; - if (curr->container == NULL) { + if (container == NULL) { return; } SCHEDULER_LOCK(intSave); - MntContainer *mntContainer = curr->container->mntContainer; + MntContainer *mntContainer = container->mntContainer; if (mntContainer != NULL) { LOS_AtomicDec(&mntContainer->rc); - if (LOS_AtomicRead(&mntContainer->rc) == 0) { + if (LOS_AtomicRead(&mntContainer->rc) <= 0) { g_currentMntContainerNum--; SCHEDULER_UNLOCK(intSave); FreeMountList(&mntContainer->mountList); - curr->container->mntContainer = NULL; + container->mntContainer = NULL; (VOID)LOS_MemFree(m_aucSysMem1, mntContainer); return; } diff --git a/kernel/base/container/los_pid_container.c b/kernel/base/container/los_pid_container.c index 81d27c9e2d9c069f8ea831ddec64da01c8111e01..4af02dd6a2158e358f2277beab87e6de4f5dac1b 100644 --- a/kernel/base/container/los_pid_container.c +++ b/kernel/base/container/los_pid_container.c @@ -274,10 +274,15 @@ STATIC UINT32 CreatePidContainer(LosProcessCB *child, LosProcessCB *parent) { UINT32 intSave; UINT32 ret; + PidContainer *newPidContainer = NULL; PidContainer *parentContainer = parent->container->pidContainer; - PidContainer *newPidContainer = CreateNewPidContainer(parentContainer); - if (newPidContainer == NULL) { - return ENOMEM; + if (parentContainer == parent->container->pidForChildContainer) { + newPidContainer = CreateNewPidContainer(parentContainer); + if (newPidContainer == NULL) { + return ENOMEM; + } + } else { + newPidContainer = parent->container->pidForChildContainer; } SCHEDULER_LOCK(intSave); @@ -312,8 +317,12 @@ VOID OsPidContainersDestroy(LosProcessCB *curr) PidContainer *pidContainer = curr->container->pidContainer; if (pidContainer != NULL) { FreeVpid(curr); - if (LOS_AtomicRead(&pidContainer->rc) == 0) { + if (LOS_AtomicRead(&pidContainer->rc) <= 0) { g_currentPidContainerNum--; + if ((pidContainer != curr->container->pidForChildContainer) && + (LOS_AtomicRead(&curr->container->pidForChildContainer->rc) <= 0)) { + (VOID)LOS_MemFree(m_aucSysMem1, curr->container->pidForChildContainer); + } curr->container->pidContainer = NULL; curr->container->pidForChildContainer = NULL; (VOID)LOS_MemFree(m_aucSysMem1, pidContainer); @@ -332,7 +341,7 @@ UINT32 OsCopyPidContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *pare UINT32 ret; UINT32 intSave; - if (!(flags & CLONE_NEWPID)) { + if (!(flags & CLONE_NEWPID) && (parent->container->pidContainer == parent->container->pidForChildContainer)) { SCHEDULER_LOCK(intSave); child->container->pidContainer = parent->container->pidContainer; child->container->pidForChildContainer = parent->container->pidContainer; @@ -360,6 +369,41 @@ UINT32 OsCopyPidContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *pare return LOS_OK; } +UINT32 OsUnsharePidContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 intSave; + if (!(flags & CLONE_NEWPID)) { + SCHEDULER_LOCK(intSave); + newContainer->pidContainer = curr->container->pidContainer; + newContainer->pidForChildContainer = curr->container->pidContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + PidContainer *pidForChild = CreateNewPidContainer(curr->container->pidContainer); + if (pidForChild == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + if (curr->container->pidContainer != curr->container->pidForChildContainer) { + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, pidForChild); + return EINVAL; + } + + if (pidForChild->level >= PID_CONTAINER_LEVEL_LIMIT) { + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, pidForChild); + return EINVAL; + } + + newContainer->pidContainer = curr->container->pidContainer; + newContainer->pidForChildContainer = pidForChild; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + UINT32 OsInitRootPidContainer(PidContainer **pidContainer) { UINT32 intSave; diff --git a/kernel/base/container/los_time_container.c b/kernel/base/container/los_time_container.c index b2320d5fe858e98680beba8cf4670d0714c8a14b..781b9ffa0b606b8d5b80c91e385fea56c7ff33c8 100644 --- a/kernel/base/container/los_time_container.c +++ b/kernel/base/container/los_time_container.c @@ -57,15 +57,29 @@ STATIC UINT32 CreateTimeContainer(LosProcessCB *child, LosProcessCB *parent) { UINT32 intSave; TimeContainer *parentContainer = parent->container->timeContainer; - TimeContainer *newTimeContainer = CreateNewTimeContainer(parentContainer); - if (newTimeContainer == NULL) { - return ENOMEM; + if (parentContainer == parent->container->timeForChildContainer) { + TimeContainer *newTimeContainer = CreateNewTimeContainer(parentContainer); + if (newTimeContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + g_currentTimeContainerNum++; + (VOID)memcpy_s(&newTimeContainer->monotonic, sizeof(struct timespec64), + &parentContainer->monotonic, sizeof(struct timespec64)); + child->container->timeContainer = newTimeContainer; + child->container->timeForChildContainer = newTimeContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; } SCHEDULER_LOCK(intSave); + TimeContainer *newTimeContainer = parent->container->timeForChildContainer; g_currentTimeContainerNum++; - (VOID)memcpy_s(&newTimeContainer->monotonic, sizeof(struct timespec64), - &parentContainer->monotonic, sizeof(struct timespec64)); + LOS_AtomicSet(&newTimeContainer->rc, 1); + if (!newTimeContainer->frozenOffsets) { + newTimeContainer->frozenOffsets = TRUE; + } child->container->timeContainer = newTimeContainer; child->container->timeForChildContainer = newTimeContainer; SCHEDULER_UNLOCK(intSave); @@ -92,11 +106,8 @@ UINT32 OsCopyTimeContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *par UINT32 intSave; TimeContainer *currTimeContainer = parent->container->timeContainer; - if (!(flags & CLONE_NEWTIME)) { + if (!(flags & CLONE_NEWTIME) && (currTimeContainer == parent->container->timeForChildContainer)) { SCHEDULER_LOCK(intSave); - if (!currTimeContainer->frozenOffsets) { - currTimeContainer->frozenOffsets = TRUE; - } LOS_AtomicInc(&currTimeContainer->rc); child->container->timeContainer = currTimeContainer; child->container->timeForChildContainer = currTimeContainer; @@ -107,6 +118,36 @@ UINT32 OsCopyTimeContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *par return CreateTimeContainer(child, parent); } +UINT32 OsUnshareTimeContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 intSave; + if (!(flags & CLONE_NEWTIME)) { + SCHEDULER_LOCK(intSave); + newContainer->timeContainer = curr->container->timeContainer; + newContainer->timeForChildContainer = curr->container->timeForChildContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + TimeContainer *timeForChild = CreateNewTimeContainer(curr->container->timeContainer); + if (timeForChild == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + if (curr->container->timeContainer != curr->container->timeForChildContainer) { + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, timeForChild); + return EINVAL; + } + + newContainer->timeContainer = curr->container->timeContainer; + newContainer->timeForChildContainer = timeForChild; + LOS_AtomicSet(&timeForChild->rc, 0); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + VOID OsTimeContainersDestroy(LosProcessCB *curr) { UINT32 intSave; @@ -118,11 +159,15 @@ VOID OsTimeContainersDestroy(LosProcessCB *curr) TimeContainer *timeContainer = curr->container->timeContainer; if (timeContainer != NULL) { LOS_AtomicDec(&timeContainer->rc); - if (LOS_AtomicRead(&timeContainer->rc) == 0) { + if (LOS_AtomicRead(&timeContainer->rc) <= 0) { g_currentTimeContainerNum--; curr->container->timeContainer = NULL; - curr->container->timeForChildContainer = NULL; SCHEDULER_UNLOCK(intSave); + if ((timeContainer != curr->container->timeForChildContainer) && + (LOS_AtomicRead(&curr->container->timeForChildContainer->rc) <= 0)) { + (VOID)LOS_MemFree(m_aucSysMem1, curr->container->timeForChildContainer); + } + curr->container->timeForChildContainer = NULL; (VOID)LOS_MemFree(m_aucSysMem1, timeContainer); return; } diff --git a/kernel/base/container/los_uts_container.c b/kernel/base/container/los_uts_container.c index 593a2cda0b688fdac5ae1cc8b881b1f2404cb667..7bc91d2b215f51a302c11cedd3d9b25ae6fcc0c7 100644 --- a/kernel/base/container/los_uts_container.c +++ b/kernel/base/container/los_uts_container.c @@ -138,20 +138,46 @@ UINT32 OsCopyUtsContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *pare return CreateUtsContainer(child, parent); } -VOID OsUtsContainersDestroy(LosProcessCB *curr) +UINT32 OsUnshareUtsContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) { UINT32 intSave; - if (curr->container == NULL) { + UtsContainer *parentContainer = curr->container->utsContainer; + + if (!(flags & CLONE_NEWUTS)) { + SCHEDULER_LOCK(intSave); + newContainer->utsContainer = parentContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + UtsContainer *utsContainer = CreateNewUtsContainer(parentContainer); + if (utsContainer == NULL) { + return ENOMEM; + } + + SCHEDULER_LOCK(intSave); + newContainer->utsContainer = utsContainer; + g_currentUtsContainerNum++; + (VOID)memcpy_s(&utsContainer->utsName, sizeof(utsContainer->utsName), + &parentContainer->utsName, sizeof(parentContainer->utsName)); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +VOID OsUtsContainersDestroy(Container *container) +{ + UINT32 intSave; + if (container == NULL) { return; } SCHEDULER_LOCK(intSave); - UtsContainer *utsContainer = curr->container->utsContainer; + UtsContainer *utsContainer = container->utsContainer; if (utsContainer != NULL) { LOS_AtomicDec(&utsContainer->rc); - if (LOS_AtomicRead(&utsContainer->rc) == 0) { + if (LOS_AtomicRead(&utsContainer->rc) <= 0) { g_currentUtsContainerNum--; - curr->container->utsContainer = NULL; + container->utsContainer = NULL; SCHEDULER_UNLOCK(intSave); (VOID)LOS_MemFree(m_aucSysMem1, utsContainer); return; diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index d57dda55a35fac5d2aae7e4b558e842a20754e56..a2c35f09d73f1da770510e8d4d5c3da90bff93ed 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -398,13 +398,6 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) } #endif -#ifdef LOSCFG_FS_VFS - if (OsProcessIsUserMode(processCB)) { - delete_files(processCB->files); - } - processCB->files = NULL; -#endif - #ifdef LOSCFG_SECURITY_CAPABILITY if (processCB->user != NULL) { (VOID)LOS_MemFree(m_aucSysMem1, processCB->user); @@ -446,6 +439,13 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) OsContainersDestroy(processCB); #endif +#ifdef LOSCFG_FS_VFS + if (OsProcessIsUserMode(processCB)) { + delete_files(processCB->files); + } + processCB->files = NULL; +#endif + if (processCB->resourceLimit != NULL) { (VOID)LOS_MemFree((VOID *)m_aucSysMem0, processCB->resourceLimit); processCB->resourceLimit = NULL; diff --git a/kernel/base/include/los_container_pri.h b/kernel/base/include/los_container_pri.h index b655fd4e09761201e8adee62f6fafcab4d236be0..a878323a3531d1c4c3e2e254c23fb71d46cee351 100644 --- a/kernel/base/include/los_container_pri.h +++ b/kernel/base/include/los_container_pri.h @@ -75,7 +75,7 @@ typedef struct Container { #ifdef LOSCFG_IPC_CONTAINER struct IpcContainer *ipcContainer; #endif -#ifdef LOSCFG_IPC_CONTAINER +#ifdef LOSCFG_TIME_CONTAINER struct TimeContainer *timeContainer; struct TimeContainer *timeForChildContainer; #endif @@ -92,5 +92,8 @@ VOID OsContainersDestroy(LosProcessCB *processCB); UINT32 OsAllocContainerID(VOID); UINT32 OsGetContainerID(Container *container, ContainerType type); + +INT32 OsUnshare(UINT32 flags); + #endif #endif /* _LOS_CONTAINER_PRI_H */ diff --git a/kernel/base/include/los_ipc_container_pri.h b/kernel/base/include/los_ipc_container_pri.h index 218954ee90c1407398ca74a1c6c858a7e8bc95b2..9439892558cc1769c8ef75d9d13781ccd0c37c75 100644 --- a/kernel/base/include/los_ipc_container_pri.h +++ b/kernel/base/include/los_ipc_container_pri.h @@ -37,6 +37,7 @@ #ifdef LOSCFG_IPC_CONTAINER struct shmIDSource; +struct Container; typedef struct TagQueueCB LosQueueCB; typedef struct OsMux LosMux; typedef LosMux pthread_mutex_t; @@ -61,7 +62,9 @@ UINT32 OsInitRootIpcContainer(IpcContainer **ipcContainer); UINT32 OsCopyIpcContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); -VOID OsIpcContainersDestroy(LosProcessCB *curr); +UINT32 OsUnshareIpcContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + +VOID OsIpcContainersDestroy(struct Container *container); UINT32 OsGetIpcContainerID(IpcContainer *ipcContainer); diff --git a/kernel/base/include/los_mnt_container_pri.h b/kernel/base/include/los_mnt_container_pri.h index ded748b9439748f96cc59c5c88786e726d03b363..af20c4a4e32bea062087498ac451e4e399342e73 100644 --- a/kernel/base/include/los_mnt_container_pri.h +++ b/kernel/base/include/los_mnt_container_pri.h @@ -39,6 +39,7 @@ #ifdef LOSCFG_MNT_CONTAINER typedef struct ProcessCB LosProcessCB; +struct Container; typedef struct MntContainer { Atomic rc; @@ -52,7 +53,9 @@ UINT32 OsInitRootMntContainer(MntContainer **mntContainer); UINT32 OsCopyMntContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); -VOID OsMntContainersDestroy(LosProcessCB *curr); +UINT32 OsUnshareMntContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + +VOID OsMntContainersDestroy(struct Container *container); UINT32 OsGetMntContainerID(MntContainer *mntContainer); diff --git a/kernel/base/include/los_pid_container_pri.h b/kernel/base/include/los_pid_container_pri.h index c1fe98b22bc8332637e3b9e5bbdb1722de158d6c..6d6ad3c3982395b14e6cf280c34713e2b9f725fc 100644 --- a/kernel/base/include/los_pid_container_pri.h +++ b/kernel/base/include/los_pid_container_pri.h @@ -37,6 +37,7 @@ typedef struct TagTaskCB LosTaskCB; typedef struct ProcessCB LosProcessCB; struct ProcessGroup; +struct Container; typedef struct { UINT32 vid; /* Virtual ID */ @@ -75,6 +76,8 @@ VOID OsPidContainersDestroy(LosProcessCB *curr); UINT32 OsCopyPidContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID); +UINT32 OsUnsharePidContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + UINT32 OsInitRootPidContainer(PidContainer **pidContainer); LosProcessCB *OsGetPCBFromVpid(UINT32 vpid); diff --git a/kernel/base/include/los_process_pri.h b/kernel/base/include/los_process_pri.h index 8a1cc1142c293d156665b4c38a98c260e132beb6..9272a54a9ba647026fd7ac345bad4e7a54b9b98d 100644 --- a/kernel/base/include/los_process_pri.h +++ b/kernel/base/include/los_process_pri.h @@ -131,7 +131,7 @@ typedef struct ProcessCB { #endif struct rlimit *resourceLimit; #ifdef LOSCFG_KERNEL_CONTAINER - struct Container *container; + Container *container; #endif #ifdef LOSCFG_PROC_PROCESS_DIR struct ProcDirEntry *procDir; diff --git a/kernel/base/include/los_time_container_pri.h b/kernel/base/include/los_time_container_pri.h index c6e3c47655e7675dc3e48166bc1dd813ba64db0e..617c0fa1425049f55434eb9ade81dea04ca02f87 100644 --- a/kernel/base/include/los_time_container_pri.h +++ b/kernel/base/include/los_time_container_pri.h @@ -35,6 +35,7 @@ #ifdef LOSCFG_TIME_CONTAINER typedef struct ProcessCB LosProcessCB; +struct Container; typedef struct TimeContainer { Atomic rc; @@ -47,6 +48,8 @@ UINT32 OsInitRootTimeContainer(TimeContainer **timeContainer); UINT32 OsCopyTimeContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); +UINT32 OsUnshareTimeContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + VOID OsTimeContainersDestroy(LosProcessCB *curr); UINT32 OsGetTimeContainerID(TimeContainer *timeContainer); diff --git a/kernel/base/include/los_uts_container_pri.h b/kernel/base/include/los_uts_container_pri.h index a4a984b2dfa1622920fe6030d33ec40cd857d548..c15e40799f3fcc269afc69293dae36656ee36975 100644 --- a/kernel/base/include/los_uts_container_pri.h +++ b/kernel/base/include/los_uts_container_pri.h @@ -38,6 +38,8 @@ #ifdef LOSCFG_UTS_CONTAINER typedef struct ProcessCB LosProcessCB; +struct Container; + typedef struct UtsContainer { Atomic rc; UINT32 containerID; @@ -48,7 +50,9 @@ UINT32 OsInitRootUtsContainer(UtsContainer **utsContainer); UINT32 OsCopyUtsContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); -VOID OsUtsContainersDestroy(LosProcessCB *curr); +UINT32 OsUnshareUtsContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + +VOID OsUtsContainersDestroy(struct Container *container); struct utsname *OsGetCurrUtsName(VOID); diff --git a/syscall/los_syscall.h b/syscall/los_syscall.h index eee7f1fe5c6ebe7f250b9fae43228202896410de..e9863ffcec1fd049699106810b7101397612f30a 100644 --- a/syscall/los_syscall.h +++ b/syscall/los_syscall.h @@ -85,6 +85,7 @@ extern int SysWaitid(idtype_t type, int pid, USER siginfo_t *info, int options, extern int SysFork(void); extern int SysVfork(void); extern int SysClone(int flags, void *stack, int *parentTid, unsigned long tls, int *childTid); +extern int SysUnshare(int flags); extern unsigned int SysGetPID(void); extern unsigned int SysGetPPID(void); extern int SysSetGroupID(unsigned int gid); diff --git a/syscall/process_syscall.c b/syscall/process_syscall.c index db4355181ee555c269adbf8540da32cb79d96851..74386be77e5185b07eeb3b14eb84e8bcac9461b1 100644 --- a/syscall/process_syscall.c +++ b/syscall/process_syscall.c @@ -369,6 +369,15 @@ int SysClone(int flags, void *stack, int *parentTid, unsigned long tls, int *chi return OsClone((UINT32)flags, (UINTPTR)stack, 0); } +int SysUnshare(int flags) +{ +#ifdef LOSCFG_KERNEL_CONTAINER + return OsUnshare(flags); +#else + return -ENOSYS; +#endif +} + unsigned int SysGetPPID(void) { #ifdef LOSCFG_PID_CONTAINER diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index 614de7d046017c5974d5ba8d1ba20522dbcb44d6..bdb69e67ee4bdf3df4d0100a953e90d8044abc12 100644 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -140,6 +140,7 @@ SYSCALL_HAND_DEF(__NR_exit, SysThreadExit, void, ARG_NUM_1) SYSCALL_HAND_DEF(__NR_fork, SysFork, int, ARG_NUM_0) SYSCALL_HAND_DEF(__NR_vfork, SysVfork, int, ARG_NUM_0) SYSCALL_HAND_DEF(__NR_clone, SysClone, int, ARG_NUM_5) +SYSCALL_HAND_DEF(__NR_unshare, SysUnshare, int, ARG_NUM_1) SYSCALL_HAND_DEF(__NR_getpid, SysGetPID, unsigned int, ARG_NUM_0) SYSCALL_HAND_DEF(__NR_pause, SysPause, int, ARG_NUM_0) diff --git a/testsuites/unittest/container/It_container_test.cpp b/testsuites/unittest/container/It_container_test.cpp index 33d34335d314c8f61a3f2fc5eee5ee7fde78dac8..17e0fb12841eefade13b84c9e073dead50157b6b 100644 --- a/testsuites/unittest/container/It_container_test.cpp +++ b/testsuites/unittest/container/It_container_test.cpp @@ -74,24 +74,12 @@ std::string GenContainerLinkPath(int pid, const std::string& containerType) std::string ReadlinkContainer(int pid, const std::string& containerType) { - char buf[PATH_MAX]; + char buf[PATH_MAX] = {0}; auto path = GenContainerLinkPath(pid, containerType); - - struct stat sb; - int ret = lstat(path.data(), &sb); - if (ret == -1) { - throw std::exception(); - } - - size_t bufsiz = sb.st_size + 1; - if (sb.st_size == 0) { - bufsiz = PATH_MAX; - } - - (void)memset_s(buf, PATH_MAX, 0, PATH_MAX); - ssize_t nbytes = readlink(path.c_str(), buf, bufsiz); + ssize_t nbytes = readlink(path.c_str(), buf, PATH_MAX); if (nbytes == -1) { - throw std::exception(); + printf("pid %d, ReadlinkContainer readlink %s failed, errno=%d\n", getpid(), path.c_str(), errno); + return path.c_str(); } return buf; } @@ -150,6 +138,30 @@ HWTEST_F(ContainerTest, ItPidContainer026, TestSize.Level0) { ItPidContainer026(); } + +/** +* @tc.name: Container_Pid_Test_027 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer027, TestSize.Level0) +{ + ItPidContainer027(); +} + +/** +* @tc.name: Container_Pid_Test_028 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer028, TestSize.Level0) +{ + ItPidContainer028(); +} #endif #if defined(LOSCFG_USER_TEST_UTS_CONTAINER) /** @@ -175,6 +187,18 @@ HWTEST_F(ContainerTest, ItUtsContainer002, TestSize.Level0) { ItUtsContainer002(); } + +/** +* @tc.name: Container_UTS_Test_004 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUtsContainer004, TestSize.Level0) +{ + ItUtsContainer004(); +} #endif #if defined(LOSCFG_USER_TEST_MNT_CONTAINER) @@ -226,6 +250,42 @@ HWTEST_F(ContainerTest, ItMntContainer004, TestSize.Level0) ItMntContainer004(); } +/** +* @tc.name: Container_MNT_Test_005 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer005, TestSize.Level0) +{ + ItMntContainer005(); +} + +/** +* @tc.name: Container_MNT_Test_006 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer006, TestSize.Level0) +{ + ItMntContainer006(); +} + +/** +* @tc.name: Container_MNT_Test_007 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer007, TestSize.Level0) +{ + ItMntContainer007(); +} + /** * @tc.name: chroot_Test_001 * @tc.desc: chroot function test case @@ -254,6 +314,18 @@ HWTEST_F(ContainerTest, ItIpcContainer001, TestSize.Level0) ItIpcContainer001(); } +/** +* @tc.name: Container_IPC_Test_003 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer003, TestSize.Level0) +{ + ItIpcContainer003(); +} + /** * @tc.name: Container_IPC_Test_004 * @tc.desc: ipc container function test case @@ -265,6 +337,18 @@ HWTEST_F(ContainerTest, ItIpcContainer004, TestSize.Level0) { ItIpcContainer004(); } + +/** +* @tc.name: Container_IPC_Test_005 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer005, TestSize.Level0) +{ + ItIpcContainer005(); +} #endif #if defined(LOSCFG_USER_TEST_TIME_CONTAINER) @@ -280,6 +364,42 @@ HWTEST_F(ContainerTest, ItTimeContainer001, TestSize.Level0) ItTimeContainer001(); } +/** +* @tc.name: Container_TIME_Test_002 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer002, TestSize.Level0) +{ + ItTimeContainer002(); +} + +/** +* @tc.name: Container_TIME_Test_004 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer004, TestSize.Level0) +{ + ItTimeContainer004(); +} + +/** +* @tc.name: Container_TIME_Test_005 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer005, TestSize.Level0) +{ + ItTimeContainer005(); +} + /* * @tc.name: Container_TIME_Test_007 * @tc.desc: time container function test case @@ -292,6 +412,18 @@ HWTEST_F(ContainerTest, ItTimeContainer007, TestSize.Level0) ItTimeContainer007(); } +/** +* @tc.name: Container_TIME_Test_008 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6BE5A +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer008, TestSize.Level0) +{ + ItTimeContainer008(); +} + /** * @tc.name: Container_TIME_Test_009 * @tc.desc: time container function test case diff --git a/testsuites/unittest/container/It_container_test.h b/testsuites/unittest/container/It_container_test.h index 3cf15daa4bafe7065d9e668435f7244710ab32fe..04753a5c48d7ca6b470f8fb219d9825371bb035f 100644 --- a/testsuites/unittest/container/It_container_test.h +++ b/testsuites/unittest/container/It_container_test.h @@ -142,10 +142,13 @@ void ItContainerChroot001(void); void ItPidContainer023(void); void ItPidContainer025(void); void ItPidContainer026(void); +void ItPidContainer027(void); +void ItPidContainer028(void); #endif #if defined(LOSCFG_USER_TEST_UTS_CONTAINER) void ItUtsContainer001(void); void ItUtsContainer002(void); +void ItUtsContainer004(void); #endif #if defined(LOSCFG_USER_TEST_MNT_CONTAINER) void ItMntContainer001(void); diff --git a/testsuites/unittest/container/config.gni b/testsuites/unittest/container/config.gni index 7bbb64d26e9db908d5caad12abd86859fcdf0f54..90c105e8b4ac5fd287b42862c6070d9b472f1223 100644 --- a/testsuites/unittest/container/config.gni +++ b/testsuites/unittest/container/config.gni @@ -48,6 +48,8 @@ if (defined(LOSCFG_USER_TEST_PID_CONTAINER)) { "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_023.cpp", "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_025.cpp", "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_026.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_027.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_028.cpp", ] sources_full += [ "$TEST_UNITTEST_DIR/container/full/It_pid_container_001.cpp", @@ -78,6 +80,7 @@ if (defined(LOSCFG_USER_TEST_UTS_CONTAINER)) { sources_smoke += [ "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_001.cpp", "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_002.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_004.cpp", ] sources_full += [ "$TEST_UNITTEST_DIR/container/full/It_uts_container_003.cpp" ] diff --git a/testsuites/unittest/container/smoke/It_ipc_container_003.cpp b/testsuites/unittest/container/smoke/It_ipc_container_003.cpp index e28164de88cd722fcc4c25e051330e5a1c12a97a..04c8eab8d45912ede2bb6d5c3d1d96bcdb829ff8 100644 --- a/testsuites/unittest/container/smoke/It_ipc_container_003.cpp +++ b/testsuites/unittest/container/smoke/It_ipc_container_003.cpp @@ -74,7 +74,7 @@ EXIT1: return EXIT_CODE_ERRNO_7; } -void ItIpcContainer003(void) +static void IpcContainerUnshare(void) { int status, exitCode, ret; int arg = CHILD_FUNC_ARG; @@ -149,3 +149,15 @@ void ItIpcContainer003(void) ASSERT_EQ(ret, strlen(msgptr)); ASSERT_STREQ(msgrcd, msgptr); } + +void ItIpcContainer003(void) +{ + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + IpcContainerUnshare(); + exit(0); + } + auto ret = waitpid(pid, NULL, 0); + ASSERT_EQ(ret, pid); +} diff --git a/testsuites/unittest/container/smoke/It_mnt_container_005.cpp b/testsuites/unittest/container/smoke/It_mnt_container_005.cpp index aa70e29bf94d407b7fc616ac0e2e269bdcbef7fd..524617fe2f5de06db3439c402ad829834a7ff87c 100644 --- a/testsuites/unittest/container/smoke/It_mnt_container_005.cpp +++ b/testsuites/unittest/container/smoke/It_mnt_container_005.cpp @@ -32,7 +32,7 @@ /* * mount container unshare test: unshare in current pcb with NEW_NS */ -void ItMntContainer005(void) +static void MntContainerUnshare(void) { int ret; @@ -56,4 +56,22 @@ void ItMntContainer005(void) ret = access(ACCESS_FILE_NAME, F_OK); ASSERT_EQ(ret, 0); + exit(0); +} + +void ItMntContainer005(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + MntContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); } diff --git a/testsuites/unittest/container/smoke/It_pid_container_027.cpp b/testsuites/unittest/container/smoke/It_pid_container_027.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d54173f787bcb2a317c29148dbb5ad03e4ecb4f --- /dev/null +++ b/testsuites/unittest/container/smoke/It_pid_container_027.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFunClone3(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_SECOND_PID) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +static int ChildFunClone2(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_FIRST_PID) { + return EXIT_CODE_ERRNO_1; + } + int ret; + int status; + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_2; + } + int childPid = clone(ChildFunClone3, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + if (childPid == -1) { + free(pstk); + return EXIT_CODE_ERRNO_3; + } + + ret = waitpid(childPid, &status, 0); + ret = WIFEXITED(status); + ret = WEXITSTATUS(status); + if (ret != 0) { + free(pstk); + return EXIT_CODE_ERRNO_4; + } + + free(pstk); + return 0; +} + + +static int ChildFunClone1(void *p) +{ + (void)p; + int ret; + int status; + const char *containerType = "pid"; + const char *containerType1 = "pid_for_children"; + + auto pid = getpid(); + ret = unshare(CLONE_NEWPID); + if (ret == -1) { + return EXIT_CODE_ERRNO_1; + } + + auto pid1 = getpid(); + if (pid != pid1) { + return EXIT_CODE_ERRNO_2; + } + + auto linkBuffer = ReadlinkContainer(pid, containerType); + auto linkBuffer1 = ReadlinkContainer(pid, containerType1); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + printf("linkBuffer: %s linkBuffer1: %s\n", linkBuffer.c_str(), linkBuffer1.c_str()); + return EXIT_CODE_ERRNO_3; + } + + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_4; + } + int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, CLONE_NEWUTS | SIGCHLD, NULL); + free(pstk); + if (childPid == -1) { + return EXIT_CODE_ERRNO_5; + } + + ret = unshare(CLONE_NEWPID); + if (ret != -1) { + return EXIT_CODE_ERRNO_6; + } + + ret = waitpid(childPid, &status, 0); + if (ret != childPid) { + return EXIT_CODE_ERRNO_7; + } + ret = WIFEXITED(status); + if (ret == 0) { + return EXIT_CODE_ERRNO_8; + } + ret = WEXITSTATUS(status); + if (ret != 0) { + return EXIT_CODE_ERRNO_9; + } + return 0; +} + +void ItPidContainer027(void) +{ + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + pid_t parentPid = getpid(); + + int childPid = clone(ChildFunClone1, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + int status; + int ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_pid_container_028.cpp b/testsuites/unittest/container/smoke/It_pid_container_028.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d846e17c49d2df9802e5c84c4c25a9aaaeafda35 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_pid_container_028.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" + +static int ChildFunClone3(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_SECOND_PID) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +static int ChildFunClone2(void *p) +{ + (void)p; + auto pid = getpid(); + if (pid != CONTAINER_FIRST_PID) { + return EXIT_CODE_ERRNO_1; + } + int ret; + int status; + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_2; + } + int childPid = clone(ChildFunClone3, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + if (childPid == -1) { + free(pstk); + return EXIT_CODE_ERRNO_3; + } + + ret = waitpid(childPid, &status, 0); + ret = WIFEXITED(status); + ret = WEXITSTATUS(status); + if (ret != 0) { + free(pstk); + return EXIT_CODE_ERRNO_4; + } + + free(pstk); + return 0; +} + + +static int ChildFunClone1(void *p) +{ + (void)p; + int ret; + int status; + const char *containerType = "pid"; + const char *containerType1 = "pid_for_children"; + + auto pid = getpid(); + ret = unshare(CLONE_NEWPID); + if (ret == -1) { + return EXIT_CODE_ERRNO_1; + } + auto pid1 = getpid(); + if (pid != pid1) { + return EXIT_CODE_ERRNO_2; + } + + auto linkBuffer = ReadlinkContainer(pid, containerType); + auto linkBuffer1 = ReadlinkContainer(pid, containerType1); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_3; + } + + void *pstk = malloc(STACK_SIZE); + if (pstk == NULL) { + return EXIT_CODE_ERRNO_4; + } + int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + free(pstk); + if (childPid == -1) { + return EXIT_CODE_ERRNO_5; + } + + ret = unshare(CLONE_NEWPID); + if (ret != -1) { + return EXIT_CODE_ERRNO_6; + } + + ret = waitpid(childPid, &status, 0); + if (ret != childPid) { + return EXIT_CODE_ERRNO_7; + } + ret = WIFEXITED(status); + if (ret == 0) { + return EXIT_CODE_ERRNO_8; + } + ret = WEXITSTATUS(status); + if (ret != 0) { + return EXIT_CODE_ERRNO_9; + } + return 0; +} + +void ItPidContainer028(void) +{ + void *pstk = malloc(STACK_SIZE); + ASSERT_TRUE(pstk != NULL); + pid_t parentPid = getpid(); + + int childPid = clone(ChildFunClone1, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); + free(pstk); + ASSERT_NE(childPid, -1); + + int status; + int ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_time_container_002.cpp b/testsuites/unittest/container/smoke/It_time_container_002.cpp index 737e248ad5cb583a8bff3c6cb003fb3da3e9b943..7f37efa7bacd4f5ed9827d3a094be4896f78421b 100644 --- a/testsuites/unittest/container/smoke/It_time_container_002.cpp +++ b/testsuites/unittest/container/smoke/It_time_container_002.cpp @@ -67,6 +67,7 @@ static int childFunc(void *arg) return 0; } + static int WriteProcTime(int pid) { int ret = 0; @@ -98,7 +99,7 @@ static int WriteProcTime(int pid) return 0; } -void ItTimeContainer002(void) +static void TimeContainerUnshare(void) { int ret; int status; @@ -112,6 +113,9 @@ void ItTimeContainer002(void) ret = unshare(CLONE_NEWTIME); ASSERT_EQ(ret, 0); + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, -1); + ret = WriteProcTime(getpid()); ASSERT_EQ(ret, 0); @@ -128,6 +132,9 @@ void ItTimeContainer002(void) ret = linkBuffer1.compare(linkBuffer2); ASSERT_EQ(ret, 0); + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, -1); + ret = waitpid(pid, &status, 0); ASSERT_EQ(ret, pid); @@ -136,4 +143,23 @@ void ItTimeContainer002(void) int exitCode = WEXITSTATUS(status); ASSERT_EQ(exitCode, 0); + + exit(0); +} + +void ItTimeContainer002(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + TimeContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); } diff --git a/testsuites/unittest/container/smoke/It_time_container_003.cpp b/testsuites/unittest/container/smoke/It_time_container_003.cpp index c5f90ed278c6df9e5f49df3b94c2b4043770b090..edd80dea9fe7fd27a1f97f29a50b5778763b5413 100644 --- a/testsuites/unittest/container/smoke/It_time_container_003.cpp +++ b/testsuites/unittest/container/smoke/It_time_container_003.cpp @@ -69,7 +69,7 @@ static int childFunc(void *arg) return 0; } -void ItTimeContainer003(void) +static void TimeContainerUnshare(void) { int ret; int status; @@ -97,4 +97,23 @@ void ItTimeContainer003(void) int exitCode = WEXITSTATUS(status); ASSERT_EQ(exitCode, 0); + exit(0); } + +void ItTimeContainer003(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + TimeContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} + diff --git a/testsuites/unittest/container/smoke/It_time_container_004.cpp b/testsuites/unittest/container/smoke/It_time_container_004.cpp index e212d2aba71af41e20f8b1764bbb50df1d403caa..e8c760f00466821ae8f37b49cb8c0bcfbdf08a1b 100644 --- a/testsuites/unittest/container/smoke/It_time_container_004.cpp +++ b/testsuites/unittest/container/smoke/It_time_container_004.cpp @@ -81,7 +81,7 @@ static int WriteProcTime(int pid) return 0; } -void ItTimeContainer004(void) +static void TimeContainerUnshare(void) { int ret; int status; @@ -111,4 +111,23 @@ void ItTimeContainer004(void) int exitCode = WEXITSTATUS(status); ASSERT_EQ(exitCode, 0); + + exit(0); +} + +void ItTimeContainer004(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + TimeContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); } diff --git a/testsuites/unittest/container/smoke/It_time_container_005.cpp b/testsuites/unittest/container/smoke/It_time_container_005.cpp index e3ddb3e5bdb9cf50ce24336cafd06a7dcd19488d..b08832d4464f473d85ccde6e37ce59275a0cac9a 100644 --- a/testsuites/unittest/container/smoke/It_time_container_005.cpp +++ b/testsuites/unittest/container/smoke/It_time_container_005.cpp @@ -81,7 +81,7 @@ static int WriteProcTime(int pid) return 0; } -void ItTimeContainer005(void) +static void TimeContainerUnshare(void) { int ret; int status; @@ -111,4 +111,23 @@ void ItTimeContainer005(void) int exitCode = WEXITSTATUS(status); ASSERT_EQ(exitCode, 0); + + exit(0); +} + +void ItTimeContainer005(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + TimeContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); } diff --git a/testsuites/unittest/container/smoke/It_time_container_008.cpp b/testsuites/unittest/container/smoke/It_time_container_008.cpp index be1204153bb0ae486ab90745560cb7e62c85125c..8c74804102a4309c744c07e4b8fd3f18993092d1 100644 --- a/testsuites/unittest/container/smoke/It_time_container_008.cpp +++ b/testsuites/unittest/container/smoke/It_time_container_008.cpp @@ -63,11 +63,30 @@ static int WriteProcTime(int pid) return 0; } -void ItTimeContainer008(void) +static void TimeContainerUnshare(void) { int ret = unshare(CLONE_NEWTIME); ASSERT_EQ(ret, 0); ret = WriteProcTime(getpid()); ASSERT_EQ(ret, 0); + + exit(0); +} + +void ItTimeContainer008(void) +{ + int status = 0; + auto pid = fork(); + ASSERT_TRUE(pid != -1); + if (pid == 0) { + TimeContainerUnshare(); + exit(EXIT_CODE_ERRNO_1); + } + auto ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); } diff --git a/testsuites/unittest/container/smoke/It_uts_container_004.cpp b/testsuites/unittest/container/smoke/It_uts_container_004.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8171a0a6f9e986f68d3368190042344420ec2414 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_uts_container_004.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_container_test.h" +#include "sys/utsname.h" + +static int ChildFunc(void *arg) +{ + (void)arg; + int ret; + + ret = unshare(CLONE_NEWUTS); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + struct utsname newName; + ret = uname(&newName); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + const char *name = "TestHostName"; + ret = sethostname(name, strlen(name)); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + struct utsname newName1; + ret = uname(&newName1); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = strcmp(newName.nodename, newName1.nodename); + if (ret == 0) { + return EXIT_CODE_ERRNO_5; + } + + return 0; +} + +void ItUtsContainer004(void) +{ + int ret; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_TRUE(stack != NULL); + char *stackTop = stack + STACK_SIZE; + struct utsname oldName; + + ret = uname(&oldName); + ASSERT_EQ(ret, 0); + + auto pid = clone(ChildFunc, stackTop, SIGCHLD, NULL); + (void)munmap(stack, STACK_SIZE); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + struct utsname oldName1; + ret = uname(&oldName1); + ASSERT_EQ(ret, 0); + + ret = strcmp(oldName.nodename, oldName1.nodename); + ASSERT_EQ(ret, 0); +}