diff --git a/fs/include/fs/fd_table.h b/fs/include/fs/fd_table.h index 2f2db323c4b26465b94ff66d38a61d956c7138b2..9dcfe994b9faf126317d13bfbad6489dbe245744 100644 --- a/fs/include/fs/fd_table.h +++ b/fs/include/fs/fd_table.h @@ -59,6 +59,9 @@ struct files_struct { spinlock_t workdir_lock; char workdir[PATH_MAX]; #endif +#ifdef LOSCFG_CHROOT + struct Vnode *rootVnode; +#endif }; typedef struct ProcessCB LosProcessCB; diff --git a/fs/include/fs/mount.h b/fs/include/fs/mount.h index 1b20a69f4fb1db09ac7374910e427d3da64f1939..d457df1a50033078826d4632e8cef735aa696e4f 100644 --- a/fs/include/fs/mount.h +++ b/fs/include/fs/mount.h @@ -39,6 +39,7 @@ #define MS_NOSYNC 2 struct MountOps; +struct fsmap_t; struct Mount { LIST_ENTRY mountList; /* mount list */ @@ -69,8 +70,11 @@ typedef int (*foreach_mountpoint_t)(const char *devpoint, struct statfs *statbuf, void *arg); -struct Mount* MountAlloc(struct Vnode* vnode, struct MountOps* mop); -LIST_HEAD* GetMountList(void); +struct Mount *MountAlloc(struct Vnode *vnode, struct MountOps *mop); +LIST_HEAD *GetMountList(void); +#ifdef LOSCFG_MNT_CONTAINER +LIST_HEAD *GetMountCache(void); +#endif int foreach_mountpoint(foreach_mountpoint_t handler, void *arg); int ForceUmountDev(struct Vnode *dev); #endif diff --git a/fs/proc/os_adapt/process_proc.c b/fs/proc/os_adapt/process_proc.c index 2d3cf707129ad587a8b4b295c4b7a3af5e9c3987..0d4b163e65e2d57ef5622aa094e57c29165a625a 100644 --- a/fs/proc/os_adapt/process_proc.c +++ b/fs/proc/os_adapt/process_proc.c @@ -68,6 +68,8 @@ static ssize_t ProcessContainerLink(unsigned int containerID, ContainerType type count = snprintf_s(buffer, bufLen, bufLen - 1, "'pid:[%u]'", containerID); } else if (type == UTS_CONTAINER) { count = snprintf_s(buffer, bufLen, bufLen - 1, "'uts:[%u]'", containerID); + } else if (type == MNT_CONTAINER) { + count = snprintf_s(buffer, bufLen, bufLen - 1, "'mnt:[%u]'", containerID); } if (count < 0) { @@ -240,6 +242,14 @@ static struct ProcProcess g_procProcess[] = { .fileOps = &PID_CONTAINER_FOPS }, #endif +#ifdef LOSCFG_MNT_CONTAINER + { + .name = "container/mnt", + .mode = S_IFLNK, + .type = MNT_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, +#endif #endif }; diff --git a/fs/vfs/include/vnode.h b/fs/vfs/include/vnode.h index 3c16a63368572632fa097713bfb3ab76d5a0c867..8a1b44205424032f4cf0045a5c0af13f0016cbd9 100644 --- a/fs/vfs/include/vnode.h +++ b/fs/vfs/include/vnode.h @@ -127,6 +127,9 @@ struct Vnode { struct Mount *newMount; /* fs info about who mount on this vnode */ char *filePath; /* file path of the vnode */ struct page_mapping mapping; /* page mapping of the vnode */ +#ifdef LOSCFG_MNT_CONTAINER + int mntCount; /* ref count of mounts */ +#endif }; struct VnodeOps { @@ -185,5 +188,5 @@ LIST_HEAD* GetVnodeFreeList(void); LIST_HEAD* GetVnodeActiveList(void); LIST_HEAD* GetVnodeVirtualList(void); int VnodeClearCache(void); - +struct Vnode *GetCurrRootVnode(void); #endif /* !_VNODE_H_ */ diff --git a/fs/vfs/mount.c b/fs/vfs/mount.c index 6e98b9e7d6a86a1b4b3d2d0b0ead3e0d2b5c6163..82f4416a04d9a1e4c3ce8c9318aa1f84936f610c 100644 --- a/fs/vfs/mount.c +++ b/fs/vfs/mount.c @@ -37,11 +37,16 @@ #include "stdlib.h" #endif +#ifdef LOSCFG_MNT_CONTAINER +#include "los_mnt_container_pri.h" +static LIST_HEAD *g_mountCache = NULL; +#else static LIST_HEAD *g_mountList = NULL; +#endif -struct Mount* MountAlloc(struct Vnode* vnodeBeCovered, struct MountOps* fsop) +struct Mount *MountAlloc(struct Vnode *vnodeBeCovered, struct MountOps *fsop) { - struct Mount* mnt = (struct Mount*)zalloc(sizeof(struct Mount)); + struct Mount *mnt = (struct Mount *)zalloc(sizeof(struct Mount)); if (mnt == NULL) { PRINT_ERR("MountAlloc failed no memory!\n"); return NULL; @@ -62,7 +67,26 @@ struct Mount* MountAlloc(struct Vnode* vnodeBeCovered, struct MountOps* fsop) return mnt; } -LIST_HEAD* GetMountList() +#ifdef LOSCFG_MNT_CONTAINER +LIST_HEAD *GetMountList(void) +{ + return GetContainerMntList(); +} + +LIST_HEAD *GetMountCache(void) +{ + if (g_mountCache == NULL) { + g_mountCache = zalloc(sizeof(LIST_HEAD)); + if (g_mountCache == NULL) { + PRINT_ERR("init cache mount list failed, no memory."); + return NULL; + } + LOS_ListInit(g_mountCache); + } + return g_mountCache; +} +#else +LIST_HEAD* GetMountList(void) { if (g_mountList == NULL) { g_mountList = zalloc(sizeof(LIST_HEAD)); @@ -74,3 +98,4 @@ LIST_HEAD* GetMountList() } return g_mountList; } +#endif diff --git a/fs/vfs/operation/vfs_other.c b/fs/vfs/operation/vfs_other.c index 8b87b6076d77b938062e4b9c147afe9a27d61ca8..7495f5be335978db60505361068378d93bb4d164 100644 --- a/fs/vfs/operation/vfs_other.c +++ b/fs/vfs/operation/vfs_other.c @@ -757,3 +757,46 @@ mode_t SysUmask(mode_t mask) SCHEDULER_UNLOCK(intSave); return oldUmask; } + +#ifdef LOSCFG_CHROOT +int chroot(const char *path) +{ + int ret; + struct Vnode *vnode = NULL; + + if (!path) { + set_errno(EFAULT); + return VFS_ERROR; + } + + if (!strlen(path)) { + set_errno(ENOENT); + return VFS_ERROR; + } + + if (strlen(path) > PATH_MAX) { + set_errno(ENAMETOOLONG); + return VFS_ERROR; + } + VnodeHold(); + ret = VnodeLookup(path, &vnode, 0); + if (ret != LOS_OK) { + VnodeDrop(); + return ret; + } + + LosProcessCB *curr = OsCurrProcessGet(); + if ((curr->files == NULL) || (curr->files->rootVnode == NULL)) { + VnodeDrop(); + return VFS_ERROR; + } + if (curr->files->rootVnode->useCount > 0) { + curr->files->rootVnode->useCount--; + } + vnode->useCount++; + curr->files->rootVnode = vnode; + + VnodeDrop(); + return LOS_OK; +} +#endif diff --git a/fs/vfs/vnode.c b/fs/vfs/vnode.c index 41fb043f7867440fcc941e655037da147e4b2545..ed15610d518cb53e8a7191b2ef12da80ee2edb59 100644 --- a/fs/vfs/vnode.c +++ b/fs/vfs/vnode.c @@ -29,9 +29,11 @@ */ #include "los_mux.h" -#include "vnode.h" #include "fs/dirent_fs.h" #include "path_cache.h" +#include "vnode.h" +#include "los_process.h" +#include "los_process_pri.h" LIST_HEAD g_vnodeFreeList; /* free vnodes list */ LIST_HEAD g_vnodeVirtualList; /* dev vnodes list */ @@ -67,6 +69,13 @@ int VnodesInit(void) g_rootVnode->type = VNODE_TYPE_DIR; g_rootVnode->filePath = "/"; +#ifdef LOSCFG_CHROOT + LosProcessCB *processCB = OsGetKernelInitProcess(); + if (processCB->files != NULL) { + g_rootVnode->useCount++; + processCB->files->rootVnode = g_rootVnode; + } +#endif return LOS_OK; } @@ -281,7 +290,7 @@ static int PreProcess(const char *originPath, struct Vnode **startVnode, char ** ret = vfs_normalize_path(NULL, originPath, &absolutePath); if (ret == LOS_OK) { - *startVnode = g_rootVnode; + *startVnode = GetCurrRootVnode(); *path = absolutePath; } @@ -293,7 +302,21 @@ static struct Vnode *ConvertVnodeIfMounted(struct Vnode *vnode) if ((vnode == NULL) || !(vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)) { return vnode; } +#ifdef LOSCFG_MNT_CONTAINER + LIST_HEAD *mntList = GetMountList(); + struct Mount *mnt = NULL; + LOS_DL_LIST_FOR_EACH_ENTRY(mnt, mntList, struct Mount, mountList) { + if ((mnt != NULL) && (mnt->vnodeBeCovered == vnode)) { + return mnt->vnodeCovered; + } + } + if (strcmp(vnode->filePath, "/dev") == 0) { + return vnode->newMount->vnodeCovered; + } + return vnode; +#else return vnode->newMount->vnodeCovered; +#endif } static void RefreshLRU(struct Vnode *vnode) @@ -394,7 +417,7 @@ int VnodeLookupAt(const char *path, struct Vnode **result, uint32_t flags, struc } if (normalizedPath[1] == '\0' && normalizedPath[0] == '/') { - *result = g_rootVnode; + *result = GetCurrRootVnode(); free(normalizedPath); return LOS_OK; } @@ -454,7 +477,7 @@ int VnodeLookup(const char *path, struct Vnode **vnode, uint32_t flags) int VnodeLookupFullpath(const char *fullpath, struct Vnode **vnode, uint32_t flags) { - return VnodeLookupAt(fullpath, vnode, flags, g_rootVnode); + return VnodeLookupAt(fullpath, vnode, flags, GetCurrRootVnode()); } static void ChangeRootInternal(struct Vnode *rootOld, char *dirname) @@ -496,6 +519,17 @@ void ChangeRoot(struct Vnode *rootNew) { struct Vnode *rootOld = g_rootVnode; g_rootVnode = rootNew; +#ifdef LOSCFG_CHROOT + LosProcessCB *curr = OsCurrProcessGet(); + if ((curr->files != NULL) && + (curr->files->rootVnode != NULL) && + (curr->files->rootVnode->useCount > 0)) { + curr->files->rootVnode->useCount--; + } + rootNew->useCount++; + curr->files->rootVnode = rootNew; +#endif + ChangeRootInternal(rootOld, "proc"); ChangeRootInternal(rootOld, "dev"); } @@ -682,6 +716,25 @@ void VnodeMemoryDump(void) PRINTK("Vnode memory size = %d(B)\n", vnodeCount * sizeof(struct Vnode)); } +struct Vnode *GetVnode(INT32 fd) +{ + INT32 sysFd; + + if (fd < 0) { + PRINT_ERR("Error. fd is invalid as %d\n", fd); + return NULL; + } + + /* Process fd convert to system global fd */ + sysFd = GetAssociatedSystemFd(fd); + if (sysFd < 0) { + PRINT_ERR("Error. sysFd is invalid as %d\n", sysFd); + return NULL; + } + + return files_get_openfile((int)sysFd); +} + LIST_HEAD* GetVnodeFreeList() { return &g_vnodeFreeList; @@ -719,3 +772,13 @@ int VnodeClearCache(void) return count; } + +struct Vnode *GetCurrRootVnode(void) +{ +#ifdef LOSCFG_CHROOT + LosProcessCB *curr = OsCurrProcessGet(); + return curr->files->rootVnode; +#else + return g_rootVnode; +#endif +} diff --git a/kernel/Kconfig b/kernel/Kconfig index 4cad992a02f77cb85c9d843b9c3a071102bfe67c..a8d68bb5d5c27e8dd909f402946e99af77879413 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -83,6 +83,16 @@ config UTS_CONTAINER default n depends on KERNEL_CONTAINER +config MNT_CONTAINER + bool "Enable MNT container Feature" + default n + depends on KERNEL_CONTAINER + +config CHROOT + bool "Enable chroot" + default n + depends on MNT_CONTAINER + ######################### config options of extended ##################### source "kernel/extended/Kconfig" diff --git a/kernel/base/BUILD.gn b/kernel/base/BUILD.gn index 72d734da1a7f6c413600fb5ab2521c542dde8fef..a4820041ae03d4371d3c9e64eb1c219d657c3d32 100644 --- a/kernel/base/BUILD.gn +++ b/kernel/base/BUILD.gn @@ -33,6 +33,7 @@ module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { sources = [ "container/los_container.c", + "container/los_mnt_container.c", "container/los_pid_container.c", "container/los_uts_container.c", "core/los_bitmap.c", diff --git a/kernel/base/container/los_container.c b/kernel/base/container/los_container.c index 40e43e7d74b60b252122668e0376fc358fc98fe4..6eed4e73b8c631b1c8c44139c89f9af5121a30fc 100644 --- a/kernel/base/container/los_container.c +++ b/kernel/base/container/los_container.c @@ -56,6 +56,9 @@ VOID OsInitRootContainer(VOID) #endif #ifdef LOSCFG_UTS_CONTAINER (VOID)OsInitRootUtsContainer(&g_rootContainer.utsContainer); +#endif +#ifdef LOSCFG_MNT_CONTAINER + (VOID)OsInitRootMntContainer(&g_rootContainer.mntContainer); #endif return; } @@ -106,6 +109,12 @@ UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent if (ret != LOS_OK) { return ret; } +#endif +#ifdef LOSCFG_MNT_CONTAINER + ret = OsCopyMntContainer(flags, child, parent); + if (ret != LOS_OK) { + return ret; + } #endif return ret; } @@ -123,6 +132,10 @@ VOID OsContainersDestroy(LosProcessCB *processCB) OsUtsContainersDestroy(processCB); #endif +#ifdef LOSCFG_MNT_CONTAINER + OsMntContainersDestroy(processCB); +#endif + #ifndef LOSCFG_PID_CONTAINER LOS_AtomicDec(&curr->container->rc); if (LOS_AtomicRead(&processCB->container->rc) == 1) { @@ -143,6 +156,8 @@ UINT32 OsGetContainerID(Container *container, ContainerType type) return OsGetPidContainerID(container->pidContainer); case UTS_CONTAINER: return OsGetUtsContainerID(container->utsContainer); + case MNT_CONTAINER: + return OsGetMntContainerID(container->mntContainer); default: break; } diff --git a/kernel/base/container/los_mnt_container.c b/kernel/base/container/los_mnt_container.c new file mode 100644 index 0000000000000000000000000000000000000000..1782ff47ff1b601c45c71971bf74611a4fe858ad --- /dev/null +++ b/kernel/base/container/los_mnt_container.c @@ -0,0 +1,165 @@ +/* + * 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 +#include "los_mnt_container_pri.h" +#include "los_container_pri.h" +#include "los_process_pri.h" +#include "sys/mount.h" +#include "vnode.h" +#include "internal.h" + +#ifdef LOSCFG_MNT_CONTAINER +STATIC UINT32 g_currentMntContainerNum; + +LIST_HEAD *GetContainerMntList(VOID) +{ + return &OsCurrProcessGet()->container->mntContainer->mountList; +} + +STATIC UINT32 CreateMntContainer(MntContainer **newMntContainer) +{ + UINT32 intSave; + MntContainer *mntContainer = (MntContainer *)LOS_MemAlloc(m_aucSysMem1, sizeof(MntContainer)); + if (mntContainer == NULL) { + return ENOMEM; + } + mntContainer->containerID = OsAllocContainerID(); + LOS_AtomicSet(&mntContainer->rc, 1); + LOS_ListInit(&mntContainer->mountList); + + SCHEDULER_LOCK(intSave); + g_currentMntContainerNum++; + *newMntContainer = mntContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +STATIC UINT32 CopyMountList(MntContainer *parentContainer, MntContainer *newContainer) +{ + struct Mount *mnt = NULL; + VnodeHold(); + LOS_DL_LIST_FOR_EACH_ENTRY(mnt, &parentContainer->mountList, struct Mount, mountList) { + struct Mount *newMnt = (struct Mount *)zalloc(sizeof(struct Mount)); + if (newMnt == NULL) { + VnodeDrop(); + return ENOMEM; + } + *newMnt = *mnt; + LOS_ListTailInsert(&newContainer->mountList, &newMnt->mountList); + newMnt->vnodeCovered->mntCount++; + } + VnodeDrop(); + return LOS_OK; +} + +UINT32 OsCopyMntContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 ret; + UINT32 intSave; + MntContainer *currMntContainer = parent->container->mntContainer; + + if (!(flags & CLONE_NEWNS)) { + SCHEDULER_LOCK(intSave); + LOS_AtomicInc(&currMntContainer->rc); + child->container->mntContainer = currMntContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + ret = CreateMntContainer(&child->container->mntContainer); + if (ret != LOS_OK) { + return ret; + } + + return CopyMountList(currMntContainer, child->container->mntContainer); +} + +STATIC VOID FreeMountList(LIST_HEAD *mountList) +{ + struct Mount *mnt = NULL; + struct Mount *nextMnt = NULL; + + VnodeHold(); + if (LOS_ListEmpty(mountList)) { + VnodeDrop(); + return; + } + + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(mnt, nextMnt, mountList, struct Mount, mountList) { + if (mnt->vnodeCovered->mntCount > 0) { + mnt->vnodeCovered->mntCount--; + LOS_ListDelete(&mnt->mountList); + free(mnt); + } else { + umount(mnt->pathName); + } + } + VnodeDrop(); + return; +} + +VOID OsMntContainersDestroy(LosProcessCB *curr) +{ + UINT32 intSave; + if (curr->container == NULL) { + return; + } + + SCHEDULER_LOCK(intSave); + MntContainer *mntContainer = curr->container->mntContainer; + if (mntContainer != NULL) { + if (LOS_AtomicRead(&mntContainer->rc) == 0) { + g_currentMntContainerNum--; + FreeMountList(&mntContainer->mountList); + curr->container->mntContainer = NULL; + SCHEDULER_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem1, mntContainer); + return; + } + } + SCHEDULER_UNLOCK(intSave); + return; +} + +UINT32 OsGetMntContainerID(MntContainer *mntContainer) +{ + if (mntContainer == NULL) { + return OS_INVALID_VALUE; + } + + return mntContainer->containerID; +} + +UINT32 OsInitRootMntContainer(MntContainer **mntContainer) +{ + return CreateMntContainer(mntContainer); +} +#endif diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index c9d0789b59ae82c17ebdcb513aa206651d39ee2e..c597f24714af95be81e89a973e706d77c3242cfa 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -2058,6 +2058,9 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size) #ifdef LOSCFG_UTS_CONTAINER cloneFlag |= CLONE_NEWUTS; #endif +#ifdef LOSCFG_MNT_CONTAINER + cloneFlag |= CLONE_NEWNS; +#endif #endif if (flags & (~cloneFlag)) { diff --git a/kernel/base/include/los_container_pri.h b/kernel/base/include/los_container_pri.h index 38d365f23bc30d31dde25ccba9937cd70133f07c..0b9d5682b915508cbe79c265a7613d2f5ddc56b5 100644 --- a/kernel/base/include/los_container_pri.h +++ b/kernel/base/include/los_container_pri.h @@ -39,11 +39,15 @@ #ifdef LOSCFG_UTS_CONTAINER #include "los_uts_container_pri.h" #endif +#ifdef LOSCFG_MNT_CONTAINER +#include "los_mnt_container_pri.h" +#endif typedef enum { CONTAINER = 0, PID_CONTAINER, UTS_CONTAINER, + MNT_CONTAINER, } ContainerType; typedef struct Container { @@ -54,6 +58,9 @@ typedef struct Container { #ifdef LOSCFG_UTS_CONTAINER struct UtsContainer *utsContainer; #endif +#ifdef LOSCFG_MNT_CONTAINER + struct MntContainer *mntContainer; +#endif } Container; VOID OsContainerInitSystemProcess(LosProcessCB *processCB); diff --git a/kernel/base/include/los_mnt_container_pri.h b/kernel/base/include/los_mnt_container_pri.h new file mode 100644 index 0000000000000000000000000000000000000000..ded748b9439748f96cc59c5c88786e726d03b363 --- /dev/null +++ b/kernel/base/include/los_mnt_container_pri.h @@ -0,0 +1,60 @@ +/* + * 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. + */ + +#ifndef _LOS_MNT_CONTAINER_PRI_H +#define _LOS_MNT_CONTAINER_PRI_H + +#include "fs/mount.h" +#include "sched.h" +#include "los_atomic.h" +#include "vnode.h" +#include "stdlib.h" + +#ifdef LOSCFG_MNT_CONTAINER +typedef struct ProcessCB LosProcessCB; + +typedef struct MntContainer { + Atomic rc; + UINT32 containerID; + LIST_HEAD mountList; +} MntContainer; + +LIST_HEAD *GetContainerMntList(VOID); + +UINT32 OsInitRootMntContainer(MntContainer **mntContainer); + +UINT32 OsCopyMntContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); + +VOID OsMntContainersDestroy(LosProcessCB *curr); + +UINT32 OsGetMntContainerID(MntContainer *mntContainer); + +#endif +#endif diff --git a/syscall/fs_syscall.c b/syscall/fs_syscall.c index 11aa60b883715d8551dad0e15517acb701ab6012..1217524c7335186325e52d8fafd719e024d0fbc8 100644 --- a/syscall/fs_syscall.c +++ b/syscall/fs_syscall.c @@ -2717,4 +2717,28 @@ OUT: return (ret == -1) ? -get_errno() : ret; } +#ifdef LOSCFG_CHROOT +int SysChroot(const char *path) +{ + int ret; + char *pathRet = NULL; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + ret = chroot(path ? pathRet : NULL); + if (ret < 0) { + ret = -get_errno(); + } +OUT: + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + return ret; +} +#endif #endif diff --git a/syscall/los_syscall.h b/syscall/los_syscall.h index 2a67887d09fcc4e1be656316c6db9c5bd486b517..eee7f1fe5c6ebe7f250b9fae43228202896410de 100644 --- a/syscall/los_syscall.h +++ b/syscall/los_syscall.h @@ -217,7 +217,7 @@ extern int do_mkdir(int dirfd, const char *pathname, mode_t mode); extern int do_rmdir(int dirfd, const char *pathname); extern int do_rename(int oldfd, const char *oldpath, int newfd, const char *newpath); extern int do_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, - struct timeval *timeout, PollFun poll); + struct timeval *timeout, PollFun poll); extern int do_readdir(int fd, struct dirent **de, unsigned int count); extern ssize_t preadv(int __fd, const struct iovec *__iov, int __count, off_t __offset); extern ssize_t pwritev(int __fd, const struct iovec *__iov, int __count, off_t __offset); @@ -284,7 +284,7 @@ extern int SysFstatat64(int fd, const char *restrict path, struct kstat *restric extern int SysFcntl64(int fd, int cmd, void *arg); extern int SysPoll(struct pollfd *fds, nfds_t nfds, int timeout); extern int SysPpoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, - const sigset_t *sigmask, int nsig); + const sigset_t *sigmask, int nsig); extern int SysPrctl(int option, ...); extern ssize_t SysPread64(int fd, void *buf, size_t nbytes, off64_t offset); extern ssize_t SysPwrite64(int fd, const void *buf, size_t nbytes, off64_t offset); @@ -317,5 +317,8 @@ extern int SysGetrusage(int what, struct rusage *ru); extern long SysSysconf(int name); extern int SysUgetrlimit(int resource, unsigned long long k_rlim[2]); extern int SysSetrlimit(int resource, unsigned long long k_rlim[2]); +#ifdef LOSCFG_CHROOT +extern int SysChroot(const char *path); +#endif #endif #endif /* _LOS_SYSCALL_H */ diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index 8cffd0224d79f57ffef58bc7f3a5b0a16152453c..614de7d046017c5974d5ba8d1ba20522dbcb44d6 100644 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -263,6 +263,10 @@ SYSCALL_HAND_DEF(__NR_shmctl, SysShmCtl, int, ARG_NUM_3) SYSCALL_HAND_DEF(__NR_statx, SysStatx, int, ARG_NUM_5) +#ifdef LOSCFG_CHROOT +SYSCALL_HAND_DEF(__NR_chroot, SysChroot, int, ARG_NUM_1) +#endif + /* LiteOS customized syscalls, not compatible with ARM EABI */ SYSCALL_HAND_DEF(__NR_pthread_set_detach, SysUserThreadSetDetach, int, ARG_NUM_1) SYSCALL_HAND_DEF(__NR_pthread_join, SysThreadJoin, int, ARG_NUM_1) diff --git a/testsuites/unittest/config.gni b/testsuites/unittest/config.gni index 28697b16f1285255040c0900c81105f57f9ca5c7..73f2987136b63319f1ea9d4026b0740afafa8f66 100644 --- a/testsuites/unittest/config.gni +++ b/testsuites/unittest/config.gni @@ -135,6 +135,7 @@ if (defined(LOSCFG_PROC_PROCESS_DIR)) { LOSCFG_USER_TEST_CONTAINER = false LOSCFG_USER_TEST_PID_CONTAINER = false LOSCFG_USER_TEST_UTS_CONTAINER = false +LOSCFG_USER_TEST_MNT_CONTAINER = false if (defined(LOSCFG_KERNEL_CONTAINER)) { LOSCFG_USER_TEST_CONTAINER = true if (defined(LOSCFG_PID_CONTAINER)) { @@ -143,4 +144,7 @@ if (defined(LOSCFG_KERNEL_CONTAINER)) { if (defined(LOSCFG_UTS_CONTAINER)) { LOSCFG_USER_TEST_UTS_CONTAINER = true } + if (defined(LOSCFG_MNT_CONTAINER)) { + LOSCFG_USER_TEST_MNT_CONTAINER = true + } } diff --git a/testsuites/unittest/container/BUILD.gn b/testsuites/unittest/container/BUILD.gn index f2b4e9d0db787ff0f599554d1e91999ada727441..f130dcd02c100e47da96374f899ebd22dd906ee6 100644 --- a/testsuites/unittest/container/BUILD.gn +++ b/testsuites/unittest/container/BUILD.gn @@ -38,6 +38,9 @@ config("container_config") { if (defined(LOSCFG_USER_TEST_UTS_CONTAINER)) { cflags += [ "-DLOSCFG_USER_TEST_UTS_CONTAINER" ] } + if (defined(LOSCFG_USER_TEST_MNT_CONTAINER)) { + cflags += [ "-DLOSCFG_USER_TEST_MNT_CONTAINER" ] + } cflags_cc = cflags } diff --git a/testsuites/unittest/container/It_container_test.cpp b/testsuites/unittest/container/It_container_test.cpp index 0142870104a156dbdb324d654f12fdbc6433de62..d7ef045302fd517e38428ff9a917e4ff3c2ed17e 100644 --- a/testsuites/unittest/container/It_container_test.cpp +++ b/testsuites/unittest/container/It_container_test.cpp @@ -34,6 +34,7 @@ const char *USERDATA_DIR_NAME = "/userdata"; const char *ACCESS_FILE_NAME = "/userdata/mntcontainertest"; +const char *MNT_ACCESS_FILE_NAME = "/mntcontainertest"; const char *USERDATA_DEV_NAME = "/dev/mmcblk0p2"; const char *FS_TYPE = "vfat"; @@ -138,6 +139,7 @@ HWTEST_F(ContainerTest, ItUtsContainer001, TestSize.Level0) { ItUtsContainer001(); } + /** * @tc.name: Container_UTS_Test_002 * @tc.desc: uts container function test case @@ -150,7 +152,71 @@ HWTEST_F(ContainerTest, ItUtsContainer002, TestSize.Level0) ItUtsContainer002(); } #endif -#endif + +#if defined(LOSCFG_USER_TEST_MNT_CONTAINER) +/** +* @tc.name: Container_MNT_Test_001 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer001, TestSize.Level0) +{ + ItMntContainer001(); +} + +/** +* @tc.name: Container_MNT_Test_002 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer002, TestSize.Level0) +{ + ItMntContainer002(); +} + +/** +* @tc.name: Container_MNT_Test_003 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer003, TestSize.Level0) +{ + ItMntContainer003(); +} + +/** +* @tc.name: Container_MNT_Test_004 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer004, TestSize.Level0) +{ + ItMntContainer004(); +} + +/** +* @tc.name: chroot_Test_001 +* @tc.desc: chroot function test case +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ + +HWTEST_F(ContainerTest, ItContainerChroot001, TestSize.Level0) +{ + ItContainerChroot001(); +} + +#endif /* LOSCFG_MNT_CONTAINER */ +#endif /* LOSCFG_USER_TEST_SMOKE */ #if defined(LOSCFG_USER_TEST_FULL) #if defined(LOSCFG_USER_TEST_PID_CONTAINER) diff --git a/testsuites/unittest/container/It_container_test.h b/testsuites/unittest/container/It_container_test.h index 9dde06c4788d8ba531b2da9f6cfe20d22465f416..4323906d8ff9a9d9e353667db01e17e9016351b0 100644 --- a/testsuites/unittest/container/It_container_test.h +++ b/testsuites/unittest/container/It_container_test.h @@ -63,6 +63,7 @@ const int CONTAINER_THIRD_PID = 3; extern const char *USERDATA_DIR_NAME; extern const char *ACCESS_FILE_NAME; +extern const char *MNT_ACCESS_FILE_NAME; extern const char *USERDATA_DEV_NAME; extern const char *FS_TYPE; @@ -80,6 +81,7 @@ extern std::string ReadlinkContainer(int pid, const std::string& containerType); #if defined(LOSCFG_USER_TEST_SMOKE) void ItContainer001(void); +void ItContainerChroot001(void); #if defined(LOSCFG_USER_TEST_PID_CONTAINER) void ItPidContainer023(void); #endif @@ -87,6 +89,16 @@ void ItPidContainer023(void); void ItUtsContainer001(void); void ItUtsContainer002(void); #endif +#if defined(LOSCFG_USER_TEST_MNT_CONTAINER) +void ItMntContainer001(void); +void ItMntContainer002(void); +void ItMntContainer003(void); +void ItMntContainer004(void); +void ItMntContainer005(void); +void ItMntContainer006(void); +void ItMntContainer007(void); +void ItMntContainer008(void); +#endif #endif #if defined(LOSCFG_USER_TEST_FULL) diff --git a/testsuites/unittest/container/config.gni b/testsuites/unittest/container/config.gni index c5befbd095f74783a89d2239375fcdaf7fe5e501..772bf450588b82d4d06f63af0df915d42a3b3998 100644 --- a/testsuites/unittest/container/config.gni +++ b/testsuites/unittest/container/config.gni @@ -36,7 +36,11 @@ common_include_dirs = [ sources_entry = [ "$TEST_UNITTEST_DIR/container/It_container_test.cpp" ] -sources_smoke = [ "$TEST_UNITTEST_DIR/container/smoke/It_container_001.cpp" ] +sources_smoke = [ + "$TEST_UNITTEST_DIR/container/smoke/It_container_001.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_container_chroot_001.cpp", +] + sources_full = [] if (defined(LOSCFG_USER_TEST_PID_CONTAINER)) { @@ -75,3 +79,15 @@ if (defined(LOSCFG_USER_TEST_UTS_CONTAINER)) { sources_full += [ "$TEST_UNITTEST_DIR/container/full/It_uts_container_003.cpp" ] } +if (defined(LOSCFG_USER_TEST_MNT_CONTAINER)) { + sources_smoke += [ + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_001.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_002.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_003.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_004.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_005.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_006.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_007.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_008.cpp", + ] +} diff --git a/testsuites/unittest/container/smoke/It_container_chroot_001.cpp b/testsuites/unittest/container/smoke/It_container_chroot_001.cpp new file mode 100644 index 0000000000000000000000000000000000000000..870cf65f3d9a040485136d7e48a2aabb1f782e7f --- /dev/null +++ b/testsuites/unittest/container/smoke/It_container_chroot_001.cpp @@ -0,0 +1,106 @@ +/* + * 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" +using namespace std; + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = chroot(USERDATA_DIR_NAME); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret == 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = access(MNT_ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_6; + } + + return 0; +} + +void ItContainerChroot001(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, CLONE_NEWNS, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_NE(ret, 0); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_NE(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_mnt_container_001.cpp b/testsuites/unittest/container/smoke/It_mnt_container_001.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2cc9d390fb48c73542129e93998c8be5850ce53b --- /dev/null +++ b/testsuites/unittest/container/smoke/It_mnt_container_001.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/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = umount(USERDATA_DIR_NAME); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret == 0) { + return EXIT_CODE_ERRNO_4; + } + + return 0; +} + +/* mount container clone test: mount in parent, clone without NEW_NS, umount in child */ +void ItMntContainer001(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, 0, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_NE(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_mnt_container_002.cpp b/testsuites/unittest/container/smoke/It_mnt_container_002.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fc6c30bdfd28acf31dab1d7279abdab511b93636 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_mnt_container_002.cpp @@ -0,0 +1,100 @@ +/* + * 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/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = umount(USERDATA_DIR_NAME); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret == 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = umount(USERDATA_DIR_NAME); + if (ret != 0) { + return EXIT_CODE_ERRNO_6; + } + + return 0; +} + +/* mount container clone test: mount in parent, clone with NEW_NS, umount in child */ +void ItMntContainer002(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, CLONE_NEWNS, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_mnt_container_003.cpp b/testsuites/unittest/container/smoke/It_mnt_container_003.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc3a9f0bc9c913a310e1b2b6bdf66a4f883cd4cd --- /dev/null +++ b/testsuites/unittest/container/smoke/It_mnt_container_003.cpp @@ -0,0 +1,94 @@ +/* + * 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/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + return 0; +} + +/* mount container clone test: clone without NEW_NS, mount in child */ +void ItMntContainer003(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, 0, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_NE(ret, 0); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_mnt_container_004.cpp b/testsuites/unittest/container/smoke/It_mnt_container_004.cpp new file mode 100644 index 0000000000000000000000000000000000000000..49e9f4b2256e5f57ce9f3521f3c4502be6cb9579 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_mnt_container_004.cpp @@ -0,0 +1,92 @@ +/* + * 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/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + return 0; +} + +/* mount container clone test: clone with NEW_NS, mount in child */ +void ItMntContainer004(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, CLONE_NEWNS, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_NE(ret, 0); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_NE(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_mnt_container_005.cpp b/testsuites/unittest/container/smoke/It_mnt_container_005.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aa70e29bf94d407b7fc616ac0e2e269bdcbef7fd --- /dev/null +++ b/testsuites/unittest/container/smoke/It_mnt_container_005.cpp @@ -0,0 +1,59 @@ +/* + * 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" + +/* + * mount container unshare test: unshare in current pcb with NEW_NS + */ +void ItMntContainer005(void) +{ + int ret; + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + ret = unshare(CLONE_NEWNS); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_NE(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_mnt_container_006.cpp b/testsuites/unittest/container/smoke/It_mnt_container_006.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6de073779695df219937e4e3624db8794644bf0e --- /dev/null +++ b/testsuites/unittest/container/smoke/It_mnt_container_006.cpp @@ -0,0 +1,103 @@ +/* + * 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/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = unshare(CLONE_NEWNS); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = umount(USERDATA_DIR_NAME); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret == 0) { + return EXIT_CODE_ERRNO_6; + } + + return 0; +} + +/* + * mount container unshare test: mount in parent, child clone without NEW_NS, + * unshare in child with NEW_NS, umount in child. + */ +void ItMntContainer006(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + stackTop = stack + STACK_SIZE; + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); + + auto pid = clone(ChildFunc, stackTop, 0, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_mnt_container_007.cpp b/testsuites/unittest/container/smoke/It_mnt_container_007.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1b5cf5cb386df1b71ec05e7264d82093a4940bd7 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_mnt_container_007.cpp @@ -0,0 +1,100 @@ +/* + * 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/mount.h" + +static int ChildFunc(void *arg) +{ + int ret; + int value = *((int *)arg); + + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + + ret = unshare(CLONE_NEWNS); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = access(ACCESS_FILE_NAME, F_OK); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + return 0; +} + +/* + * mount container unshare test: child clone without NEW_NS, + * unshare in child with NEW_NS, umount in child + */ +void ItMntContainer007(void) +{ + int ret; + int status = 0; + int childReturn = 0; + int arg = CHILD_FUNC_ARG; + char *stack = nullptr; + char *stackTop = nullptr; + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + ASSERT_NE(stack, MAP_FAILED); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_EQ(ret, 0); + + stackTop = stack + STACK_SIZE; + auto pid = clone(ChildFunc, stackTop, 0, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); + + ret = access(ACCESS_FILE_NAME, F_OK); + ASSERT_NE(ret, 0); + + ret = umount(USERDATA_DIR_NAME); + ASSERT_NE(ret, 0); + + ret = mount(USERDATA_DEV_NAME, USERDATA_DIR_NAME, FS_TYPE, 0, nullptr); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_mnt_container_008.cpp b/testsuites/unittest/container/smoke/It_mnt_container_008.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c4d9855b312a2e84acb6b5b88cff3b4c82bf4373 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_mnt_container_008.cpp @@ -0,0 +1,90 @@ +/* + * 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" + +const int CHILD_FUNC_EXITCODE = 3; +const int PATH_LENGTH = 100; + +static int ChildFun(void *p) +{ + (void)p; + const int sleepSecond = 2; + (void)getpid(); + (void)sleep(sleepSecond); + return CHILD_FUNC_EXITCODE; +} + +void ItMntContainer008(void) +{ + pid_t parentPid; + int childPid; + void *pstk = nullptr; + int fd; + int ret; + int status; + char targetpath[PATH_LENGTH]; + char old_mnt_link[PATH_LENGTH]; + char new_mnt_link[PATH_LENGTH]; + std::string containerType = "mnt"; + int setFlag = CLONE_NEWNS; + + parentPid = getpid(); + pstk = malloc(STACK_SIZE); + ASSERT_NE(pstk, nullptr); + + childPid = clone(ChildFun, (char *)pstk + STACK_SIZE, CLONE_NEWNS, nullptr); + ASSERT_NE(childPid, -1); + + auto linkBuffer = ReadlinkContainer(parentPid, containerType.c_str()); + ret = sprintf_s(old_mnt_link, PATH_LENGTH, "%s", linkBuffer.c_str()); + ASSERT_GT(ret, 0); + ret = sprintf_s(targetpath, PATH_LENGTH, "/proc/%d/container/mnt", childPid); + ASSERT_GT(ret, 0); + fd = open(targetpath, O_RDONLY | O_CLOEXEC); + ASSERT_NE(fd, -1); + + ret = setns(fd, setFlag); + ASSERT_EQ(ret, 0); + + ret = close(fd); + ASSERT_EQ(ret, 0); + + linkBuffer = ReadlinkContainer(parentPid, containerType.c_str()); + + ret = sprintf_s(new_mnt_link, PATH_LENGTH, "%s", linkBuffer.c_str()); + ASSERT_GT(ret, 0); + ASSERT_STRNE(old_mnt_link, new_mnt_link); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, CHILD_FUNC_EXITCODE); +} diff --git a/testsuites/unittest/process/fs/smoke/It_process_fs_006.cpp b/testsuites/unittest/process/fs/smoke/It_process_fs_006.cpp index fc3fc570fd75ea364e50ff700a07152ca9168fd5..2610f27d5cd8d927c2d16f911d8c1fe7ed919015 100644 --- a/testsuites/unittest/process/fs/smoke/It_process_fs_006.cpp +++ b/testsuites/unittest/process/fs/smoke/It_process_fs_006.cpp @@ -47,7 +47,7 @@ static void WriteContainer(const char *filepath, int value) { PrintTest("writeproc %d >> %s\n", value, filepath); int fd = open(filepath, O_WRONLY); - ASSERT_EQ(fd, -1); + ASSERT_NE(fd, -1); char buf[configLen]; size_t twd = sprintf_s(buf, configLen, "%d", value); ASSERT_GT(twd, 0); @@ -78,7 +78,7 @@ static void ReadContainer(std::string strFile, int value) static void ErrWriteContainer0(const char *filepath) { int fd = open(filepath, O_WRONLY); - ASSERT_EQ(fd, -1); + ASSERT_NE(fd, -1); char buf[configLen]; int invalidNum = 0; size_t twd1 = sprintf_s(buf, configLen, "%d", invalidNum); @@ -92,7 +92,7 @@ static void ErrWriteContainer0(const char *filepath) static void ErrWriteContainer65(const char *filepath) { int fd = open(filepath, O_WRONLY); - ASSERT_EQ(fd, -1); + ASSERT_NE(fd, -1); char buf[configLen]; int invalidNum = 65; size_t twd2 = sprintf_s(buf, configLen, "%d", invalidNum);