From e1ceb339a0d71da3795ca3e32c8434d8efc1b1ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 3 Apr 2018 22:36:33 +0200 Subject: [PATCH] kernel: override access control in user_[un]block_thread()... when reading/writing the wait_status in userland. fixes #14067. --- src/system/kernel/thread.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 4e6641de0d..b10f32a4e5 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -2965,10 +2965,13 @@ user_unblock_thread(thread_id threadID, status_t status) InterruptsSpinLocker locker(thread->scheduler_lock); + set_ac(); if (thread->user_thread->wait_status > 0) { thread->user_thread->wait_status = status; + clear_ac(); thread_unblock_locked(thread, status); - } + } else + clear_ac(); return B_OK; } @@ -3626,8 +3629,13 @@ _user_block_thread(uint32 flags, bigtime_t timeout) ThreadLocker threadLocker(thread); // check, if already done - if (thread->user_thread->wait_status <= 0) - return thread->user_thread->wait_status; + set_ac(); + if (thread->user_thread->wait_status <= 0) { + status_t status = thread->user_thread->wait_status; + clear_ac(); + return status; + } + clear_ac(); // nope, so wait thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_OTHER, "user"); @@ -3641,11 +3649,15 @@ _user_block_thread(uint32 flags, bigtime_t timeout) // Interruptions or timeouts can race with other threads unblocking us. // Favor a wake-up by another thread, i.e. if someone changed the wait // status, use that. + set_ac(); status_t oldStatus = thread->user_thread->wait_status; - if (oldStatus > 0) + if (oldStatus > 0) { thread->user_thread->wait_status = status; - else + clear_ac(); + } else { + clear_ac(); status = oldStatus; + } threadLocker.Unlock();