diff --git a/components/lwp/lwp.c b/components/lwp/lwp.c index 53045d6f1aa35f2181781965647b9eeee2650ad4..3c0312566a16c3cfe75c4faf418139f1cea9e6a4 100644 --- a/components/lwp/lwp.c +++ b/components/lwp/lwp.c @@ -373,6 +373,9 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str size_t rel_dyn_size = 0; size_t dynsym_off = 0; size_t dynsym_size = 0; +#ifdef RT_USING_USERSPACE + void *pa, *va; +#endif #ifdef RT_USING_USERSPACE rt_mmu_info *m_info = &lwp->mmu_info; @@ -424,9 +427,6 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str } { /* load aux */ -#ifdef RT_USING_USERSPACE - void *pa, *va; -#endif uint8_t *process_header; size_t process_header_size; @@ -478,6 +478,50 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str #endif } +#ifdef RT_USING_USERSPACE + /* map user */ + off = eheader.e_shoff; + for (i = 0; i < eheader.e_shnum; i++, off += sizeof sheader) + { + int need_map = 0; + int text = 0; + + check_off(off, len); + lseek(fd, off, SEEK_SET); + read_len = load_fread(&sheader, 1, sizeof sheader, fd); + check_read(read_len, sizeof sheader); + + if ((sheader.sh_flags & SHF_ALLOC) == 0) + { + continue; + } + + switch (sheader.sh_type) + { + case SHT_PROGBITS: + if ((sheader.sh_flags & SHF_EXECINSTR) != 0) + { + text = 1; + } + case SHT_NOBITS: + need_map = 1; + break; + default: + break; + } + if (need_map) + { + /* map user */ + va = lwp_map_user(lwp, (void *)sheader.sh_addr, sheader.sh_size, text); + if (!va || (va != (void *)(size_t)sheader.sh_addr)) + { + result = -RT_ERROR; + goto _exit; + } + } + } +#endif + off = eheader.e_phoff; for (i = 0; i < eheader.e_phnum; i++, off += sizeof pheader) { @@ -513,12 +557,8 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str result = -RT_ERROR; goto _exit; } - va = lwp_map_user(lwp, (void *)pheader.p_vaddr, pheader.p_memsz, 1); - } - else - { - va = lwp_map_user(lwp, 0, pheader.p_memsz, 0); } + va = (void *)pheader.p_vaddr; if (va) { lwp->text_entry = va; diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index 08d837be16af19fc0641622088109a1e68de04bb..1b29b689e68ecd5c4b6918c719f23dbe0c639a8a 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -2662,6 +2662,11 @@ int sys_access(const char *filename, int mode) int sys_pipe(int fd[2]) { + if (!lwp_user_accessable((void *)fd, sizeof(int[2]))) + { + rt_set_errno(EINVAL); + return -1; + } return pipe(fd); } diff --git a/components/lwp/lwp_user_mm.c b/components/lwp/lwp_user_mm.c index be31ab0e5410c9c4854ad5042921acf040b2f54a..41d98ddb41e7fa3839b9ea41b600cbb2985e5708 100644 --- a/components/lwp/lwp_user_mm.c +++ b/components/lwp/lwp_user_mm.c @@ -568,7 +568,7 @@ size_t lwp_data_get(rt_mmu_info *mmu_info, void *dst, void *src, size_t size) { break; } - tmp_src = (void *)((char *)rt_hw_mmu_v2p(mmu_info, addr_start) - PV_OFFSET); + tmp_src = (void *)((char *)tmp_src - PV_OFFSET); rt_memcpy(tmp_dst, tmp_src, len); tmp_dst = (void *)((char *)tmp_dst + len); addr_start = (void *)((char *)addr_start + len); @@ -607,7 +607,7 @@ size_t lwp_data_put(rt_mmu_info *mmu_info, void *dst, void *src, size_t size) { break; } - tmp_dst = (void *)((char *)rt_hw_mmu_v2p(mmu_info, addr_start) - PV_OFFSET); + tmp_dst = (void *)((char *)tmp_dst - PV_OFFSET); rt_memcpy(tmp_dst, tmp_src, len); tmp_src = (void *)((char *)tmp_src + len); addr_start = (void *)((char *)addr_start + len);