sched_setaffinity: add permission check
This commit is contained in:
@@ -4917,14 +4917,13 @@ SYSCALL_DECLARE(sched_setaffinity)
|
|||||||
int tid = (int)ihk_mc_syscall_arg0(ctx);
|
int tid = (int)ihk_mc_syscall_arg0(ctx);
|
||||||
size_t len = (size_t)ihk_mc_syscall_arg1(ctx);
|
size_t len = (size_t)ihk_mc_syscall_arg1(ctx);
|
||||||
cpu_set_t *u_cpu_set = (cpu_set_t *)ihk_mc_syscall_arg2(ctx);
|
cpu_set_t *u_cpu_set = (cpu_set_t *)ihk_mc_syscall_arg2(ctx);
|
||||||
|
|
||||||
cpu_set_t k_cpu_set, cpu_set;
|
cpu_set_t k_cpu_set, cpu_set;
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
int cpu_id;
|
int cpu_id;
|
||||||
int empty_set = 1;
|
int empty_set = 1;
|
||||||
unsigned long irqstate;
|
|
||||||
extern int num_processors;
|
extern int num_processors;
|
||||||
|
|
||||||
|
kprintf("sched_setaffinity tid=%d len=%d set=%p\n", tid, len, u_cpu_set);
|
||||||
if (sizeof(k_cpu_set) > len) {
|
if (sizeof(k_cpu_set) > len) {
|
||||||
memset(&k_cpu_set, 0, sizeof(k_cpu_set));
|
memset(&k_cpu_set, 0, sizeof(k_cpu_set));
|
||||||
}
|
}
|
||||||
@@ -4956,47 +4955,35 @@ SYSCALL_DECLARE(sched_setaffinity)
|
|||||||
tid = cpu_local_var(current)->tid;
|
tid = cpu_local_var(current)->tid;
|
||||||
thread = cpu_local_var(current);
|
thread = cpu_local_var(current);
|
||||||
cpu_id = ihk_mc_get_processor_id();
|
cpu_id = ihk_mc_get_processor_id();
|
||||||
irqstate = ihk_mc_spinlock_lock(&get_cpu_local_var(cpu_id)->runq_lock);
|
hold_thread(thread);
|
||||||
|
|
||||||
goto found;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (cpu_id = 0; cpu_id < num_processors; cpu_id++) {
|
struct mcs_rwlock_node_irqsave lock;
|
||||||
irqstate = ihk_mc_spinlock_lock(
|
struct thread *mythread = cpu_local_var(current);
|
||||||
&get_cpu_local_var(cpu_id)->runq_lock);
|
|
||||||
|
|
||||||
list_for_each_entry(thread,
|
thread = find_thread(0, tid, &lock);
|
||||||
&get_cpu_local_var(cpu_id)->runq, sched_list) {
|
if(!thread)
|
||||||
|
return -ESRCH;
|
||||||
if (thread->proc->pid && thread->tid == tid) {
|
if(mythread->proc->euid != 0 &&
|
||||||
goto found; /* without unlocking runq_lock */
|
mythread->proc->euid != thread->proc->ruid &&
|
||||||
}
|
mythread->proc->euid != thread->proc->euid){
|
||||||
}
|
thread_unlock(thread, &lock);
|
||||||
|
return -EPERM;
|
||||||
ihk_mc_spinlock_unlock(&get_cpu_local_var(cpu_id)->runq_lock,
|
|
||||||
irqstate);
|
|
||||||
}
|
}
|
||||||
|
hold_thread(thread);
|
||||||
|
thread_unlock(thread, &lock);
|
||||||
|
cpu_id = thread->cpu_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
kprintf("%s:%d Thread not found.\n", __FILE__, __LINE__);
|
|
||||||
return -ESRCH;
|
|
||||||
|
|
||||||
found:
|
|
||||||
memcpy(&thread->cpu_set, &cpu_set, sizeof(cpu_set));
|
memcpy(&thread->cpu_set, &cpu_set, sizeof(cpu_set));
|
||||||
|
|
||||||
if (!CPU_ISSET(cpu_id, &thread->cpu_set)) {
|
if (!CPU_ISSET(cpu_id, &thread->cpu_set)) {
|
||||||
hold_thread(thread);
|
|
||||||
ihk_mc_spinlock_unlock(&get_cpu_local_var(cpu_id)->runq_lock, irqstate);
|
|
||||||
dkprintf("sched_setaffinity(): tid %d sched_request_migrate\n",
|
dkprintf("sched_setaffinity(): tid %d sched_request_migrate\n",
|
||||||
cpu_local_var(current)->tid, cpu_id);
|
cpu_local_var(current)->tid, cpu_id);
|
||||||
sched_request_migrate(cpu_id, thread);
|
sched_request_migrate(cpu_id, thread);
|
||||||
release_thread(thread);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ihk_mc_spinlock_unlock(&get_cpu_local_var(cpu_id)->runq_lock, irqstate);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
release_thread(thread);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see linux-2.6.34.13/kernel/sched.c
|
// see linux-2.6.34.13/kernel/sched.c
|
||||||
@@ -5005,38 +4992,37 @@ SYSCALL_DECLARE(sched_getaffinity)
|
|||||||
int tid = (int)ihk_mc_syscall_arg0(ctx);
|
int tid = (int)ihk_mc_syscall_arg0(ctx);
|
||||||
size_t len = (size_t)ihk_mc_syscall_arg1(ctx);
|
size_t len = (size_t)ihk_mc_syscall_arg1(ctx);
|
||||||
cpu_set_t k_cpu_set, *u_cpu_set = (cpu_set_t *)ihk_mc_syscall_arg2(ctx);
|
cpu_set_t k_cpu_set, *u_cpu_set = (cpu_set_t *)ihk_mc_syscall_arg2(ctx);
|
||||||
|
struct thread *thread;
|
||||||
int ret;
|
int ret;
|
||||||
int found = 0;
|
|
||||||
int i;
|
|
||||||
unsigned long irqstate;
|
|
||||||
extern int num_processors;
|
|
||||||
|
|
||||||
if (!len)
|
if (!len)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
len = MIN2(len, sizeof(k_cpu_set));
|
len = MIN2(len, sizeof(k_cpu_set));
|
||||||
|
|
||||||
if(tid == 0)
|
if(tid == 0){
|
||||||
tid = cpu_local_var(current)->tid;
|
thread = cpu_local_var(current);
|
||||||
|
hold_thread(thread);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
struct mcs_rwlock_node_irqsave lock;
|
||||||
|
struct thread *mythread = cpu_local_var(current);
|
||||||
|
|
||||||
for (i = 0; i < num_processors && !found; i++) {
|
thread = find_thread(0, tid, &lock);
|
||||||
struct thread *thread;
|
if(!thread)
|
||||||
irqstate = ihk_mc_spinlock_lock(&get_cpu_local_var(i)->runq_lock);
|
return -ESRCH;
|
||||||
list_for_each_entry(thread, &get_cpu_local_var(i)->runq, sched_list) {
|
if(mythread->proc->euid != 0 &&
|
||||||
if (thread->proc->pid && thread->tid == tid) {
|
mythread->proc->euid != thread->proc->ruid &&
|
||||||
found = 1;
|
mythread->proc->euid != thread->proc->euid){
|
||||||
memcpy(&k_cpu_set, &thread->cpu_set, sizeof(k_cpu_set));
|
thread_unlock(thread, &lock);
|
||||||
break;
|
return -EPERM;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ihk_mc_spinlock_unlock(&get_cpu_local_var(i)->runq_lock, irqstate);
|
hold_thread(thread);
|
||||||
|
thread_unlock(thread, &lock);
|
||||||
}
|
}
|
||||||
if (!found) {
|
|
||||||
kprintf("%s:%d Thread not found.\n", __FILE__, __LINE__);
|
ret = copy_to_user(u_cpu_set, &thread->cpu_set, len);
|
||||||
return -ESRCH;
|
release_thread(thread);
|
||||||
}
|
|
||||||
ret = copy_to_user(u_cpu_set, &k_cpu_set, len);
|
|
||||||
dkprintf("%s() ret: %d\n", __FUNCTION__, ret);
|
dkprintf("%s() ret: %d\n", __FUNCTION__, ret);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
Reference in New Issue
Block a user