commit
57455849ca
1
BUILD.gn
1
BUILD.gn
|
@ -250,6 +250,7 @@ config("container_config") {
|
|||
"-DLOSCFG_CHROOT",
|
||||
"-DLOSCFG_IPC_CONTAINER",
|
||||
"-DLOSCFG_TIME_CONTAINER",
|
||||
"-DLOSCFG_USER_CONTAINER",
|
||||
"-DLOSCFG_PROC_PROCESS_DIR",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -46,6 +46,11 @@ typedef enum {
|
|||
#ifdef LOSCFG_KERNEL_CPUP
|
||||
PROC_PID_CPUP,
|
||||
#endif
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
PROC_UID_MAP,
|
||||
PROC_GID_MAP,
|
||||
#endif
|
||||
PROC_P_TYPE_MAX,
|
||||
} ProcessDataType;
|
||||
|
||||
struct ProcProcess {
|
||||
|
@ -84,6 +89,8 @@ static ssize_t ProcessContainerLink(unsigned int containerID, ContainerType type
|
|||
count = snprintf_s(buffer, bufLen, bufLen - 1, "'ipc:[%u]'", containerID);
|
||||
} else if ((type == TIME_CONTAINER) || (type == TIME_CHILD_CONTAINER)) {
|
||||
count = snprintf_s(buffer, bufLen, bufLen - 1, "'time:[%u]'", containerID);
|
||||
} else if (type == USER_CONTAINER) {
|
||||
count = snprintf_s(buffer, bufLen, bufLen - 1, "'user:[%u]'", containerID);
|
||||
}
|
||||
|
||||
if (count < 0) {
|
||||
|
@ -105,7 +112,7 @@ static ssize_t ProcessContainerReadLink(struct ProcDirEntry *entry, char *buffer
|
|||
}
|
||||
LosProcessCB *processCB = ProcGetProcessCB(data);
|
||||
SCHEDULER_LOCK(intSave);
|
||||
UINT32 containerID = OsGetContainerID(processCB->container, (ContainerType)data->type);
|
||||
UINT32 containerID = OsGetContainerID(processCB, (ContainerType)data->type);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
if (containerID != OS_INVALID_VALUE) {
|
||||
return ProcessContainerLink(containerID, (ContainerType)data->type, buffer, bufLen);
|
||||
|
@ -320,6 +327,121 @@ static const struct ProcFileOperations TIME_CONTAINER_FOPS = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
|
||||
static void *MemdupUserNul(const void *src, size_t len)
|
||||
{
|
||||
char *des = NULL;
|
||||
if (len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
des = LOS_MemAlloc(OS_SYS_MEM_ADDR, len + 1);
|
||||
if (des == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (LOS_ArchCopyFromUser(des, src, len) != 0) {
|
||||
(VOID)LOS_MemFree(OS_SYS_MEM_ADDR, des);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
des[len] = '\0';
|
||||
return des;
|
||||
}
|
||||
|
||||
static LosProcessCB *ProcUidGidMapWriteCheck(struct ProcFile *pf, const char *buf, size_t size,
|
||||
char **kbuf, ProcessDataType *type)
|
||||
{
|
||||
if ((pf == NULL) || (size <= 0) || (size >= PAGE_SIZE)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ProcDirEntry *entry = pf->pPDE;
|
||||
if (entry == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ProcessData *data = (struct ProcessData *)entry->data;
|
||||
if (data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*kbuf = MemdupUserNul(buf, size);
|
||||
if (*kbuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
*type = (ProcessDataType)data->type;
|
||||
return ProcGetProcessCB(data);
|
||||
}
|
||||
|
||||
static ssize_t ProcIDMapWrite(struct ProcFile *file, const char *buf, size_t size, loff_t *ppos)
|
||||
{
|
||||
(void)ppos;
|
||||
char *kbuf = NULL;
|
||||
int ret;
|
||||
unsigned int intSave;
|
||||
ProcessDataType type = PROC_P_TYPE_MAX;
|
||||
LosProcessCB *processCB = ProcUidGidMapWriteCheck(file, buf, size, &kbuf, &type);
|
||||
if (processCB == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if ((processCB->credentials == NULL) || (processCB->credentials->userContainer == NULL)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
(void)LOS_MemFree(m_aucSysMem1, kbuf);
|
||||
return -EINVAL;
|
||||
}
|
||||
UserContainer *userContainer = processCB->credentials->userContainer;
|
||||
if (userContainer->parent == NULL) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
(void)LOS_MemFree(m_aucSysMem1, kbuf);
|
||||
return -EPERM;
|
||||
}
|
||||
if (type == PROC_UID_MAP) {
|
||||
ret = OsUserContainerMapWrite(file, kbuf, size, CAP_SETUID,
|
||||
&userContainer->uidMap, &userContainer->parent->uidMap);
|
||||
} else {
|
||||
ret = OsUserContainerMapWrite(file, kbuf, size, CAP_SETGID,
|
||||
&userContainer->gidMap, &userContainer->parent->gidMap);
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
(void)LOS_MemFree(m_aucSysMem1, kbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ProcIDMapRead(struct SeqBuf *seqBuf, void *v)
|
||||
{
|
||||
unsigned int intSave;
|
||||
if ((seqBuf == NULL) || (v == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
struct ProcessData *data = (struct ProcessData *)v;
|
||||
LosProcessCB *processCB = ProcGetProcessCB(data);
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if ((processCB->credentials == NULL) || (processCB->credentials->userContainer == NULL)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return -EINVAL;
|
||||
}
|
||||
UserContainer *userContainer = processCB->credentials->userContainer;
|
||||
if ((userContainer != NULL) && (userContainer->parent == NULL)) {
|
||||
UidGidExtent uidGidExtent = userContainer->uidMap.extent[0];
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
(void)LosBufPrintf(seqBuf, "%d %d %u\n", uidGidExtent.first, uidGidExtent.lowerFirst,
|
||||
uidGidExtent.count);
|
||||
return 0;
|
||||
}
|
||||
SCHEDULER_LOCK(intSave);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ProcFileOperations UID_GID_MAP_FOPS = {
|
||||
.read = ProcIDMapRead,
|
||||
.write = ProcIDMapWrite,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int ProcProcessRead(struct SeqBuf *m, void *v)
|
||||
{
|
||||
if ((m == NULL) || (v == NULL)) {
|
||||
|
@ -432,6 +554,26 @@ static struct ProcProcess g_procProcess[] = {
|
|||
.fileOps = &TIME_CONTAINER_FOPS
|
||||
},
|
||||
#endif
|
||||
#ifdef LOSCFG_IPC_CONTAINER
|
||||
{
|
||||
.name = "container/user",
|
||||
.mode = S_IFLNK,
|
||||
.type = USER_CONTAINER,
|
||||
.fileOps = &PID_CONTAINER_FOPS
|
||||
},
|
||||
{
|
||||
.name = "uid_map",
|
||||
.mode = 0,
|
||||
.type = PROC_UID_MAP,
|
||||
.fileOps = &UID_GID_MAP_FOPS
|
||||
},
|
||||
{
|
||||
.name = "gid_map",
|
||||
.mode = 0,
|
||||
.type = PROC_GID_MAP,
|
||||
.fileOps = &UID_GID_MAP_FOPS
|
||||
},
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -103,6 +103,11 @@ config TIME_CONTAINER
|
|||
default n
|
||||
depends on KERNEL_CONTAINER
|
||||
|
||||
config USER_CONTAINER
|
||||
bool "Enable user container"
|
||||
default n
|
||||
depends on KERNEL_CONTAINER
|
||||
|
||||
######################### config options of extended #####################
|
||||
source "kernel/extended/Kconfig"
|
||||
|
||||
|
|
|
@ -33,10 +33,12 @@ module_name = get_path_info(rebase_path("."), "name")
|
|||
kernel_module(module_name) {
|
||||
sources = [
|
||||
"container/los_container.c",
|
||||
"container/los_credentials.c",
|
||||
"container/los_ipc_container.c",
|
||||
"container/los_mnt_container.c",
|
||||
"container/los_pid_container.c",
|
||||
"container/los_time_container.c",
|
||||
"container/los_user_container.c",
|
||||
"container/los_uts_container.c",
|
||||
"core/los_bitmap.c",
|
||||
"core/los_info.c",
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
|
||||
STATIC Container g_rootContainer;
|
||||
STATIC Atomic g_containerCount = 0xF0000000U;
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
STATIC Credentials *g_rootCredentials = NULL;
|
||||
#endif
|
||||
|
||||
UINT32 OsAllocContainerID(VOID)
|
||||
{
|
||||
|
@ -43,6 +46,9 @@ UINT32 OsAllocContainerID(VOID)
|
|||
VOID OsContainerInitSystemProcess(LosProcessCB *processCB)
|
||||
{
|
||||
processCB->container = &g_rootContainer;
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
processCB->credentials = g_rootCredentials;
|
||||
#endif
|
||||
LOS_AtomicInc(&processCB->container->rc);
|
||||
#ifdef LOSCFG_PID_CONTAINER
|
||||
(VOID)OsAllocSpecifiedVpidUnsafe(processCB->processID, processCB->container->pidContainer, processCB, NULL);
|
||||
|
@ -52,6 +58,9 @@ VOID OsContainerInitSystemProcess(LosProcessCB *processCB)
|
|||
|
||||
VOID OsInitRootContainer(VOID)
|
||||
{
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
OsInitRootUserCredentials(&g_rootCredentials);
|
||||
#endif
|
||||
#ifdef LOSCFG_PID_CONTAINER
|
||||
(VOID)OsInitRootPidContainer(&g_rootContainer.pidContainer);
|
||||
g_rootContainer.pidForChildContainer = g_rootContainer.pidContainer;
|
||||
|
@ -95,6 +104,12 @@ STATIC UINT32 CopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *p
|
|||
return ret;
|
||||
}
|
||||
#endif
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
ret = OsCopyCredentials(flags, child, parent);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#ifdef LOSCFG_UTS_CONTAINER
|
||||
ret = OsCopyUtsContainer(flags, child, parent);
|
||||
if (ret != LOS_OK) {
|
||||
|
@ -182,6 +197,10 @@ VOID OsContainersDestroy(LosProcessCB *processCB)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
OsUserContainerDestroy(processCB);
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_UTS_CONTAINER
|
||||
OsUtsContainerDestroy(processCB->container);
|
||||
#endif
|
||||
|
@ -245,8 +264,9 @@ STATIC VOID DeInitContainers(UINT32 flags, Container *container, LosProcessCB *p
|
|||
SCHEDULER_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
UINT32 OsGetContainerID(Container *container, ContainerType type)
|
||||
UINT32 OsGetContainerID(LosProcessCB *processCB, ContainerType type)
|
||||
{
|
||||
Container *container = processCB->container;
|
||||
if (container == NULL) {
|
||||
return OS_INVALID_VALUE;
|
||||
}
|
||||
|
@ -258,6 +278,10 @@ UINT32 OsGetContainerID(Container *container, ContainerType type)
|
|||
case PID_CHILD_CONTAINER:
|
||||
return OsGetPidContainerID(container->pidForChildContainer);
|
||||
#endif
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
case USER_CONTAINER:
|
||||
return OsGetUserContainerID(processCB->credentials);
|
||||
#endif
|
||||
#ifdef LOSCFG_UTS_CONTAINER
|
||||
case UTS_CONTAINER:
|
||||
return OsGetUtsContainerID(container->utsContainer);
|
||||
|
@ -324,12 +348,22 @@ INT32 OsUnshare(UINT32 flags)
|
|||
UINT32 intSave;
|
||||
LosProcessCB *curr = OsCurrProcessGet();
|
||||
Container *oldContainer = curr->container;
|
||||
UINT32 unshareFlags = CLONE_NEWPID | CLONE_NEWTIME | CLONE_NEWUTS | CLONE_NEWNS | CLONE_NEWIPC;
|
||||
UINT32 unshareFlags = CLONE_NEWPID | CLONE_NEWTIME | CLONE_NEWUTS | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUSER;
|
||||
|
||||
if (!(flags & unshareFlags) || ((flags & (~unshareFlags)) != 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
ret = OsUnshareUserCredentials(flags, curr);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
if (flags == CLONE_NEWUSER) {
|
||||
return LOS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
Container *newContainer = CreateContainer();
|
||||
if (newContainer == NULL) {
|
||||
return -ENOMEM;
|
||||
|
@ -363,6 +397,8 @@ STATIC UINT32 SetNsGetFlagByContainerType(UINT32 containerType)
|
|||
case PID_CONTAINER:
|
||||
case PID_CHILD_CONTAINER:
|
||||
return CLONE_NEWPID;
|
||||
case USER_CONTAINER:
|
||||
return CLONE_NEWUSER;
|
||||
case UTS_CONTAINER:
|
||||
return CLONE_NEWUTS;
|
||||
case MNT_CONTAINER:
|
||||
|
@ -414,27 +450,65 @@ STATIC UINT32 SetNsCreateNewContainers(UINT32 flags, Container *newContainer, Co
|
|||
return LOS_OK;
|
||||
}
|
||||
|
||||
INT32 OsSetNs(INT32 fd, INT32 type)
|
||||
STATIC UINT32 SetNsParamCheck(INT32 fd, INT32 type, UINT32 *flag, LosProcessCB **target)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 typeMask = CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWTIME;
|
||||
UINT32 typeMask = CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWTIME | CLONE_NEWUSER;
|
||||
*flag = (UINT32)(type & typeMask);
|
||||
UINT32 containerType = 0;
|
||||
UINT32 flag = (UINT32)(type & typeMask);
|
||||
LosProcessCB *curr = OsCurrProcessGet();
|
||||
|
||||
if (((type & (~typeMask)) != 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
Container *newContainer = CreateContainer();
|
||||
if (newContainer == NULL) {
|
||||
return -ENOMEM;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
LosProcessCB *processCB = (LosProcessCB *)ProcfsContainerGet(fd, &containerType);
|
||||
if (processCB == NULL) {
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, newContainer);
|
||||
return -EBADF;
|
||||
return EBADF;
|
||||
}
|
||||
|
||||
if (*flag == 0) {
|
||||
*flag = SetNsGetFlagByContainerType(containerType);
|
||||
}
|
||||
|
||||
if ((*flag == 0) || (*flag != SetNsGetFlagByContainerType(containerType))) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (processCB == OsCurrProcessGet()) {
|
||||
return EINVAL;
|
||||
}
|
||||
*target = processCB;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
INT32 OsSetNs(INT32 fd, INT32 type)
|
||||
{
|
||||
UINT32 intSave, ret;
|
||||
UINT32 flag = 0;
|
||||
LosProcessCB *curr = OsCurrProcessGet();
|
||||
LosProcessCB *processCB = NULL;
|
||||
|
||||
ret = SetNsParamCheck(fd, type, &flag, &processCB);
|
||||
if (ret != LOS_OK) {
|
||||
return -ret;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
if (flag == CLONE_NEWUSER) {
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if ((processCB->credentials == NULL) || (processCB->credentials->userContainer == NULL)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return -EBADF;
|
||||
}
|
||||
UserContainer *userContainer = processCB->credentials->userContainer;
|
||||
ret = OsSetNsUserContainer(userContainer, curr);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
Container *newContainer = CreateContainer();
|
||||
if (newContainer == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
|
@ -444,16 +518,7 @@ INT32 OsSetNs(INT32 fd, INT32 type)
|
|||
return -EBADF;
|
||||
}
|
||||
|
||||
if (flag == 0) {
|
||||
flag = SetNsGetFlagByContainerType(containerType);
|
||||
}
|
||||
|
||||
if ((flag == 0) || (flag != SetNsGetFlagByContainerType(containerType)) || (targetContainer == curr->container)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
UINT32 ret = SetNsCreateNewContainers(flag, newContainer, targetContainer);
|
||||
ret = SetNsCreateNewContainers(flag, newContainer, targetContainer);
|
||||
if (ret != LOS_OK) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
goto EXIT;
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* 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 <errno.h>
|
||||
#include "los_credentials_pri.h"
|
||||
#include "los_user_container_pri.h"
|
||||
#include "los_config.h"
|
||||
#include "los_memory.h"
|
||||
#include "los_process_pri.h"
|
||||
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
STATIC Credentials *CreateNewCredential(LosProcessCB *parent)
|
||||
{
|
||||
UINT32 size = sizeof(Credentials);
|
||||
Credentials *newCredentials = LOS_MemAlloc(m_aucSysMem1, size);
|
||||
if (newCredentials == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (parent != NULL) {
|
||||
const Credentials *oldCredentials = parent->credentials;
|
||||
(VOID)memcpy_s(newCredentials, sizeof(Credentials), oldCredentials, sizeof(Credentials));
|
||||
LOS_AtomicSet(&newCredentials->rc, 1);
|
||||
} else {
|
||||
(VOID)memset_s(newCredentials, sizeof(Credentials), 0, sizeof(Credentials));
|
||||
LOS_AtomicSet(&newCredentials->rc, 3); /* 3: Three system processes */
|
||||
}
|
||||
newCredentials->userContainer = NULL;
|
||||
return newCredentials;
|
||||
}
|
||||
|
||||
Credentials *PrepareCredential(LosProcessCB *runProcessCB)
|
||||
{
|
||||
Credentials *newCredentials = CreateNewCredential(runProcessCB);
|
||||
if (newCredentials == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newCredentials->userContainer = runProcessCB->credentials->userContainer;
|
||||
LOS_AtomicInc(&newCredentials->userContainer->rc);
|
||||
return newCredentials;
|
||||
}
|
||||
|
||||
VOID FreeCredential(Credentials *credentials)
|
||||
{
|
||||
if (credentials == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (credentials->userContainer != NULL) {
|
||||
LOS_AtomicDec(&credentials->userContainer->rc);
|
||||
if (LOS_AtomicRead(&credentials->userContainer->rc) <= 0) {
|
||||
FreeUserContainer(credentials->userContainer);
|
||||
credentials->userContainer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LOS_AtomicDec(&credentials->rc);
|
||||
if (LOS_AtomicRead(&credentials->rc) <= 0) {
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, credentials);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsUserContainerDestroy(LosProcessCB *curr)
|
||||
{
|
||||
UINT32 intSave;
|
||||
SCHEDULER_LOCK(intSave);
|
||||
FreeCredential(curr->credentials);
|
||||
curr->credentials = NULL;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC Credentials *CreateCredentials(unsigned long flags, LosProcessCB *parent)
|
||||
{
|
||||
UINT32 ret;
|
||||
Credentials *newCredentials = CreateNewCredential(parent);
|
||||
if (newCredentials == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(flags & CLONE_NEWUSER)) {
|
||||
newCredentials->userContainer = parent->credentials->userContainer;
|
||||
LOS_AtomicInc(&newCredentials->userContainer->rc);
|
||||
return newCredentials;
|
||||
}
|
||||
|
||||
if (parent != NULL) {
|
||||
ret = OsCreateUserContainer(newCredentials, parent->credentials->userContainer);
|
||||
} else {
|
||||
ret = OsCreateUserContainer(newCredentials, NULL);
|
||||
}
|
||||
if (ret != LOS_OK) {
|
||||
FreeCredential(newCredentials);
|
||||
return NULL;
|
||||
}
|
||||
return newCredentials;
|
||||
}
|
||||
|
||||
UINT32 OsCopyCredentials(unsigned long flags, LosProcessCB *child, LosProcessCB *parent)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
child->credentials = CreateCredentials(flags, parent);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
if (child->credentials == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsInitRootUserCredentials(Credentials **credentials)
|
||||
{
|
||||
*credentials = CreateCredentials(CLONE_NEWUSER, NULL);
|
||||
if (*credentials == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsUnshareUserCredentials(UINTPTR flags, LosProcessCB *curr)
|
||||
{
|
||||
UINT32 intSave;
|
||||
if (!(flags & CLONE_NEWUSER)) {
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
UINT32 ret = OsCreateUserContainer(curr->credentials, curr->credentials->userContainer);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT32 OsSetNsUserContainer(struct UserContainer *targetContainer, LosProcessCB *runProcess)
|
||||
{
|
||||
Credentials *oldCredentials = runProcess->credentials;
|
||||
Credentials *newCredentials = CreateNewCredential(runProcess);
|
||||
if (newCredentials == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
runProcess->credentials = newCredentials;
|
||||
newCredentials->userContainer = targetContainer;
|
||||
LOS_AtomicInc(&targetContainer->rc);
|
||||
FreeCredential(oldCredentials);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsGetUserContainerID(Credentials *credentials)
|
||||
{
|
||||
if ((credentials == NULL) || (credentials->userContainer == NULL)) {
|
||||
return OS_INVALID_VALUE;
|
||||
}
|
||||
|
||||
return credentials->userContainer->containerID;
|
||||
}
|
||||
|
||||
INT32 CommitCredentials(Credentials *newCredentials)
|
||||
{
|
||||
Credentials *oldCredentials = OsCurrProcessGet()->credentials;
|
||||
|
||||
if (LOS_AtomicRead(&newCredentials->rc) < 1) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
OsCurrProcessGet()->credentials = newCredentials;
|
||||
FreeCredential(oldCredentials);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Credentials *CurrentCredentials(VOID)
|
||||
{
|
||||
return OsCurrProcessGet()->credentials;
|
||||
}
|
||||
|
||||
UserContainer *OsCurrentUserContainer(VOID)
|
||||
{
|
||||
UserContainer *userContainer = OsCurrProcessGet()->credentials->userContainer;
|
||||
return userContainer;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,426 @@
|
|||
/*
|
||||
* 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 "los_user_container_pri.h"
|
||||
#include "errno.h"
|
||||
#include "ctype.h"
|
||||
#include "los_config.h"
|
||||
#include "los_memory.h"
|
||||
#include "proc_fs.h"
|
||||
#include "user_copy.h"
|
||||
#include "los_seq_buf.h"
|
||||
#include "capability_type.h"
|
||||
#include "capability_api.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define DEFAULT_OVERFLOWUID 65534
|
||||
#define DEFAULT_OVERFLOWGID 65534
|
||||
#define LEVEL_MAX 3
|
||||
#define HEX 16
|
||||
#define OCT 8
|
||||
#define DEC 10
|
||||
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
UINT32 g_currentUserContainerNum = 1;
|
||||
|
||||
UINT32 OsCreateUserContainer(Credentials *newCredentials, UserContainer *parentUserContainer)
|
||||
{
|
||||
if ((parentUserContainer != NULL) && (parentUserContainer->level >= LEVEL_MAX)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if ((newCredentials->euid < 0) || (newCredentials->egid < 0)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
UserContainer *userContainer = LOS_MemAlloc(m_aucSysMem1, sizeof(UserContainer));
|
||||
if (userContainer == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
(VOID)memset_s(userContainer, sizeof(UserContainer), 0, sizeof(UserContainer));
|
||||
|
||||
g_currentUserContainerNum++;
|
||||
userContainer->containerID = OsAllocContainerID();
|
||||
userContainer->parent = parentUserContainer;
|
||||
newCredentials->userContainer = userContainer;
|
||||
if (parentUserContainer != NULL) {
|
||||
LOS_AtomicInc(&parentUserContainer->rc);
|
||||
LOS_AtomicSet(&userContainer->rc, 1);
|
||||
userContainer->level = parentUserContainer->level + 1;
|
||||
userContainer->owner = newCredentials->euid;
|
||||
userContainer->group = newCredentials->egid;
|
||||
} else {
|
||||
LOS_AtomicSet(&userContainer->rc, 3); /* 3: Three system processes */
|
||||
userContainer->uidMap.extentCount = 1;
|
||||
userContainer->uidMap.extent[0].count = 4294967295U;
|
||||
userContainer->gidMap.extentCount = 1;
|
||||
userContainer->gidMap.extent[0].count = 4294967295U;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
VOID FreeUserContainer(UserContainer *userContainer)
|
||||
{
|
||||
UserContainer *parent = NULL;
|
||||
do {
|
||||
parent = userContainer->parent;
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, userContainer);
|
||||
userContainer->parent = NULL;
|
||||
userContainer = parent;
|
||||
g_currentUserContainerNum--;
|
||||
} while ((userContainer != NULL) && (LOS_AtomicRead(&userContainer->rc) <= 0));
|
||||
}
|
||||
|
||||
STATIC UidGidExtent *MapIdUpBase(UINT32 extents, UidGidMap *map, UINT32 id)
|
||||
{
|
||||
UINT32 idx;
|
||||
UINT32 first;
|
||||
UINT32 last;
|
||||
|
||||
for (idx = 0; idx < extents; idx++) {
|
||||
first = map->extent[idx].lowerFirst;
|
||||
last = first + map->extent[idx].count - 1;
|
||||
if ((id >= first) && (id <= last)) {
|
||||
return &map->extent[idx];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC UINT32 MapIdUp(UidGidMap *map, UINT32 id)
|
||||
{
|
||||
UINT32 extents = map->extentCount;
|
||||
if (extents > UID_GID_MAP_MAX_EXTENTS) {
|
||||
return (UINT32)-1;
|
||||
}
|
||||
|
||||
UidGidExtent *extent = MapIdUpBase(extents, map, id);
|
||||
if (extent != NULL) {
|
||||
return ((id - extent->lowerFirst) + extent->first);
|
||||
}
|
||||
|
||||
return (UINT32)-1;
|
||||
}
|
||||
|
||||
UINT32 FromKuid(UserContainer *userContainer, UINT32 kuid)
|
||||
{
|
||||
return MapIdUp(&userContainer->uidMap, kuid);
|
||||
}
|
||||
|
||||
UINT32 FromKgid(UserContainer *userContainer, UINT32 kgid)
|
||||
{
|
||||
return MapIdUp(&userContainer->gidMap, kgid);
|
||||
}
|
||||
|
||||
UINT32 OsFromKuidMunged(UserContainer *userContainer, UINT32 kuid)
|
||||
{
|
||||
UINT32 uid = FromKuid(userContainer, kuid);
|
||||
if (uid == (UINT32)-1) {
|
||||
uid = DEFAULT_OVERFLOWUID;
|
||||
}
|
||||
return uid;
|
||||
}
|
||||
|
||||
UINT32 OsFromKgidMunged(UserContainer *userContainer, UINT32 kgid)
|
||||
{
|
||||
UINT32 gid = FromKgid(userContainer, kgid);
|
||||
if (gid == (UINT32)-1) {
|
||||
gid = DEFAULT_OVERFLOWGID;
|
||||
}
|
||||
return gid;
|
||||
}
|
||||
|
||||
STATIC UidGidExtent *MapIdRangeDownBase(UINT32 extents, UidGidMap *map, UINT32 id, UINT32 count)
|
||||
{
|
||||
UINT32 idx;
|
||||
UINT32 first;
|
||||
UINT32 last;
|
||||
UINT32 id2;
|
||||
|
||||
id2 = id + count - 1;
|
||||
for (idx = 0; idx < extents; idx++) {
|
||||
first = map->extent[idx].first;
|
||||
last = first + map->extent[idx].count - 1;
|
||||
if ((id >= first && id <= last) && (id2 >= first && id2 <= last)) {
|
||||
return &map->extent[idx];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC UINT32 MapIdRangeDown(UidGidMap *map, UINT32 id, UINT32 count)
|
||||
{
|
||||
UINT32 extents = map->extentCount;
|
||||
if (extents > UID_GID_MAP_MAX_EXTENTS) {
|
||||
return (UINT32)-1;
|
||||
}
|
||||
|
||||
UidGidExtent *extent = MapIdRangeDownBase(extents, map, id, count);
|
||||
if (extent != NULL) {
|
||||
return ((id - extent->first) + extent->lowerFirst);
|
||||
}
|
||||
|
||||
return (UINT32)-1;
|
||||
}
|
||||
|
||||
STATIC UINT32 MapIdDown(UidGidMap *map, UINT32 id)
|
||||
{
|
||||
return MapIdRangeDown(map, id, 1);
|
||||
}
|
||||
|
||||
UINT32 OsMakeKuid(UserContainer *userContainer, UINT32 uid)
|
||||
{
|
||||
return MapIdDown(&userContainer->uidMap, uid);
|
||||
}
|
||||
|
||||
UINT32 OsMakeKgid(UserContainer *userContainer, UINT32 gid)
|
||||
{
|
||||
return MapIdDown(&userContainer->gidMap, gid);
|
||||
}
|
||||
|
||||
STATIC INT32 InsertExtent(UidGidMap *idMap, UidGidExtent *extent)
|
||||
{
|
||||
if (idMap->extentCount > UID_GID_MAP_MAX_EXTENTS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
UidGidExtent *dest = &idMap->extent[idMap->extentCount];
|
||||
*dest = *extent;
|
||||
idMap->extentCount++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC BOOL MappingsOverlap(UidGidMap *idMap, UidGidExtent *extent)
|
||||
{
|
||||
UINT32 upperFirst = extent->first;
|
||||
UINT32 lowerFirst = extent->lowerFirst;
|
||||
UINT32 upperLast = upperFirst + extent->count - 1;
|
||||
UINT32 lowerLast = lowerFirst + extent->count - 1;
|
||||
INT32 idx;
|
||||
|
||||
for (idx = 0; idx < idMap->extentCount; idx++) {
|
||||
if (idMap->extentCount > UID_GID_MAP_MAX_EXTENTS) {
|
||||
return TRUE;
|
||||
}
|
||||
UidGidExtent *prev = &idMap->extent[idx];
|
||||
UINT32 prevUpperFirst = prev->first;
|
||||
UINT32 prevLowerFirst = prev->lowerFirst;
|
||||
UINT32 prevUpperLast = prevUpperFirst + prev->count - 1;
|
||||
UINT32 prevLowerLast = prevLowerFirst + prev->count - 1;
|
||||
|
||||
if ((prevUpperFirst <= upperLast) && (prevUpperLast >= upperFirst)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((prevLowerFirst <= lowerLast) && (prevLowerLast >= lowerFirst)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
STATIC CHAR *SkipSpaces(const CHAR *str)
|
||||
{
|
||||
while (isspace(*str)) {
|
||||
++str;
|
||||
}
|
||||
|
||||
return (CHAR *)str;
|
||||
}
|
||||
|
||||
STATIC UINTPTR StrToUInt(const CHAR *str, CHAR **endp, UINT32 base)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
unsigned long value;
|
||||
|
||||
if (*str == '0') {
|
||||
str++;
|
||||
if ((*str == 'x') && isxdigit(str[1])) {
|
||||
base = HEX;
|
||||
str++;
|
||||
}
|
||||
if (!base) {
|
||||
base = OCT;
|
||||
}
|
||||
}
|
||||
if (!base) {
|
||||
base = DEC;
|
||||
}
|
||||
while (isxdigit(*str) && (value = isdigit(*str) ? *str - '0' : (islower(*str) ?
|
||||
toupper(*str) : *str) - 'A' + DEC) < base) {
|
||||
result = result * base + value;
|
||||
str++;
|
||||
}
|
||||
if (endp != NULL) {
|
||||
*endp = (CHAR *)str;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
STATIC INT32 ParsePosData(CHAR *pos, UidGidExtent *extent)
|
||||
{
|
||||
INT32 ret = -EINVAL;
|
||||
pos = SkipSpaces(pos);
|
||||
extent->first = StrToUInt(pos, &pos, DEC);
|
||||
if (!isspace(*pos)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pos = SkipSpaces(pos);
|
||||
extent->lowerFirst = StrToUInt(pos, &pos, DEC);
|
||||
if (!isspace(*pos)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pos = SkipSpaces(pos);
|
||||
extent->count = StrToUInt(pos, &pos, DEC);
|
||||
if (*pos && !isspace(*pos)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pos = SkipSpaces(pos);
|
||||
if (*pos != '\0') {
|
||||
return ret;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 ParseUserData(CHAR *kbuf, UidGidExtent *extent, UidGidMap *newMap)
|
||||
{
|
||||
INT32 ret = -EINVAL;
|
||||
CHAR *pos = NULL;
|
||||
CHAR *nextLine = NULL;
|
||||
|
||||
for (pos = kbuf; pos != NULL; pos = nextLine) {
|
||||
nextLine = strchr(pos, '\n');
|
||||
if (nextLine != NULL) {
|
||||
*nextLine = '\0';
|
||||
nextLine++;
|
||||
if (*nextLine == '\0') {
|
||||
nextLine = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ParsePosData(pos, extent) != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((extent->first == (UINT32)-1) || (extent->lowerFirst == (UINT32)-1)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((extent->first + extent->count) <= extent->first) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((extent->lowerFirst + extent->count) <= extent->lowerFirst) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (MappingsOverlap(newMap, extent)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((newMap->extentCount + 1) == UID_GID_MAP_MAX_EXTENTS && (nextLine != NULL)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = InsertExtent(newMap, extent);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (newMap->extentCount == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC INT32 ParentMapIdRange(UidGidMap *newMap, UidGidMap *parentMap)
|
||||
{
|
||||
UINT32 idx;
|
||||
INT32 ret = -EPERM;
|
||||
for (idx = 0; idx < newMap->extentCount; idx++) {
|
||||
if (newMap->extentCount > UID_GID_MAP_MAX_EXTENTS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
UidGidExtent *extent = &newMap->extent[idx];
|
||||
UINT32 lowerFirst = MapIdRangeDown(parentMap, extent->lowerFirst, extent->count);
|
||||
if (lowerFirst == (UINT32) -1) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
extent->lowerFirst = lowerFirst;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT32 OsUserContainerMapWrite(struct ProcFile *fp, CHAR *kbuf, size_t count,
|
||||
INT32 capSetid, UidGidMap *map, UidGidMap *parentMap)
|
||||
{
|
||||
UidGidMap newMap = {0};
|
||||
UidGidExtent extent;
|
||||
INT32 ret;
|
||||
|
||||
if (map->extentCount != 0) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (!IsCapPermit(capSetid)) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
ret = ParseUserData(kbuf, &extent, &newMap);
|
||||
if (ret < 0) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
ret = ParentMapIdRange(&newMap, parentMap);
|
||||
if (ret < 0) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (newMap.extentCount <= UID_GID_MAP_MAX_EXTENTS) {
|
||||
size_t mapSize = newMap.extentCount * sizeof(newMap.extent[0]);
|
||||
ret = memcpy_s(map->extent, sizeof(map->extent), newMap.extent, mapSize);
|
||||
if (ret != EOK) {
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
|
||||
map->extentCount = newMap.extentCount;
|
||||
return count;
|
||||
}
|
||||
#endif
|
|
@ -822,7 +822,11 @@ LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID)
|
|||
INT32 uid;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
uid = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->uid);
|
||||
#else
|
||||
uid = (INT32)OsCurrUserGet()->userID;
|
||||
#endif
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return uid;
|
||||
#else
|
||||
|
@ -837,7 +841,11 @@ LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID)
|
|||
INT32 gid;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
gid = OsFromKgidMunged(OsCurrentUserContainer(), CurrentCredentials()->gid);
|
||||
#else
|
||||
gid = (INT32)OsCurrUserGet()->gid;
|
||||
#endif
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
return gid;
|
||||
|
@ -2123,6 +2131,9 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size)
|
|||
#ifdef LOSCFG_TIME_CONTAINER
|
||||
cloneFlag |= CLONE_NEWTIME;
|
||||
#endif
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
cloneFlag |= CLONE_NEWUSER;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (flags & (~cloneFlag)) {
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
#ifdef LOSCFG_IPC_CONTAINER
|
||||
#include "los_ipc_container_pri.h"
|
||||
#endif
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
#include "los_user_container_pri.h"
|
||||
#endif
|
||||
#ifdef LOSCFG_TIME_CONTAINER
|
||||
#include "los_time_container_pri.h"
|
||||
#endif
|
||||
|
@ -56,6 +59,7 @@ typedef enum {
|
|||
UTS_CONTAINER,
|
||||
MNT_CONTAINER,
|
||||
IPC_CONTAINER,
|
||||
USER_CONTAINER,
|
||||
TIME_CONTAINER,
|
||||
TIME_CHILD_CONTAINER,
|
||||
CONTAINER_MAX,
|
||||
|
@ -94,7 +98,7 @@ VOID OsContainerFree(LosProcessCB *processCB);
|
|||
|
||||
UINT32 OsAllocContainerID(VOID);
|
||||
|
||||
UINT32 OsGetContainerID(Container *container, ContainerType type);
|
||||
UINT32 OsGetContainerID(LosProcessCB *processCB, ContainerType type);
|
||||
|
||||
INT32 OsUnshare(UINT32 flags);
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2022 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_CREDENTIALS_PRI_H
|
||||
#define _LOS_CREDENTIALS_PRI_H
|
||||
|
||||
#include "los_atomic.h"
|
||||
#include "los_list.h"
|
||||
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
struct Container;
|
||||
struct UserContainer;
|
||||
typedef struct ProcessCB LosProcessCB;
|
||||
|
||||
typedef struct Credentials {
|
||||
Atomic rc;
|
||||
UINT32 uid;
|
||||
UINT32 gid;
|
||||
UINT32 euid;
|
||||
UINT32 egid;
|
||||
struct UserContainer *userContainer;
|
||||
} Credentials;
|
||||
|
||||
UINT32 OsCopyCredentials(unsigned long flags, LosProcessCB *child, LosProcessCB *parent);
|
||||
|
||||
UINT32 OsInitRootUserCredentials(Credentials **credentials);
|
||||
|
||||
UINT32 OsUnshareUserCredentials(UINTPTR flags, LosProcessCB *curr);
|
||||
|
||||
UINT32 OsSetNsUserContainer(struct UserContainer *targetContainer, LosProcessCB *runProcess);
|
||||
|
||||
VOID FreeCredential(Credentials *credentials);
|
||||
|
||||
VOID OsUserContainerDestroy(LosProcessCB *curr);
|
||||
|
||||
UINT32 OsGetUserContainerID(Credentials *credentials);
|
||||
|
||||
Credentials *PrepareCredential(LosProcessCB *runProcessCB);
|
||||
|
||||
INT32 CommitCredentials(Credentials *newCredentials);
|
||||
|
||||
Credentials *CurrentCredentials(VOID);
|
||||
|
||||
struct UserContainer *OsCurrentUserContainer(VOID);
|
||||
#endif
|
||||
#endif /* _LOS_CREDENTIALS_PRI_H */
|
|
@ -132,6 +132,9 @@ typedef struct ProcessCB {
|
|||
struct rlimit *resourceLimit;
|
||||
#ifdef LOSCFG_KERNEL_CONTAINER
|
||||
Container *container;
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
struct Credentials *credentials;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef LOSCFG_PROC_PROCESS_DIR
|
||||
struct ProcDirEntry *procDir;
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2022 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_USER_CONTAINER_PRI_H
|
||||
#define _LOS_USER_CONTAINER_PRI_H
|
||||
|
||||
#include "los_atomic.h"
|
||||
#include "los_credentials_pri.h"
|
||||
|
||||
#define UID_GID_MAP_MAX_EXTENTS 5
|
||||
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
struct ProcFile;
|
||||
|
||||
typedef struct UidGidExtent {
|
||||
UINT32 first;
|
||||
UINT32 lowerFirst;
|
||||
UINT32 count;
|
||||
} UidGidExtent;
|
||||
|
||||
typedef struct UidGidMap {
|
||||
UINT32 extentCount;
|
||||
union {
|
||||
UidGidExtent extent[UID_GID_MAP_MAX_EXTENTS];
|
||||
};
|
||||
} UidGidMap;
|
||||
|
||||
typedef struct UserContainer {
|
||||
Atomic rc;
|
||||
INT32 level;
|
||||
UINT32 owner;
|
||||
UINT32 group;
|
||||
struct UserContainer *parent;
|
||||
UidGidMap uidMap;
|
||||
UidGidMap gidMap;
|
||||
UINT32 containerID;
|
||||
} UserContainer;
|
||||
|
||||
UINT32 OsCreateUserContainer(Credentials *newCredentials, UserContainer *parentUserContainer);
|
||||
|
||||
VOID FreeUserContainer(UserContainer *userContainer);
|
||||
|
||||
UINT32 OsFromKuidMunged(UserContainer *userContainer, UINT32 kuid);
|
||||
|
||||
UINT32 OsFromKgidMunged(UserContainer *userContainer, UINT32 kgid);
|
||||
|
||||
UINT32 OsMakeKuid(UserContainer *userContainer, UINT32 uid);
|
||||
|
||||
UINT32 OsMakeKgid(UserContainer *userContainer, UINT32 gid);
|
||||
|
||||
INT32 OsUserContainerMapWrite(struct ProcFile *fp, CHAR *buf, size_t count,
|
||||
INT32 capSetid, UidGidMap *map, UidGidMap *parentMap);
|
||||
#endif
|
||||
#endif
|
|
@ -448,7 +448,11 @@ int SysGetEffUserID(void)
|
|||
int euid;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
euid = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid);
|
||||
#else
|
||||
euid = (int)OsCurrUserGet()->effUserID;
|
||||
#endif
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return euid;
|
||||
#else
|
||||
|
@ -463,7 +467,11 @@ int SysGetEffGID(void)
|
|||
int egid;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
egid = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid);
|
||||
#else
|
||||
egid = (int)OsCurrUserGet()->effGid;
|
||||
#endif
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return egid;
|
||||
#else
|
||||
|
@ -479,9 +487,15 @@ int SysGetRealEffSaveUserID(int *ruid, int *euid, int *suid)
|
|||
unsigned int intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
realUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->uid);
|
||||
effUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid);
|
||||
saveUserID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->euid);
|
||||
#else
|
||||
realUserID = OsCurrUserGet()->userID;
|
||||
effUserID = OsCurrUserGet()->effUserID;
|
||||
saveUserID = OsCurrUserGet()->effUserID;
|
||||
#endif
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
#else
|
||||
realUserID = 0;
|
||||
|
@ -507,6 +521,58 @@ int SysGetRealEffSaveUserID(int *ruid, int *euid, int *suid)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
long SysSetUserID(int uid)
|
||||
{
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
UserContainer *userContainer = CurrentCredentials()->userContainer;
|
||||
int retval = -EPERM;
|
||||
unsigned int intSave;
|
||||
|
||||
UINT32 kuid = OsMakeKuid(userContainer, uid);
|
||||
if (kuid == (UINT32)-1) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
Credentials *newCredentials = PrepareCredential(OsCurrProcessGet());
|
||||
if (newCredentials == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
Credentials *oldCredentials = CurrentCredentials();
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
User *user = OsCurrUserGet();
|
||||
if (IsCapPermit(CAP_SETUID)) {
|
||||
newCredentials->uid = kuid;
|
||||
if (kuid != oldCredentials->uid) {
|
||||
user->userID = kuid;
|
||||
user->effUserID = kuid;
|
||||
}
|
||||
retval = LOS_OK;
|
||||
} else if (kuid != oldCredentials->uid) {
|
||||
goto ERROR;
|
||||
}
|
||||
newCredentials->euid = kuid;
|
||||
|
||||
retval = CommitCredentials(newCredentials);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return retval;
|
||||
|
||||
ERROR:
|
||||
FreeCredential(newCredentials);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return retval;
|
||||
#else
|
||||
if (uid != 0) {
|
||||
return -EPERM;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int SysSetUserID(int uid)
|
||||
{
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
|
@ -540,6 +606,7 @@ EXIT:
|
|||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
static int SetRealEffSaveUserIDCheck(int ruid, int euid, int suid)
|
||||
|
@ -607,6 +674,62 @@ int SysSetRealEffUserID(int ruid, int euid)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
int SysSetGroupID(int gid)
|
||||
{
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
UserContainer *userContainer = CurrentCredentials()->userContainer;
|
||||
int retval = -EPERM;
|
||||
unsigned int oldGid;
|
||||
unsigned int intSave;
|
||||
int count;
|
||||
|
||||
unsigned int kgid = OsMakeKgid(userContainer, gid);
|
||||
if (kgid == (UINT32)-1) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
Credentials *newCredentials = PrepareCredential(OsCurrProcessGet());
|
||||
if (newCredentials == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
User *user = OsCurrUserGet();
|
||||
if (IsCapPermit(CAP_SETGID)) {
|
||||
newCredentials->gid = kgid;
|
||||
newCredentials->egid = kgid;
|
||||
oldGid = user->gid;
|
||||
user->gid = kgid;
|
||||
user->effGid = kgid;
|
||||
for (count = 0; count < user->groupNumber; count++) {
|
||||
if (user->groups[count] == oldGid) {
|
||||
user->groups[count] = kgid;
|
||||
retval = LOS_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (user->gid != kgid) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
retval = CommitCredentials(newCredentials);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return retval;
|
||||
|
||||
ERROR:
|
||||
FreeCredential(newCredentials);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return retval;
|
||||
|
||||
#else
|
||||
if (gid != 0) {
|
||||
return -EPERM;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
int SysSetGroupID(int gid)
|
||||
{
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
|
@ -651,6 +774,7 @@ EXIT:
|
|||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int SysGetRealEffSaveGroupID(int *rgid, int *egid, int *sgid)
|
||||
{
|
||||
|
@ -660,9 +784,15 @@ int SysGetRealEffSaveGroupID(int *rgid, int *egid, int *sgid)
|
|||
unsigned int intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
realGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->gid);
|
||||
effGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid);
|
||||
saveGroupID = OsFromKuidMunged(OsCurrentUserContainer(), CurrentCredentials()->egid);
|
||||
#else
|
||||
realGroupID = OsCurrUserGet()->gid;
|
||||
effGroupID = OsCurrUserGet()->effGid;
|
||||
saveGroupID = OsCurrUserGet()->effGid;
|
||||
#endif
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
#else
|
||||
realGroupID = 0;
|
||||
|
|
|
@ -142,6 +142,7 @@ LOSCFG_USER_TEST_UTS_CONTAINER = false
|
|||
LOSCFG_USER_TEST_MNT_CONTAINER = false
|
||||
LOSCFG_USER_TEST_IPC_CONTAINER = false
|
||||
LOSCFG_USER_TEST_TIME_CONTAINER = false
|
||||
LOSCFG_USER_TEST_USER_CONTAINER = false
|
||||
if (defined(LOSCFG_KERNEL_CONTAINER) || liteos_container_test_enable == true) {
|
||||
LOSCFG_USER_TEST_CONTAINER = true
|
||||
if (defined(LOSCFG_PID_CONTAINER) || liteos_container_test_enable == true) {
|
||||
|
@ -159,6 +160,9 @@ if (defined(LOSCFG_KERNEL_CONTAINER) || liteos_container_test_enable == true) {
|
|||
if (defined(LOSCFG_TIME_CONTAINER) || liteos_container_test_enable == true) {
|
||||
LOSCFG_USER_TEST_TIME_CONTAINER = true
|
||||
}
|
||||
if (defined(LOSCFG_USER_CONTAINER) || liteos_container_test_enable == true) {
|
||||
LOSCFG_USER_TEST_USER_CONTAINER = true
|
||||
}
|
||||
}
|
||||
|
||||
########## fuzz test ##########
|
||||
|
|
|
@ -47,6 +47,9 @@ config("container_config") {
|
|||
if (defined(LOSCFG_USER_TEST_TIME_CONTAINER)) {
|
||||
cflags += [ "-DLOSCFG_USER_TEST_TIME_CONTAINER" ]
|
||||
}
|
||||
if (defined(LOSCFG_USER_TEST_USER_CONTAINER)) {
|
||||
cflags += [ "-DLOSCFG_USER_TEST_USER_CONTAINER" ]
|
||||
}
|
||||
cflags_cc = cflags
|
||||
}
|
||||
|
||||
|
|
|
@ -589,6 +589,55 @@ HWTEST_F(ContainerTest, ItTimeContainer010, TestSize.Level0)
|
|||
ItTimeContainer010();
|
||||
}
|
||||
#endif
|
||||
#if defined(LOSCFG_USER_TEST_USER_CONTAINER)
|
||||
/**
|
||||
* @tc.name: Container_UTS_Test_001
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6EC0A
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItUserContainer001, TestSize.Level0)
|
||||
{
|
||||
ItUserContainer001();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_UTS_Test_002
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6EC0A
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItUserContainer002, TestSize.Level0)
|
||||
{
|
||||
ItUserContainer002();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_UTS_Test_003
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6EC0A
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItUserContainer003, TestSize.Level0)
|
||||
{
|
||||
ItUserContainer003();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_UTS_Test_004
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6EC0A
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItUserContainer004, TestSize.Level0)
|
||||
{
|
||||
ItUserContainer004();
|
||||
}
|
||||
#endif
|
||||
#endif /* LOSCFG_USER_TEST_SMOKE */
|
||||
|
||||
#if defined(LOSCFG_USER_TEST_FULL)
|
||||
|
@ -884,6 +933,19 @@ HWTEST_F(ContainerTest, ItUtsContainer003, TestSize.Level0)
|
|||
ItUtsContainer003();
|
||||
}
|
||||
#endif
|
||||
#if defined(LOSCFG_USER_TEST_USER_CONTAINER)
|
||||
/**
|
||||
* @tc.name: Container_UTS_Test_005
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6EC0A
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItUserContainer005, TestSize.Level0)
|
||||
{
|
||||
ItUserContainer005();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
} // namespace OHOS
|
||||
|
||||
|
|
|
@ -137,6 +137,11 @@ private:
|
|||
int m_shmid;
|
||||
};
|
||||
|
||||
void ItUserContainer001(void);
|
||||
void ItUserContainer002(void);
|
||||
void ItUserContainer003(void);
|
||||
void ItUserContainer004(void);
|
||||
void ItUserContainer005(void);
|
||||
#if defined(LOSCFG_USER_TEST_SMOKE)
|
||||
void ItContainer001(void);
|
||||
void ItContainerChroot001(void);
|
||||
|
|
|
@ -128,3 +128,14 @@ if (defined(LOSCFG_USER_TEST_TIME_CONTAINER)) {
|
|||
"$TEST_UNITTEST_DIR/container/smoke/It_time_container_010.cpp",
|
||||
]
|
||||
}
|
||||
|
||||
if (defined(LOSCFG_USER_TEST_USER_CONTAINER)) {
|
||||
sources_smoke += [
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_user_container_001.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_user_container_002.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_user_container_003.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_user_container_004.cpp",
|
||||
]
|
||||
sources_full +=
|
||||
[ "$TEST_UNITTEST_DIR/container/full/It_user_container_005.cpp" ]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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/resource.h"
|
||||
#include "sys/wait.h"
|
||||
#include "pthread.h"
|
||||
#include "sched.h"
|
||||
|
||||
const int EXIT_TRUE_CODE = 255;
|
||||
const int MAX_PID_RANGE = 100000;
|
||||
const int SLEEP_TIME_US = 1000;
|
||||
const int LOOP_NUM = 1000;
|
||||
|
||||
static int childFunc(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
usleep(SLEEP_TIME_US);
|
||||
exit(EXIT_TRUE_CODE);
|
||||
}
|
||||
|
||||
static int GroupProcess(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
int ret;
|
||||
int status = 0;
|
||||
|
||||
for (int i = 0; i < LOOP_NUM; i++) {
|
||||
int arg_child = CHILD_FUNC_ARG;
|
||||
auto pid = CloneWrapper(childFunc, CLONE_NEWUSER, &arg_child);
|
||||
if (pid == -1) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
if (ret != pid) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
status = WEXITSTATUS(status);
|
||||
if (status != EXIT_TRUE_CODE) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
}
|
||||
|
||||
exit(EXIT_TRUE_CODE);
|
||||
}
|
||||
|
||||
void ItUserContainer005(void)
|
||||
{
|
||||
int ret;
|
||||
int status = 0;
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto pid = CloneWrapper(GroupProcess, CLONE_NEWUSER, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
status = WEXITSTATUS(status);
|
||||
ASSERT_EQ(status, EXIT_TRUE_CODE);
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
const int RETURN_CODE = 2;
|
||||
|
||||
static int childFunc(void *arg)
|
||||
{
|
||||
int value = *((int*)arg);
|
||||
if (value != CHILD_FUNC_ARG) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
return RETURN_CODE;
|
||||
}
|
||||
|
||||
void ItUserContainer001(void)
|
||||
{
|
||||
int ret;
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto pid = CloneWrapper(childFunc, CLONE_NEWUSER, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
int status;
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
ret = WIFEXITED(status);
|
||||
ASSERT_NE(ret, 0);
|
||||
|
||||
int exitCode = WEXITSTATUS(status);
|
||||
ASSERT_EQ(exitCode, RETURN_CODE);
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
const int EXIT_TRUE_CODE = 255;
|
||||
const int TEST_SET_OLD_ID = 1001;
|
||||
const int TEST_SET_NEW_ID = 4;
|
||||
static const int SLEEP_TIME = 3;
|
||||
|
||||
std::string GetIdMapPath(int pid, const std::string& mapType)
|
||||
{
|
||||
std::ostringstream buf;
|
||||
buf << "/proc/" << pid << "/" << mapType;
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
int WriteIdMap(int pid)
|
||||
{
|
||||
std::string uidMapPath = GetIdMapPath(pid, "uid_map");
|
||||
std::string gidMapPath = GetIdMapPath(pid, "gid_map");
|
||||
|
||||
const char* idMapStr = "0 1000 1\n1 1001 1\n2 1002 1\n3 1003 1\n4 1004 1\n";
|
||||
int strLen = strlen(idMapStr);
|
||||
int uidMap = open(uidMapPath.c_str(), O_WRONLY);
|
||||
if (uidMap == -1) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
int ret = write(uidMap, idMapStr, strLen);
|
||||
if (ret != strLen) {
|
||||
close(uidMap);
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
close(uidMap);
|
||||
|
||||
int gidMap = open(gidMapPath.c_str(), O_WRONLY);
|
||||
if (gidMap == -1) {
|
||||
close(gidMap);
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
ret = write(gidMap, idMapStr, strLen);
|
||||
if (ret != strLen) {
|
||||
close(gidMap);
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
close(gidMap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int childFunc(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
sleep(SLEEP_TIME);
|
||||
|
||||
int newUid = getuid();
|
||||
if (newUid != 1) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
int newGid = getgid();
|
||||
if (newGid != 1) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
int ret = setuid(TEST_SET_NEW_ID);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
ret = setgid(TEST_SET_NEW_ID);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
newUid = getuid();
|
||||
if (newUid != TEST_SET_NEW_ID) {
|
||||
return EXIT_CODE_ERRNO_5;
|
||||
}
|
||||
|
||||
newGid = getgid();
|
||||
if (newGid != TEST_SET_NEW_ID) {
|
||||
return EXIT_CODE_ERRNO_6;
|
||||
}
|
||||
|
||||
exit(EXIT_TRUE_CODE);
|
||||
}
|
||||
|
||||
void ItUserContainer002(void)
|
||||
{
|
||||
int ret = setuid(TEST_SET_OLD_ID);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
int oldUid = getuid();
|
||||
ASSERT_EQ(oldUid, TEST_SET_OLD_ID);
|
||||
|
||||
ret = setgid(TEST_SET_OLD_ID);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
int oldGid = getgid();
|
||||
ASSERT_EQ(oldGid, TEST_SET_OLD_ID);
|
||||
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto pid = CloneWrapper(childFunc, CLONE_NEWUSER, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
ret = WriteIdMap(pid);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
int status;
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
status = WEXITSTATUS(status);
|
||||
ASSERT_EQ(status, EXIT_TRUE_CODE);
|
||||
|
||||
int oldUid1 = getuid();
|
||||
ASSERT_EQ(oldUid1, TEST_SET_OLD_ID);
|
||||
|
||||
int oldGid1 = getgid();
|
||||
ASSERT_EQ(oldGid1, TEST_SET_OLD_ID);
|
||||
|
||||
ASSERT_EQ(oldUid, oldUid1);
|
||||
ASSERT_EQ(oldGid, oldGid1);
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
const int EXIT_TRUE_CODE = 255;
|
||||
const int MAX_PID_RANGE = 100000;
|
||||
const int TEST_SET_OLD_ID = 1001;
|
||||
const int TEST_SET_NEW_ID = 4;
|
||||
|
||||
std::string GetIdMapPath(int pid, const std::string& mapType);
|
||||
int WriteIdMap(int pid);
|
||||
|
||||
static int TestMap(int oldUid, int oldGid)
|
||||
{
|
||||
pid_t pid = getpid();
|
||||
int ret = WriteIdMap(pid);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_6;
|
||||
}
|
||||
|
||||
int newUid = getuid();
|
||||
if (newUid != 1) {
|
||||
return EXIT_CODE_ERRNO_7;
|
||||
}
|
||||
|
||||
int newGid = getgid();
|
||||
if (newGid != 1) {
|
||||
return EXIT_CODE_ERRNO_8;
|
||||
}
|
||||
|
||||
ret = setuid(TEST_SET_NEW_ID);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_9;
|
||||
}
|
||||
|
||||
ret = setgid(TEST_SET_NEW_ID);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_10;
|
||||
}
|
||||
|
||||
newUid = getuid();
|
||||
if (newUid != TEST_SET_NEW_ID) {
|
||||
return EXIT_CODE_ERRNO_11;
|
||||
}
|
||||
|
||||
newGid = getgid();
|
||||
if (newGid != TEST_SET_NEW_ID) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (oldUid == newUid) {
|
||||
return EXIT_CODE_ERRNO_12;
|
||||
}
|
||||
|
||||
if (oldGid == newGid) {
|
||||
return EXIT_CODE_ERRNO_13;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int childFunc(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
int ret;
|
||||
int oldUid;
|
||||
int oldGid;
|
||||
|
||||
ret = setuid(TEST_SET_OLD_ID);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
oldUid = getuid();
|
||||
if (oldUid != TEST_SET_OLD_ID) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
ret = setgid(TEST_SET_OLD_ID);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
oldGid = getgid();
|
||||
if (oldGid != TEST_SET_OLD_ID) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
ret = unshare(CLONE_NEWUSER);
|
||||
if (ret == -1) {
|
||||
return EXIT_CODE_ERRNO_5;
|
||||
}
|
||||
|
||||
ret = TestMap(oldUid, oldGid);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
exit(EXIT_TRUE_CODE);
|
||||
}
|
||||
|
||||
void ItUserContainer003(void)
|
||||
{
|
||||
int ret;
|
||||
int status = 0;
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto pid = CloneWrapper(childFunc, SIGCHLD, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
status = WEXITSTATUS(status);
|
||||
ASSERT_EQ(status, EXIT_TRUE_CODE);
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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 <sched.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "It_container_test.h"
|
||||
|
||||
const int EXIT_TRUE_CODE = 255;
|
||||
const int MAX_PID_RANGE = 100000;
|
||||
|
||||
static int childFunc(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
std::string containerType = "user";
|
||||
std::string childlink;
|
||||
std::string filePath;
|
||||
std::string parentlink1;
|
||||
int fd;
|
||||
int ret;
|
||||
int status;
|
||||
int parentPid = getpid();
|
||||
|
||||
auto parentlink = ReadlinkContainer(parentPid, containerType);
|
||||
int childsPid = CloneWrapper(ChildFunction, CLONE_NEWUSER, NULL);
|
||||
if (childsPid == -1) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
childlink = ReadlinkContainer(childsPid, containerType);
|
||||
filePath = GenContainerLinkPath(childsPid, containerType);
|
||||
fd = open(filePath.c_str(), O_RDONLY);
|
||||
if (fd == -1) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
ret = setns(fd, CLONE_NEWUSER);
|
||||
if (ret == -1) {
|
||||
close(fd);
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
parentlink1 = ReadlinkContainer(parentPid, containerType);
|
||||
|
||||
close(fd);
|
||||
|
||||
ret = waitpid(childsPid, &status, 0);
|
||||
if (ret != childsPid) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
ret = parentlink.compare(parentlink1);
|
||||
if (ret == 0) {
|
||||
return EXIT_CODE_ERRNO_5;
|
||||
}
|
||||
|
||||
ret = parentlink1.compare(childlink);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_6;
|
||||
}
|
||||
|
||||
exit(EXIT_TRUE_CODE);
|
||||
}
|
||||
|
||||
void ItUserContainer004(void)
|
||||
{
|
||||
|
||||
int ret;
|
||||
int status = 0;
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto pid = CloneWrapper(childFunc, SIGCHLD, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
status = WEXITSTATUS(status);
|
||||
ASSERT_EQ(status, EXIT_TRUE_CODE);
|
||||
}
|
Loading…
Reference in New Issue