signal part 3 (EFAULT)
This commit is contained in:
@@ -18,10 +18,8 @@
|
||||
typedef unsigned long int __sigset_t;
|
||||
#define __sigmask(sig) (((__sigset_t) 1) << ((sig) - 1))
|
||||
|
||||
# define _SIGSET_NWORDS (1024 / (8 * sizeof (__sigset_t)))
|
||||
|
||||
typedef struct {
|
||||
__sigset_t __val[_SIGSET_NWORDS];
|
||||
__sigset_t __val[_NSIG_WORDS];
|
||||
} sigset_t;
|
||||
|
||||
#define SIG_BLOCK 0
|
||||
|
||||
@@ -1749,7 +1749,67 @@ unsigned long virt_to_phys(void *v)
|
||||
return va - MAP_ST_START;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct process_vm *vm = proc->vm;
|
||||
struct vm_range *range;
|
||||
size_t pos;
|
||||
size_t wsiz;
|
||||
unsigned long pgstart = (unsigned long)src;
|
||||
|
||||
wsiz = siz + (pgstart & 0x0000000000000fffUL);
|
||||
pgstart &= 0xfffffffffffff000UL;
|
||||
if(!pgstart || pgstart >= MAP_KERNEL_START)
|
||||
return -EFAULT;
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
for(pos = 0; pos < wsiz; pos += 4096, pgstart += 4096){
|
||||
range = lookup_process_memory_range(vm, pgstart, pgstart+1);
|
||||
if(range == NULL){
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
if((range->flag & VR_PROT_MASK) == VR_PROT_NONE){
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
memcpy(dst, src, siz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_to_user(struct process *proc, void *dst, const void *src, size_t siz)
|
||||
{
|
||||
struct process_vm *vm = proc->vm;
|
||||
struct vm_range *range;
|
||||
size_t pos;
|
||||
size_t wsiz;
|
||||
unsigned long pgstart = (unsigned long)dst;
|
||||
|
||||
wsiz = siz + (pgstart & 0x0000000000000fffUL);
|
||||
pgstart &= 0xfffffffffffff000UL;
|
||||
if(!pgstart || pgstart >= MAP_KERNEL_START)
|
||||
return -EFAULT;
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
for(pos = 0; pos < wsiz; pos += 4096, pgstart += 4096){
|
||||
range = lookup_process_memory_range(vm, pgstart, pgstart+1);
|
||||
if(range == NULL){
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
if(((range->flag & VR_PROT_MASK) == VR_PROT_NONE) ||
|
||||
!(range->flag & VR_PROT_WRITE)){
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
memcpy(dst, src, siz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,9 @@ struct process {
|
||||
} thread;
|
||||
|
||||
int tid;
|
||||
volatile int sigevent;
|
||||
sigset_t sigmask;
|
||||
sigset_t supmask;
|
||||
ihk_spinlock_t sigpendinglock;
|
||||
struct list_head sigpending;
|
||||
struct sig_shared *sigshared;
|
||||
|
||||
@@ -93,6 +93,8 @@ static char *syscall_name[] MCKERNEL_UNUSED = {
|
||||
};
|
||||
|
||||
void check_signal(long rc, unsigned long *regs);
|
||||
int copy_from_user(struct process *, void *, const void *, size_t);
|
||||
int copy_to_user(struct process *, void *, const void *, size_t);
|
||||
|
||||
#ifdef DCFA_KMOD
|
||||
static void do_mod_exit(int status);
|
||||
@@ -1041,32 +1043,38 @@ do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
|
||||
k = proc->sighandler->action + sig - 1;
|
||||
if(oact)
|
||||
memcpy(oact, k, sizeof(struct k_sigaction));
|
||||
if(act){
|
||||
if(act)
|
||||
memcpy(k, act, sizeof(struct k_sigaction));
|
||||
}
|
||||
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(rt_sigaction)
|
||||
{
|
||||
struct process *proc = cpu_local_var(current);
|
||||
int sig = ihk_mc_syscall_arg0(ctx);
|
||||
const struct sigaction *act = (const struct sigaction *)ihk_mc_syscall_arg1(ctx);
|
||||
struct sigaction *oact = (struct sigaction *)ihk_mc_syscall_arg2(ctx);
|
||||
//size_t sigsetsize = ihk_mc_syscall_arg3(ctx);
|
||||
size_t sigsetsize = ihk_mc_syscall_arg3(ctx);
|
||||
struct k_sigaction new_sa, old_sa;
|
||||
int rc;
|
||||
|
||||
//if (sigsetsize != sizeof(sigset_t))
|
||||
//return -EINVAL;
|
||||
if (sigsetsize != sizeof(sigset_t))
|
||||
return -EINVAL;
|
||||
|
||||
if(act)
|
||||
memcpy(&new_sa.sa, act, sizeof new_sa.sa);
|
||||
if(copy_from_user(proc, &new_sa.sa, act, sizeof new_sa.sa)){
|
||||
goto fault;
|
||||
}
|
||||
rc = do_sigaction(sig, act? &new_sa: NULL, oact? &old_sa: NULL);
|
||||
if(oact)
|
||||
memcpy(oact, &old_sa.sa, sizeof old_sa.sa);
|
||||
if(rc == 0 && oact)
|
||||
if(copy_to_user(proc, oact, &old_sa.sa, sizeof old_sa.sa)){
|
||||
goto fault;
|
||||
}
|
||||
|
||||
return rc;
|
||||
fault:
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(rt_sigprocmask)
|
||||
@@ -1074,8 +1082,13 @@ SYSCALL_DECLARE(rt_sigprocmask)
|
||||
int how = ihk_mc_syscall_arg0(ctx);
|
||||
const sigset_t *set = (const sigset_t *)ihk_mc_syscall_arg1(ctx);
|
||||
sigset_t *oldset = (sigset_t *)ihk_mc_syscall_arg2(ctx);
|
||||
size_t sigsetsize = (size_t)ihk_mc_syscall_arg3(ctx);
|
||||
struct process *proc = cpu_local_var(current);
|
||||
int flag;
|
||||
__sigset_t wsig;
|
||||
|
||||
if(sigsetsize != sizeof(sigset_t))
|
||||
return -EINVAL;
|
||||
|
||||
if(set &&
|
||||
how != SIG_BLOCK &&
|
||||
@@ -1084,23 +1097,32 @@ SYSCALL_DECLARE(rt_sigprocmask)
|
||||
return -EINVAL;
|
||||
|
||||
flag = ihk_mc_spinlock_lock(&proc->sighandler->lock);
|
||||
if(oldset)
|
||||
oldset->__val[0] = proc->sigmask.__val[0];
|
||||
if(oldset){
|
||||
wsig = proc->sigmask.__val[0];
|
||||
if(copy_to_user(proc, oldset->__val, &wsig, sizeof wsig))
|
||||
goto fault;
|
||||
}
|
||||
if(set){
|
||||
if(copy_from_user(proc, &wsig, set->__val, sizeof wsig))
|
||||
goto fault;
|
||||
switch(how){
|
||||
case SIG_BLOCK:
|
||||
proc->sigmask.__val[0] |= set->__val[0];
|
||||
proc->sigmask.__val[0] |= wsig;
|
||||
break;
|
||||
case SIG_UNBLOCK:
|
||||
proc->sigmask.__val[0] &= ~set->__val[0];
|
||||
proc->sigmask.__val[0] &= ~wsig;
|
||||
break;
|
||||
case SIG_SETMASK:
|
||||
proc->sigmask.__val[0] = set->__val[0];
|
||||
proc->sigmask.__val[0] = wsig;
|
||||
break;
|
||||
}
|
||||
}
|
||||
proc->supmask = proc->sigmask;
|
||||
ihk_mc_spinlock_unlock(&proc->sighandler->lock, flag);
|
||||
return 0;
|
||||
fault:
|
||||
ihk_mc_spinlock_unlock(&proc->sighandler->lock, flag);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(rt_sigpending)
|
||||
@@ -1112,6 +1134,10 @@ SYSCALL_DECLARE(rt_sigpending)
|
||||
__sigset_t w = 0;
|
||||
struct process *proc = cpu_local_var(current);
|
||||
sigset_t *set = (sigset_t *)ihk_mc_syscall_arg0(ctx);
|
||||
size_t sigsetsize = (size_t)ihk_mc_syscall_arg1(ctx);
|
||||
|
||||
if (sigsetsize > sizeof(sigset_t))
|
||||
return -EINVAL;
|
||||
|
||||
lock = &proc->sigshared->lock;
|
||||
head = &proc->sigshared->sigpending;
|
||||
@@ -1129,23 +1155,39 @@ SYSCALL_DECLARE(rt_sigpending)
|
||||
}
|
||||
ihk_mc_spinlock_unlock(lock, flag);
|
||||
|
||||
set->__val[0] = w;
|
||||
if(copy_to_user(proc, set->__val, &w, sizeof w))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(rt_sigtimedwait)
|
||||
{
|
||||
/*
|
||||
sigset_t *
|
||||
siginfo_t *
|
||||
struct timespec *
|
||||
size_t
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(rt_sigqueueinfo)
|
||||
{
|
||||
/*
|
||||
pid_t
|
||||
int
|
||||
siginfo_t *
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(rt_sigsuspend)
|
||||
{
|
||||
/*
|
||||
sigset_t *
|
||||
size_t
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1276,8 +1318,10 @@ SYSCALL_DECLARE(getrlimit)
|
||||
|
||||
case RLIMIT_STACK:
|
||||
dkprintf("[%d] getrlimit() RLIMIT_STACK\n", ihk_mc_get_processor_id());
|
||||
rlm->rlim_cur = proc->rlimit_stack.rlim_cur;
|
||||
rlm->rlim_max = proc->rlimit_stack.rlim_max;
|
||||
if(copy_to_user(proc, &rlm->rlim_cur, &proc->rlimit_stack.rlim_cur, sizeof rlm->rlim_cur))
|
||||
return -EFAULT;
|
||||
if(copy_to_user(proc, &rlm->rlim_max, &proc->rlimit_stack.rlim_max, sizeof rlm->rlim_max))
|
||||
return -EFAULT;
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user