Kernel: Scheduler donations need to verify that the beneficiary is valid.

Add a Thread::is_thread(void*) helper that we can use to check that the
incoming donation beneficiary is a valid thread. The O(n) here is a bit sad
and we should eventually rethink the process/thread table data structures.
This commit is contained in:
Andreas Kling 2019-04-17 12:41:51 +02:00
parent 6bb0dbe8bf
commit c59f8cd663
3 changed files with 19 additions and 5 deletions

View file

@ -243,11 +243,14 @@ bool Scheduler::pick_next()
bool Scheduler::donate_to(Thread* beneficiary, const char* reason)
{
InterruptDisabler disabler;
if (!Thread::is_thread(beneficiary))
return false;
(void)reason;
unsigned ticks_left = current->ticks_left();
if (!beneficiary || beneficiary->state() != Thread::Runnable || ticks_left <= 1) {
if (!beneficiary || beneficiary->state() != Thread::Runnable || ticks_left <= 1)
return yield();
}
unsigned ticks_to_donate = min(ticks_left - 1, time_slice_for(beneficiary->process().priority()));
#ifdef SCHEDULER_DEBUG
@ -256,7 +259,7 @@ bool Scheduler::donate_to(Thread* beneficiary, const char* reason)
context_switch(*beneficiary);
beneficiary->set_ticks_left(ticks_to_donate);
switch_now();
return 0;
return false;
}
bool Scheduler::yield()
@ -266,11 +269,11 @@ bool Scheduler::yield()
// dbgprintf("%s(%u:%u) yield()\n", current->process().name().characters(), current->pid(), current->tid());
if (!pick_next())
return 1;
return false;
// dbgprintf("yield() jumping to new process: sel=%x, %s(%u:%u)\n", current->far_ptr().selector, current->process().name().characters(), current->pid(), current->tid());
switch_now();
return 0;
return true;
}
void Scheduler::pick_next_and_switch_now()

View file

@ -526,3 +526,13 @@ Vector<Thread*> Thread::all_threads()
threads.append(thread);
return threads;
}
bool Thread::is_thread(void* ptr)
{
ASSERT_INTERRUPTS_DISABLED();
for (auto* thread = g_threads->head(); thread; thread = thread->next()) {
if (thread == ptr)
return true;
}
return false;
}

View file

@ -34,6 +34,7 @@ public:
static void finalize_dying_threads();
static Vector<Thread*> all_threads();
static bool is_thread(void*);
int tid() const { return m_tid; }
int pid() const;