change copy-in routines
- restrict copy_from_user() to only current process. - add read_process_vm() to read specified process space.
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include <list.h>
|
||||
#include <process.h>
|
||||
#include <page.h>
|
||||
#include <cls.h>
|
||||
|
||||
#define dkprintf(...) do { if (0) kprintf(__VA_ARGS__); } while (0)
|
||||
#define ekprintf(...) kprintf(__VA_ARGS__)
|
||||
@@ -2117,9 +2118,9 @@ void *phys_to_virt(unsigned long p)
|
||||
return (void *)(p + MAP_ST_START);
|
||||
}
|
||||
|
||||
int copy_from_user(struct process *proc, void *dst, const void *src, size_t siz)
|
||||
int copy_from_user(void *dst, const void *src, size_t siz)
|
||||
{
|
||||
struct process_vm *vm = proc->vm;
|
||||
struct process_vm *vm = cpu_local_var(current)->vm;
|
||||
struct vm_range *range;
|
||||
size_t pos;
|
||||
size_t wsiz;
|
||||
@@ -2146,6 +2147,59 @@ int copy_from_user(struct process *proc, void *dst, const void *src, size_t siz)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_process_vm(struct process_vm *vm, void *kdst, const void *usrc, size_t siz)
|
||||
{
|
||||
const uintptr_t ustart = (uintptr_t)usrc;
|
||||
const uintptr_t uend = ustart + siz;
|
||||
uint64_t reason;
|
||||
uintptr_t addr;
|
||||
int error;
|
||||
const void *from;
|
||||
void *to;
|
||||
size_t remain;
|
||||
size_t cpsize;
|
||||
unsigned long pa;
|
||||
void *va;
|
||||
|
||||
if ((ustart < vm->region.user_start)
|
||||
|| (vm->region.user_end <= ustart)
|
||||
|| ((vm->region.user_end - ustart) < siz)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
reason = PF_USER; /* page not present */
|
||||
for (addr = ustart & PAGE_MASK; addr < uend; addr += PAGE_SIZE) {
|
||||
error = page_fault_process_vm(vm, (void *)addr, reason);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
from = usrc;
|
||||
to = kdst;
|
||||
remain = siz;
|
||||
while (remain > 0) {
|
||||
cpsize = PAGE_SIZE - ((uintptr_t)from & (PAGE_SIZE - 1));
|
||||
if (cpsize > remain) {
|
||||
cpsize = remain;
|
||||
}
|
||||
|
||||
error = ihk_mc_pt_virt_to_phys(vm->page_table, from, &pa);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
va = phys_to_virt(pa);
|
||||
memcpy(to, va, cpsize);
|
||||
|
||||
from += cpsize;
|
||||
to += cpsize;
|
||||
remain -= cpsize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* read_process_vm() */
|
||||
|
||||
int copy_to_user(struct process *proc, void *dst, const void *src, size_t siz)
|
||||
{
|
||||
struct process_vm *vm = proc->vm;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <kmalloc.h>
|
||||
|
||||
void terminate(int, int, ihk_mc_user_context_t *);
|
||||
int copy_from_user(struct process *proc, void *dst, const void *src, size_t siz);
|
||||
int copy_from_user(void *dst, const void *src, size_t siz);
|
||||
int copy_to_user(struct process *proc, void *dst, const void *src, size_t siz);
|
||||
long do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact);
|
||||
|
||||
@@ -117,7 +117,7 @@ SYSCALL_DECLARE(rt_sigaction)
|
||||
return -EINVAL;
|
||||
|
||||
if(act)
|
||||
if(copy_from_user(proc, &new_sa.sa, act, sizeof new_sa.sa)){
|
||||
if(copy_from_user(&new_sa.sa, act, sizeof new_sa.sa)){
|
||||
goto fault;
|
||||
}
|
||||
rc = do_sigaction(sig, act? &new_sa: NULL, oact? &old_sa: NULL);
|
||||
@@ -152,9 +152,9 @@ SYSCALL_DECLARE(rt_sigreturn)
|
||||
sigsp = (struct sigsp *)regs->gpr.rsp;
|
||||
proc->sigmask.__val[0] = sigsp->sigmask;
|
||||
proc->sigstack.ss_flags = sigsp->ssflags;
|
||||
if(copy_from_user(proc, regs, &sigsp->regs, sizeof(struct x86_user_context)))
|
||||
if(copy_from_user(regs, &sigsp->regs, sizeof(struct x86_user_context)))
|
||||
return rc;
|
||||
copy_from_user(proc, &rc, &sigsp->sigrc, sizeof(long));
|
||||
copy_from_user(&rc, &sigsp->sigrc, sizeof(long));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user