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 ENOMEM 0xBAD5
|
||||||
#define ENOENT 0xBAD6
|
#define ENOENT 0xBAD6
|
||||||
#define ENOTDIR 0xBAD7
|
#define ENOTDIR 0xBAD7
|
||||||
|
#define ENAMETOOLONG 0xBAD8
|
||||||
|
|
||||||
#endif /* __ERRNO_H__ */
|
#endif /* __ERRNO_H__ */
|
||||||
|
|
||||||
|
@ -21,3 +21,27 @@ copy_unsafe_fault:
|
|||||||
retq
|
retq
|
||||||
FUNC_END(copy_unsafe)
|
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_done(void);
|
||||||
extern void copy_unsafe_fault(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
|
void
|
||||||
trap_entry(TrapFrame *tf)
|
trap_entry(TrapFrame *tf)
|
||||||
{
|
{
|
||||||
@ -140,6 +144,15 @@ trap_entry(TrapFrame *tf)
|
|||||||
return;
|
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
|
// Halt on kernel errors
|
||||||
if (tf->vector <= T_CPU_LAST)
|
if (tf->vector <= T_CPU_LAST)
|
||||||
{
|
{
|
||||||
|
@ -107,6 +107,8 @@ Handle *Handle_Lookup(Process *proc, uint64_t fd);
|
|||||||
// CopyIn/CopyOut Functions
|
// CopyIn/CopyOut Functions
|
||||||
int CopyIn(uintptr_t fromuser, void *tokernel, uintptr_t len);
|
int CopyIn(uintptr_t fromuser, void *tokernel, uintptr_t len);
|
||||||
int CopyOut(void *fromkernel, uintptr_t touser, 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__ */
|
#endif /* __SYS_THREAD_H__ */
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <machine/pmap.h>
|
#include <machine/pmap.h>
|
||||||
|
|
||||||
extern int copy_unsafe(void *to_addr, void *from_addr, uintptr_t len);
|
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
|
int
|
||||||
CopyIn(uintptr_t fromuser, void *tokernel, uintptr_t len)
|
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);
|
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;
|
Process *proc;
|
||||||
Thread *thr;
|
Thread *thr;
|
||||||
|
|
||||||
// XXX: Use CopyInStr
|
status = CopyStrIn(user_path, &path, sizeof(path));
|
||||||
status = CopyIn(user_path, &path, sizeof(path));
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@ -200,8 +199,7 @@ Syscall_Open(uint64_t user_path, uint64_t flags)
|
|||||||
int status;
|
int status;
|
||||||
char path[256];
|
char path[256];
|
||||||
|
|
||||||
// XXX: Use CopyInStr
|
status = CopyStrIn(user_path, &path, sizeof(path));
|
||||||
status = CopyIn(user_path, &path, sizeof(path));
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@ -241,8 +239,7 @@ Syscall_Stat(uint64_t user_path, uint64_t user_stat)
|
|||||||
char path[256];
|
char path[256];
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
// XXX: Use CopyInStr
|
status = CopyStrIn(user_path, &path, sizeof(path));
|
||||||
status = CopyIn(user_path, &path, sizeof(path));
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user