diff options
Diffstat (limited to 'components/lwp')
| -rw-r--r-- | components/lwp/arch/risc-v/rv64/lwp_gcc.S | 10 | ||||
| -rw-r--r-- | components/lwp/lwp_shm.c | 7 | ||||
| -rw-r--r-- | components/lwp/lwp_syscall.c | 105 | ||||
| -rw-r--r-- | components/lwp/lwp_user_mm.c | 11 |
4 files changed, 122 insertions, 11 deletions
diff --git a/components/lwp/arch/risc-v/rv64/lwp_gcc.S b/components/lwp/arch/risc-v/rv64/lwp_gcc.S index c54726bc45..3977553dbf 100644 --- a/components/lwp/arch/risc-v/rv64/lwp_gcc.S +++ b/components/lwp/arch/risc-v/rv64/lwp_gcc.S @@ -121,6 +121,16 @@ arch_signal_quit: * routine in user stack */ user_do_signal: + /* prefetch ustack to avoid corrupted status in RESTORE/STORE pair below */ + LOAD t0, FRAME_OFF_SP(sp) + addi t1, t0, -CTX_REG_NR * REGBYTES + LOAD t2, (t0) + li t3, -0x1000 +1: + add t0, t0, t3 + LOAD t2, (t0) + bgt t0, t1, 1b + /** restore and backup kernel sp carefully to avoid leaking */ addi t0, sp, CTX_REG_NR * REGBYTES csrw sscratch, t0 diff --git a/components/lwp/lwp_shm.c b/components/lwp/lwp_shm.c index 8c765fc8c9..51964dd2b8 100644 --- a/components/lwp/lwp_shm.c +++ b/components/lwp/lwp_shm.c @@ -101,7 +101,7 @@ static int _lwp_shmget(size_t key, size_t size, int create) int id = -1; struct lwp_avl_struct *node_key = 0; struct lwp_avl_struct *node_pa = 0; - void *page_addr = 0, *page_addr_p = RT_NULL; + void *page_addr = 0; uint32_t bit = 0; /* try to locate the item with the key in the binary tree */ @@ -134,11 +134,10 @@ static int _lwp_shmget(size_t key, size_t size, int create) { goto err; } - page_addr_p = (void *)((char *)page_addr + PV_OFFSET); /* physical address */ /* initialize the shared memory structure */ p = _shm_ary + id; - p->addr = (size_t)page_addr_p; + p->addr = (size_t)page_addr; p->size = (1UL << (bit + ARCH_PAGE_SHIFT)); p->ref = 0; p->key = key; @@ -236,7 +235,7 @@ static int _lwp_shmrm(int id) return 0; } bit = rt_page_bits(p->size); - rt_pages_free((void *)((char *)p->addr - PV_OFFSET), bit); + rt_pages_free((void *)p->addr, bit); lwp_avl_remove(node_key, &shm_tree_key); node_pa = node_key + 1; lwp_avl_remove(node_pa, &shm_tree_pa); diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index 37459366f5..6b12d929fe 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -612,7 +612,7 @@ int sys_fstat(int file, struct stat *buf) { #ifdef ARCH_MM_MMU int ret = -1; - struct stat statbuff; + struct stat statbuff = {0}; if (!lwp_user_accessable((void *)buf, sizeof(struct stat))) { @@ -2575,7 +2575,45 @@ int sys_log(const char* log, int size) int sys_stat(const char *file, struct stat *buf) { int ret = 0; - ret = stat(file, buf); + int err; + size_t len; + size_t copy_len; + char *copy_path; + struct stat statbuff = {0}; + + if (!lwp_user_accessable((void *)buf, sizeof(struct stat))) + { + return -EFAULT; + } + + len = lwp_user_strlen(file, &err); + if (err) + { + return -EFAULT; + } + + copy_path = (char*)rt_malloc(len + 1); + if (!copy_path) + { + return -ENOMEM; + } + + copy_len = lwp_get_from_user(copy_path, (void*)file, len); + if (copy_len == 0) + { + rt_free(copy_path); + return -EFAULT; + } + copy_path[copy_len] = '\0'; + + ret = stat(copy_path, &statbuff); + rt_free(copy_path); + + if (ret == 0) + { + lwp_put_to_user(buf, &statbuff, sizeof statbuff); + } + return (ret < 0 ? GET_ERRNO() : ret); } @@ -4157,6 +4195,67 @@ int sys_getrandom(void *buf, size_t buflen, unsigned int flags) #endif return ret; } + +ssize_t sys_readlink(char* path, char *buf, size_t bufsz) +{ + size_t len, copy_len; + int err; + int fd = -1; + struct dfs_fd *d; + char *copy_path; + + len = lwp_user_strlen(path, &err); + if (err) + { + return -EFAULT; + } + + if (!lwp_user_accessable(buf, bufsz)) + { + return -EINVAL; + } + + copy_path = (char*)rt_malloc(len + 1); + if (!copy_path) + { + return -ENOMEM; + } + + copy_len = lwp_get_from_user(copy_path, path, len); + copy_path[copy_len] = '\0'; + + /* musl __procfdname */ + err = sscanf(copy_path, "/proc/self/fd/%d", &fd); + rt_free(copy_path); + + if (err != 1) + { + LOG_E("readlink: path not is /proc/self/fd/* , call by musl __procfdname()?"); + return -EINVAL; + } + + d = fd_get(fd); + if (!d) + { + return -EBADF; + } + + if (!d->vnode) + { + return -EBADF; + } + + copy_len = strlen(d->vnode->fullpath); + if (copy_len > bufsz) + { + copy_len = bufsz; + } + + bufsz = lwp_put_to_user(buf, d->vnode->fullpath, copy_len); + + return bufsz; +} + int sys_setaffinity(pid_t pid, size_t size, void *set) { if (!lwp_user_accessable(set, sizeof(cpu_set_t))) @@ -4672,7 +4771,7 @@ const static void* func_table[] = SYSCALL_SIGN(sys_setrlimit), SYSCALL_SIGN(sys_setsid), SYSCALL_SIGN(sys_getrandom), - SYSCALL_SIGN(sys_notimpl), // SYSCALL_SIGN(sys_readlink) /* 145 */ + SYSCALL_SIGN(sys_readlink), // SYSCALL_SIGN(sys_readlink) /* 145 */ SYSCALL_USPACE(SYSCALL_SIGN(sys_mremap)), SYSCALL_USPACE(SYSCALL_SIGN(sys_madvise)), SYSCALL_SIGN(sys_sched_setparam), diff --git a/components/lwp/lwp_user_mm.c b/components/lwp/lwp_user_mm.c index 3844a3b189..edda62632d 100644 --- a/components/lwp/lwp_user_mm.c +++ b/components/lwp/lwp_user_mm.c @@ -560,9 +560,12 @@ int lwp_user_accessable(void *addr, size_t size) len = size; } tmp_addr = lwp_v2p(lwp, addr_start); - if (!tmp_addr) + if (tmp_addr == ARCH_MAP_FAILED) { - return 0; + if ((rt_ubase_t)addr_start >= USER_STACK_VSTART && (rt_ubase_t)addr_start < USER_STACK_VEND) + tmp_addr = *(void **)addr_start; + else + return 0; } addr_start = (void *)((char *)addr_start + len); size -= len; @@ -596,7 +599,7 @@ size_t lwp_data_get(struct rt_lwp *lwp, void *dst, void *src, size_t size) len = size; } tmp_src = lwp_v2p(lwp, addr_start); - if (!tmp_src) + if (tmp_src == ARCH_MAP_FAILED) { break; } @@ -636,7 +639,7 @@ size_t lwp_data_put(struct rt_lwp *lwp, void *dst, void *src, size_t size) len = size; } tmp_dst = lwp_v2p(lwp, addr_start); - if (!tmp_dst) + if (tmp_dst == ARCH_MAP_FAILED) { break; } |
