From Jérôme Duval <jerome.duval@xxxxxxxxx>:
Jérôme Duval has uploaded this change for review. (
https://review.haiku-os.org/c/haiku/+/3613 ;)
Change subject: kernel/thread: handle invalid user_thread pointer in
user_[un]block_thread
......................................................................
kernel/thread: handle invalid user_thread pointer in user_[un]block_thread
should help with #16736
---
M src/system/kernel/thread.cpp
1 file changed, 26 insertions(+), 18 deletions(-)
git pull ssh://git.haiku-os.org:22/haiku refs/changes/13/3613/1
diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp
index 1f10548..c5a60d7 100644
--- a/src/system/kernel/thread.cpp
+++ b/src/system/kernel/thread.cpp
@@ -2969,10 +2969,16 @@
InterruptsSpinLocker locker(thread->scheduler_lock);
- set_ac();
- if (thread->user_thread->wait_status > 0) {
- thread->user_thread->wait_status = status;
- clear_ac();
+ status_t waitStatus;
+ if (user_memcpy(&waitStatus, &thread->user_thread->wait_status,
+ sizeof(waitStatus)) < B_OK) {
+ return B_BAD_ADDRESS;
+ }
+ if (waitStatus > 0) {
+ if (user_memcpy(&thread->user_thread->wait_status, &status,
+ sizeof(status)) < B_OK) {
+ return B_BAD_ADDRESS;
+ }
// Even if the user_thread->wait_status was > 0, it may be the
// case that this thread is actually blocked on something else.
@@ -2980,9 +2986,7 @@
&& thread->wait.type == THREAD_BLOCK_TYPE_USER)
{
thread_unblock_locked(thread, status);
}
- } else
- clear_ac();
-
+ }
return B_OK;
}
@@ -3709,13 +3713,13 @@
ThreadLocker threadLocker(thread);
// check, if already done
- set_ac();
- if (thread->user_thread->wait_status <= 0) {
- status_t status = thread->user_thread->wait_status;
- clear_ac();
- return status;
+ status_t waitStatus;
+ if (user_memcpy(&waitStatus, &thread->user_thread->wait_status,
+ sizeof(waitStatus)) < B_OK) {
+ return B_BAD_ADDRESS;
}
- clear_ac();
+ if (waitStatus <= 0)
+ return waitStatus;
// nope, so wait
thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_USER, NULL);
@@ -3729,13 +3733,17 @@
// 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;
+ status_t oldStatus;
+ if (user_memcpy(&oldStatus, &thread->user_thread->wait_status,
+ sizeof(oldStatus)) < B_OK) {
+ return B_BAD_ADDRESS;
+ }
if (oldStatus > 0) {
- thread->user_thread->wait_status = status;
- clear_ac();
+ if (user_memcpy(&thread->user_thread->wait_status, &status,
+ sizeof(status)) < B_OK) {
+ return B_BAD_ADDRESS;
+ }
} else {
- clear_ac();
status = oldStatus;
}
--
To view, visit https://review.haiku-os.org/c/haiku/+/3613
To unsubscribe, or for help writing mail filters, visit
https://review.haiku-os.org/settings
Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: I103488679b8c352855fbd19405bb30c978cf4457
Gerrit-Change-Number: 3613
Gerrit-PatchSet: 1
Gerrit-Owner: Jérôme Duval <jerome.duval@xxxxxxxxx>
Gerrit-MessageType: newchange