Implemented CopyStrIn/Out to fix bugginess of using CopyIn/Out wrapping passed a mapped page.
This commit is contained in:
parent
5ed248c8ec
commit
5808a2564d
@ -9,6 +9,7 @@
|
||||
#define ENOMEM 0xBAD5
|
||||
#define ENOENT 0xBAD6
|
||||
#define ENOTDIR 0xBAD7
|
||||
#define ENAMETOOLONG 0xBAD8
|
||||
|
||||
#endif /* __ERRNO_H__ */
|
||||
|
||||
|
@ -21,3 +21,27 @@ copy_unsafe_fault:
|
||||
retq
|
||||
FUNC_END(copy_unsafe)
|
||||
|
||||
// copystr_unsafe(to, from, len)
|
||||
FUNC_BEGIN(copystr_unsafe)
|
||||
movq %rdx, %rcx
|
||||
1:
|
||||
decq %rcx
|
||||
jz copystr_unsafe_toolong
|
||||
lodsb
|
||||
stosb
|
||||
orb %al, %al
|
||||
jnz 1b
|
||||
.globl copystr_unsafe_done
|
||||
copystr_unsafe_done:
|
||||
xorq %rax, %rax
|
||||
retq
|
||||
.globl copystr_unsafe_fault
|
||||
copystr_unsafe_fault:
|
||||
movq $EFAULT, %rax
|
||||
retq
|
||||
.globl copystr_unsafe_toolong
|
||||
copystr_unsafe_toolong:
|
||||
movq $ENAMETOOLONG, %rax
|
||||
retq
|
||||
FUNC_END(copystr_unsafe)
|
||||
|
||||
|
@ -115,6 +115,10 @@ extern int copy_unsafe(void *to, void *from, uintptr_t len);
|
||||
extern void copy_unsafe_done(void);
|
||||
extern void copy_unsafe_fault(void);
|
||||
|
||||
extern int copystr_unsafe(void *to, void *from, uintptr_t len);
|
||||
extern void copystr_unsafe_done(void);
|
||||
extern void copystr_unsafe_fault(void);
|
||||
|
||||
void
|
||||
trap_entry(TrapFrame *tf)
|
||||
{
|
||||
@ -140,6 +144,15 @@ trap_entry(TrapFrame *tf)
|
||||
return;
|
||||
}
|
||||
|
||||
// User IO
|
||||
if ((tf->vector == T_PF) &&
|
||||
(tf->rip >= (uint64_t)©str_unsafe) &&
|
||||
(tf->rip <= (uint64_t)©str_unsafe_done)) {
|
||||
kprintf("Faulted in copystr_unsafe\n");
|
||||
tf->rip = (uint64_t)©str_unsafe_fault;
|
||||
return;
|
||||
}
|
||||
|
||||
// Halt on kernel errors
|
||||
if (tf->vector <= T_CPU_LAST)
|
||||
{
|
||||
|
@ -107,6 +107,8 @@ Handle *Handle_Lookup(Process *proc, uint64_t fd);
|
||||
// CopyIn/CopyOut Functions
|
||||
int CopyIn(uintptr_t fromuser, void *tokernel, uintptr_t len);
|
||||
int CopyOut(void *fromkernel, uintptr_t touser, uintptr_t len);
|
||||
int CopyStrIn(uintptr_t fromuser, void *tokernel, uintptr_t len);
|
||||
int CopyStrOut(void *fromkernel, uintptr_t touser, uintptr_t len);
|
||||
|
||||
#endif /* __SYS_THREAD_H__ */
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <machine/pmap.h>
|
||||
|
||||
extern int copy_unsafe(void *to_addr, void *from_addr, uintptr_t len);
|
||||
extern int copystr_unsafe(void *to_addr, void *from_addr, uintptr_t len);
|
||||
|
||||
int
|
||||
CopyIn(uintptr_t fromuser, void *tokernel, uintptr_t len)
|
||||
@ -54,3 +55,45 @@ CopyOut(void *fromkernel, uintptr_t touser, uintptr_t len)
|
||||
return copy_unsafe((void *)touser, fromkernel, len);
|
||||
}
|
||||
|
||||
int
|
||||
CopyStrIn(uintptr_t fromuser, void *tokernel, uintptr_t len)
|
||||
{
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
// Kernel space
|
||||
if (fromuser >= MEM_USERSPACE_TOP) {
|
||||
kprintf("CopyStrIn: address exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
// Wrap around
|
||||
if (len > (MEM_USERSPACE_TOP - fromuser)) {
|
||||
kprintf("CopyStrIn: length exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
return copystr_unsafe(tokernel, (void *)fromuser, len);
|
||||
}
|
||||
|
||||
int
|
||||
CopyStrOut(void *fromkernel, uintptr_t touser, uintptr_t len)
|
||||
{
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
// Kernel space
|
||||
if (touser >= MEM_USERSPACE_TOP) {
|
||||
kprintf("CopyStrOut: address exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
// Wrap around
|
||||
if (len > (MEM_USERSPACE_TOP - touser)) {
|
||||
kprintf("CopyStrOut: length exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
return copystr_unsafe((void *)touser, fromkernel, len);
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,7 @@ Syscall_Spawn(uint64_t user_path)
|
||||
Process *proc;
|
||||
Thread *thr;
|
||||
|
||||
// XXX: Use CopyInStr
|
||||
status = CopyIn(user_path, &path, sizeof(path));
|
||||
status = CopyStrIn(user_path, &path, sizeof(path));
|
||||
if (status != 0)
|
||||
return status;
|
||||
|
||||
@ -200,8 +199,7 @@ Syscall_Open(uint64_t user_path, uint64_t flags)
|
||||
int status;
|
||||
char path[256];
|
||||
|
||||
// XXX: Use CopyInStr
|
||||
status = CopyIn(user_path, &path, sizeof(path));
|
||||
status = CopyStrIn(user_path, &path, sizeof(path));
|
||||
if (status != 0)
|
||||
return status;
|
||||
|
||||
@ -241,8 +239,7 @@ Syscall_Stat(uint64_t user_path, uint64_t user_stat)
|
||||
char path[256];
|
||||
struct stat sb;
|
||||
|
||||
// XXX: Use CopyInStr
|
||||
status = CopyIn(user_path, &path, sizeof(path));
|
||||
status = CopyStrIn(user_path, &path, sizeof(path));
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user