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
CheckRegion(const LosVmSpace * space,VADDR_T ptr,size_t len)33 int 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
DupUserMem(const void * ptr,size_t len,int needCopy)46 void *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
GetFullpath(int fd,const char * path,char ** fullpath)63 int 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
103 OUT:
104 PointerFree(pathRet);
105 return ret;
106 }
107
UserPathCopy(const char * userPath,char ** pathBuf)108 int 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