process_read/write_vm(): fix LTP bugs

This commit is contained in:
Balazs Gerofi
2015-12-18 15:58:44 +09:00
parent 0f8b2aba22
commit d0507f7e9f
2 changed files with 101 additions and 8 deletions

View File

@@ -48,6 +48,7 @@
#include <shm.h> #include <shm.h>
#include <prio.h> #include <prio.h>
#include <arch/cpu.h> #include <arch/cpu.h>
#include <limits.h>
/* Headers taken from kitten LWK */ /* Headers taken from kitten LWK */
#include <lwk/stddef.h> #include <lwk/stddef.h>
@@ -5930,13 +5931,45 @@ static int do_process_vm_read_writev(int pid,
unsigned long rphys; unsigned long rphys;
unsigned long rpage_left; unsigned long rpage_left;
void *rva; void *rva;
struct vm_range *range;
/* Sanity checks */ /* Sanity checks */
if (flags) { if (flags) {
return -EINVAL; return -EINVAL;
} }
/* TODO: IOV_MAX and PTRACE_ATTACH permission checks.. */ if (liovcnt > IOV_MAX || riovcnt > IOV_MAX) {
return -EINVAL;
}
/* Check if parameters are okay */
ihk_mc_spinlock_lock_noirq(&lthread->vm->memory_range_lock);
range = lookup_process_memory_range(lthread->vm,
(uintptr_t)local_iov,
(uintptr_t)(local_iov + liovcnt * sizeof(struct iovec)));
if (!range) {
ret = -EFAULT;
goto arg_out;
}
range = lookup_process_memory_range(lthread->vm,
(uintptr_t)remote_iov,
(uintptr_t)(remote_iov + riovcnt * sizeof(struct iovec)));
if (!range) {
ret = -EFAULT;
goto arg_out;
}
ret = 0;
arg_out:
ihk_mc_spinlock_unlock_noirq(&lthread->vm->memory_range_lock);
if (ret != 0) {
goto out;
}
for (li = 0; li < liovcnt; ++li) { for (li = 0; li < liovcnt; ++li) {
llen += local_iov[li].iov_len; llen += local_iov[li].iov_len;
@@ -5978,6 +6011,16 @@ static int do_process_vm_read_writev(int pid,
goto out; goto out;
} }
if (rthread->proc->ruid != lthread->proc->ruid ||
rthread->proc->euid != lthread->proc->euid ||
rthread->proc->rgid != lthread->proc->rgid ||
rthread->proc->egid != lthread->proc->egid) {
ret = -EPERM;
goto out;
}
dkprintf("pid %d found, doing %s \n", pid, dkprintf("pid %d found, doing %s \n", pid,
(op == PROCESS_VM_READ) ? "PROCESS_VM_READ" : "PROCESS_VM_WRITE"); (op == PROCESS_VM_READ) ? "PROCESS_VM_READ" : "PROCESS_VM_WRITE");
@@ -5994,6 +6037,17 @@ static int do_process_vm_read_writev(int pid,
ihk_mc_spinlock_lock_noirq(&lthread->vm->memory_range_lock); ihk_mc_spinlock_lock_noirq(&lthread->vm->memory_range_lock);
/* Is base valid? */
range = lookup_process_memory_range(lthread->vm,
(uintptr_t)local_iov[li].iov_base,
(uintptr_t)(local_iov[li].iov_base + 1));
if (!range) {
ret = -EFAULT;
goto pli_out;
}
/* Is length valid? */
range = lookup_process_memory_range(lthread->vm, range = lookup_process_memory_range(lthread->vm,
(uintptr_t)local_iov[li].iov_base, (uintptr_t)local_iov[li].iov_base,
(uintptr_t)(local_iov[li].iov_base + local_iov[li].iov_len)); (uintptr_t)(local_iov[li].iov_base + local_iov[li].iov_len));
@@ -6005,7 +6059,7 @@ static int do_process_vm_read_writev(int pid,
if (!(range->flag & ((op == PROCESS_VM_READ) ? if (!(range->flag & ((op == PROCESS_VM_READ) ?
VR_PROT_WRITE : VR_PROT_READ))) { VR_PROT_WRITE : VR_PROT_READ))) {
ret = -EPERM; ret = -EFAULT;
goto pli_out; goto pli_out;
} }
@@ -6024,7 +6078,45 @@ pli_out:
if (pri != ri) { if (pri != ri) {
uint64_t reason = PF_POPULATE | PF_WRITE | PF_USER; uint64_t reason = PF_POPULATE | PF_WRITE | PF_USER;
void *addr; void *addr;
struct vm_range *range;
ihk_mc_spinlock_lock_noirq(&rthread->vm->memory_range_lock);
/* Is base valid? */
range = lookup_process_memory_range(rthread->vm,
(uintptr_t)remote_iov[li].iov_base,
(uintptr_t)(remote_iov[li].iov_base + 1));
if (!range) {
ret = -EFAULT;
goto pri_out;
}
/* Is length valid? */
range = lookup_process_memory_range(lthread->vm,
(uintptr_t)remote_iov[li].iov_base,
(uintptr_t)(remote_iov[li].iov_base + remote_iov[li].iov_len));
if (range == NULL) {
ret = -EINVAL;
goto pri_out;
}
if (!(range->flag & ((op == PROCESS_VM_READ) ?
VR_PROT_READ : VR_PROT_WRITE))) {
ret = -EFAULT;
goto pri_out;
}
ret = 0;
pri_out:
ihk_mc_spinlock_unlock_noirq(&rthread->vm->memory_range_lock);
if (ret != 0) {
goto out;
}
/* Fault in pages */
for (addr = (void *) for (addr = (void *)
((unsigned long)remote_iov[ri].iov_base & PAGE_MASK); ((unsigned long)remote_iov[ri].iov_base & PAGE_MASK);
addr < (remote_iov[ri].iov_base + remote_iov[ri].iov_len); addr < (remote_iov[ri].iov_base + remote_iov[ri].iov_len);
@@ -6032,7 +6124,7 @@ pli_out:
ret = page_fault_process_vm(rthread->vm, addr, reason); ret = page_fault_process_vm(rthread->vm, addr, reason);
if (ret) { if (ret) {
ret = -EINVAL; ret = -EFAULT;
goto out; goto out;
} }
} }
@@ -6058,7 +6150,7 @@ pli_out:
remote_iov[ri].iov_base + roff, &rphys); remote_iov[ri].iov_base + roff, &rphys);
if (ret) { if (ret) {
ret = -EINVAL; ret = -EFAULT;
goto out; goto out;
} }

View File

@@ -15,5 +15,6 @@
#define INT_MAX 0x7fffffff #define INT_MAX 0x7fffffff
#define INT_MIN -0x80000000 #define INT_MIN -0x80000000
#define IOV_MAX 1024
#endif #endif