xref: /kernel/liteos_a/syscall/syscall_pub.c (revision 0d163575)
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