diff --git a/syscall/fs_syscall.c b/syscall/fs_syscall.c index 1217524c..fefff88d 100644 --- a/syscall/fs_syscall.c +++ b/syscall/fs_syscall.c @@ -291,17 +291,135 @@ ssize_t SysWrite(int fd, const void *buf, size_t nbytes) return ret; } +// int vfs_normalize_path(const char *directory, const char *filename, char **pathname) +#ifdef LOSCFG_PID_CONTAINER +#ifdef LOSCFG_PROC_PROCESS_DIR +#define PROCESS_DIR_ROOT "/proc" +static char *NextName(char *pos, uint8_t *len) +{ + char *name = NULL; + while (*pos != 0 && *pos == '/') { + pos++; + } + if (*pos == '\0') { + return NULL; + } + name = (char *)pos; + while (*pos != '\0' && *pos != '/') { + pos++; + } + *len = pos - name; + return name; +} + +static unsigned int ProcRealProcessIDGet(unsigned int pid) +{ + unsigned int intSave; + if (OS_PID_CHECK_INVALID(pid)) { + return 0; + } + + SCHEDULER_LOCK(intSave); + LosProcessCB *pcb = OsGetPCBFromVpid(pid); + if (pcb == NULL) { + SCHEDULER_UNLOCK(intSave); + return 0; + } + + int rootPid = OsGetRootPid(pcb); + SCHEDULER_UNLOCK(intSave); + if ((rootPid == OS_INVALID_VALUE) || (rootPid == pid)) { + return 0; + } + + return rootPid; +} + +static int ProcRealProcessDirGet(char *path) +{ + char pidBuf[PATH_MAX] = {0}; + char *fullPath = NULL; + uint8_t strLen = 0; + int pid, rootPid; + int ret = vfs_normalize_path(NULL, path, &fullPath); + if (ret < 0) { + return ret; + } + + int procLen = strlen(PROCESS_DIR_ROOT); + if (strncmp(fullPath, PROCESS_DIR_ROOT, procLen) != 0) { + free(fullPath); + return 0; + } + + char *pidStr = NextName(fullPath + procLen, &strLen); + if (pidStr == NULL) { + free(fullPath); + return 0; + } + + if ((*pidStr <= '0') || (*pidStr > '9')) { + free(fullPath); + return 0; + } + + if (memcpy_s(pidBuf, PATH_MAX, pidStr, strLen) != EOK) { + free(fullPath); + return 0; + } + pidBuf[strLen] = '\0'; + + pid = atoi(pidBuf); + if (pid == 0) { + free(fullPath); + return 0; + } + + rootPid = ProcRealProcessIDGet((unsigned)pid); + if (rootPid == 0) { + free(fullPath); + return 0; + } + + if (snprintf_s(path, PATH_MAX + 1, PATH_MAX, "/proc/%d%s", rootPid, (pidStr + strLen)) < 0) { + free(fullPath); + return -EFAULT; + } + + free(fullPath); + return 0; +} +#endif +#endif + +static int GetPath(const char *path, char **pathRet) +{ + int ret = UserPathCopy(path, pathRet); + if (ret != 0) { + return ret; + } +#ifdef LOSCFG_PID_CONTAINER +#ifdef LOSCFG_PROC_PROCESS_DIR + ret = ProcRealProcessDirGet(*pathRet); + if (ret != 0) { + return ret; + } +#endif +#endif + return 0; +} + int SysOpen(const char *path, int oflags, ...) { int ret; - int procFd; + int procFd = -1; mode_t mode = DEFAULT_FILE_MODE; /* 0666: File read-write properties. */ char *pathRet = NULL; if (path != NULL) { - ret = UserPathCopy(path, &pathRet); + ret = GetPath(path, &pathRet); if (ret != 0) { - return ret; + goto ERROUT; } } @@ -432,6 +550,15 @@ ssize_t SysReadlink(const char *pathname, char *buf, size_t bufsize) if (ret != 0) { goto OUT; } + +#ifdef LOSCFG_PID_CONTAINER +#ifdef LOSCFG_PROC_PROCESS_DIR + ret = ProcRealProcessDirGet(pathRet); + if (ret != 0) { + goto OUT; + } +#endif +#endif } if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, bufsize)) { @@ -1840,6 +1967,15 @@ ssize_t SysReadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize if (ret != 0) { goto OUT; } + +#ifdef LOSCFG_PID_CONTAINER +#ifdef LOSCFG_PROC_PROCESS_DIR + ret = ProcRealProcessDirGet(pathRet); + if (ret != 0) { + goto OUT; + } +#endif +#endif } if (dirfd != AT_FDCWD) { diff --git a/testsuites/unittest/container/full/It_pid_container_002.cpp b/testsuites/unittest/container/full/It_pid_container_002.cpp index a667139b..f9048eb8 100644 --- a/testsuites/unittest/container/full/It_pid_container_002.cpp +++ b/testsuites/unittest/container/full/It_pid_container_002.cpp @@ -110,25 +110,26 @@ static int ChildFunClone1(void *p) int ret; pid_t pid = getpid(); int childFunRet = (int)pid; - void *pstk = malloc(STACK_SIZE); - if (pstk == NULL) { - return EXIT_CODE_ERRNO_2; - } - int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + char *containerType = "pid"; + int childPid = clone(ChildFunClone2, NULL, CLONE_NEWPID | SIGCHLD, NULL); if (childPid == -1) { - free(pstk); return EXIT_CODE_ERRNO_3; } + auto linkBuffer = ReadlinkContainer(childPid, containerType); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + (void)waitpid(childPid, &status, 0); + return EXIT_CODE_ERRNO_5; + } + ret = waitpid(childPid, &status, 0); ret = WIFEXITED(status); ret = WEXITSTATUS(status); if (ret != CONTAINER_FIRST_PID) { - free(pstk); return EXIT_CODE_ERRNO_4; } - - free(pstk); return childFunRet; }