Scheduler: Use copy_to_user in a few system calls
This commit is contained in:
parent
46e4d37098
commit
ea94b331fb
@ -492,23 +492,11 @@ void sys_waitpid(Context* context, long pid, int* wstatus,
|
|||||||
context->rax = 0; // No child has exited, let's return 0.
|
context->rax = 0; // No child has exited, let's return 0.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int* kwstatus;
|
|
||||||
if (wstatus)
|
|
||||||
{
|
|
||||||
kwstatus = obtain_user_ref(wstatus);
|
|
||||||
if (!kwstatus)
|
|
||||||
{
|
|
||||||
context->rax = -EFAULT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
kdbgln("blocking wait on any child");
|
kdbgln("blocking wait on any child");
|
||||||
sched_current_task->state = sched_current_task->Blocking;
|
sched_current_task->state = sched_current_task->Blocking;
|
||||||
sched_current_task->block_reason = BlockReason::Waiting;
|
sched_current_task->block_reason = BlockReason::Waiting;
|
||||||
sched_current_task->blocking_wait_info.pid = -1;
|
sched_current_task->blocking_wait_info.pid = -1;
|
||||||
if (wstatus) sched_current_task->blocking_wait_info.wstatus = kwstatus;
|
sched_current_task->blocking_wait_info.wstatus = wstatus;
|
||||||
else
|
|
||||||
sched_current_task->blocking_wait_info.wstatus = nullptr;
|
|
||||||
return Scheduler::task_yield(context);
|
return Scheduler::task_yield(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -534,42 +522,19 @@ void sys_waitpid(Context* context, long pid, int* wstatus,
|
|||||||
context->rax = 0; // No child has exited, let's return 0.
|
context->rax = 0; // No child has exited, let's return 0.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int* kwstatus;
|
|
||||||
if (wstatus)
|
|
||||||
{
|
|
||||||
kwstatus = obtain_user_ref(wstatus);
|
|
||||||
if (!kwstatus)
|
|
||||||
{
|
|
||||||
context->rax = -EFAULT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sched_current_task->state = sched_current_task->Blocking;
|
sched_current_task->state = sched_current_task->Blocking;
|
||||||
sched_current_task->block_reason = BlockReason::Waiting;
|
sched_current_task->block_reason = BlockReason::Waiting;
|
||||||
sched_current_task->blocking_wait_info.pid = pid;
|
sched_current_task->blocking_wait_info.pid = pid;
|
||||||
if (wstatus) sched_current_task->blocking_wait_info.wstatus = kwstatus;
|
sched_current_task->blocking_wait_info.wstatus = wstatus;
|
||||||
else
|
|
||||||
sched_current_task->blocking_wait_info.wstatus = nullptr;
|
|
||||||
return Scheduler::task_yield(context);
|
return Scheduler::task_yield(context);
|
||||||
}
|
}
|
||||||
if (wstatus)
|
|
||||||
{
|
|
||||||
int* kwstatus = obtain_user_ref(wstatus);
|
|
||||||
if (kwstatus)
|
|
||||||
{
|
|
||||||
*kwstatus = (int)(child->exit_status & 0xff);
|
|
||||||
release_user_ref(kwstatus);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
kinfoln("wstatus ptr is invalid: %p", (void*)wstatus);
|
|
||||||
child->state = child->Exited;
|
|
||||||
context->rax = -EFAULT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
child->state = child->Exited;
|
child->state = child->Exited;
|
||||||
context->rax = (long)child->id;
|
context->rax = (long)child->id;
|
||||||
|
if (wstatus)
|
||||||
|
{
|
||||||
|
int status = (int)(child->exit_status & 0xff);
|
||||||
|
if (!copy_to_user(wstatus, &status, sizeof(int))) context->rax = -EFAULT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Task::is_wait_still_blocking()
|
bool Task::is_wait_still_blocking()
|
||||||
@ -610,14 +575,14 @@ void Task::resume_wait()
|
|||||||
Task* child = Scheduler::find_by_pid(blocking_wait_info.pid);
|
Task* child = Scheduler::find_by_pid(blocking_wait_info.pid);
|
||||||
ensure(child); // This should also already have been validated.
|
ensure(child); // This should also already have been validated.
|
||||||
|
|
||||||
if (blocking_wait_info.wstatus)
|
|
||||||
{
|
|
||||||
*blocking_wait_info.wstatus = (int)(child->exit_status & 0xff);
|
|
||||||
release_user_ref(blocking_wait_info.wstatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
child->state = child->Exited;
|
child->state = child->Exited;
|
||||||
regs.rax = (long)child->id;
|
regs.rax = (long)child->id;
|
||||||
|
|
||||||
|
if (blocking_wait_info.wstatus)
|
||||||
|
{
|
||||||
|
int wstatus = (int)(child->exit_status & 0xff);
|
||||||
|
if (!copy_to_user(blocking_wait_info.wstatus, &wstatus, sizeof(int))) regs.rax = -EFAULT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pstat
|
struct pstat
|
||||||
@ -649,23 +614,17 @@ void sys_pstat(Context* context, long pid, struct pstat* buf)
|
|||||||
context->rax = -ESRCH;
|
context->rax = -ESRCH;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
context->rax = task->id;
|
||||||
if (buf)
|
if (buf)
|
||||||
{
|
{
|
||||||
struct pstat* kpstat = obtain_user_ref(buf);
|
struct pstat stat;
|
||||||
if (!kpstat)
|
stat.pt_pid = task->id;
|
||||||
{
|
stat.pt_ppid = task->ppid;
|
||||||
context->rax = -EFAULT;
|
stat.pt_state = (int)task->state;
|
||||||
return;
|
stat.pt_time = (long)task->cpu_time;
|
||||||
|
stat.pt_uid = task->uid;
|
||||||
|
stat.pt_gid = task->gid;
|
||||||
|
strlcpy(stat.pt_name, task->name, sizeof(stat.pt_name));
|
||||||
|
if (!copy_to_user(buf, &stat, sizeof(struct pstat))) context->rax = -EFAULT;
|
||||||
}
|
}
|
||||||
kpstat->pt_pid = task->id;
|
|
||||||
kpstat->pt_ppid = task->ppid;
|
|
||||||
kpstat->pt_state = (int)task->state;
|
|
||||||
kpstat->pt_time = (long)task->cpu_time;
|
|
||||||
kpstat->pt_uid = task->uid;
|
|
||||||
kpstat->pt_gid = task->gid;
|
|
||||||
strlcpy(kpstat->pt_name, task->name, sizeof(kpstat->pt_name));
|
|
||||||
release_user_ref(kpstat);
|
|
||||||
}
|
|
||||||
context->rax = task->id;
|
|
||||||
return;
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user