1/* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 * of conditions and the following disclaimer in the documentation and/or other materials 13 * provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31#include "syscall_pub.h" 32 33int CheckRegion(const LosVmSpace *space, VADDR_T ptr, size_t len) 34{ 35 LosVmMapRegion *region = LOS_RegionFind((LosVmSpace *)space, ptr); 36 if (region == NULL) { 37 return -1; 38 } 39 if (ptr + len <= region->range.base + region->range.size) { 40 return 0; 41 } 42 return CheckRegion(space, region->range.base + region->range.size, 43 (ptr + len) - (region->range.base + region->range.size)); 44} 45 46void *DupUserMem(const void *ptr, size_t len, int needCopy) 47{ 48 void *p = LOS_MemAlloc(OS_SYS_MEM_ADDR, len); 49 if (p == NULL) { 50 set_errno(ENOMEM); 51 return NULL; 52 } 53 54 if (needCopy && LOS_ArchCopyFromUser(p, ptr, len) != 0) { 55 LOS_MemFree(OS_SYS_MEM_ADDR, p); 56 set_errno(EFAULT); 57 return NULL; 58 } 59 60 return p; 61} 62 63int GetFullpath(int fd, const char *path, char **fullpath) 64{ 65 int ret = 0; 66 char *pathRet = NULL; 67 struct file *file = NULL; 68 struct stat bufRet = {0}; 69 70 if (path != NULL) { 71 ret = UserPathCopy(path, &pathRet); 72 if (ret != 0) { 73 goto OUT; 74 } 75 } 76 77 if ((pathRet != NULL) && (*pathRet == '/')) { 78 *fullpath = pathRet; 79 pathRet = NULL; 80 } else { 81 if (fd != AT_FDCWD) { 82 /* Process fd convert to system global fd */ 83 fd = GetAssociatedSystemFd(fd); 84 } 85 ret = fs_getfilep(fd, &file); 86 if (ret < 0) { 87 ret = -EPERM; 88 goto OUT; 89 } 90 if (file) { 91 ret = stat(file->f_path, &bufRet); 92 if (!ret) { 93 if (!S_ISDIR(bufRet.st_mode)) { 94 set_errno(ENOTDIR); 95 ret = -ENOTDIR; 96 goto OUT; 97 } 98 } 99 } 100 ret = vfs_normalize_pathat(fd, pathRet, fullpath); 101 } 102 103OUT: 104 PointerFree(pathRet); 105 return ret; 106} 107 108int UserPathCopy(const char *userPath, char **pathBuf) 109{ 110 int ret; 111 112 *pathBuf = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, PATH_MAX + 1); 113 if (*pathBuf == NULL) { 114 return -ENOMEM; 115 } 116 117 ret = LOS_StrncpyFromUser(*pathBuf, userPath, PATH_MAX + 1); 118 if (ret < 0) { 119 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *pathBuf); 120 *pathBuf = NULL; 121 return ret; 122 } else if (ret > PATH_MAX) { 123 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *pathBuf); 124 *pathBuf = NULL; 125 return -ENAMETOOLONG; 126 } 127 (*pathBuf)[ret] = '\0'; 128 129 return 0; 130} 131