summaryrefslogtreecommitdiff
path: root/components/lwp
diff options
context:
space:
mode:
Diffstat (limited to 'components/lwp')
-rw-r--r--components/lwp/arch/risc-v/rv64/lwp_gcc.S10
-rw-r--r--components/lwp/lwp_shm.c7
-rw-r--r--components/lwp/lwp_syscall.c105
-rw-r--r--components/lwp/lwp_user_mm.c11
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;
}